package cn.com.ctop.manage.modules.material.service.impl;

import cn.com.ctop.common.module.entity.*;
import cn.com.ctop.common.module.enums.MaterialEnum;
import cn.com.ctop.common.module.mapper.CtopOauthTokenMapper;
import cn.com.ctop.common.module.mapper.MaterialImageInfoMapper;
import cn.com.ctop.common.module.mapper.MaterialInfoMapper;
import cn.com.ctop.common.module.service.*;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
import cn.com.ctop.common.module.utils.LoadFileUtil;
import cn.com.ctop.common.module.utils.PropertiesUtils;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAdvertiserBaseInfo;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouAdvertiserBaseInfoService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
import cn.com.ctop.manage.modules.material.service.IMaterialUploadImageService;
import cn.com.ctop.manage.modules.material.service.IMaterialUploadService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Service
public class MaterialUploadServiceImpl implements IMaterialUploadService {
    static ExecutorService kuaiShouExecutorService = Executors.newFixedThreadPool(5);
    static ExecutorService touTiaoExecutorService = Executors.newFixedThreadPool(5);
    @Value("${oss.replace.download}")
    private String downloadUrl;

    @Autowired
    private CtopOauthTokenMapper oauthTokenMapper;
    @Autowired
    private MaterialInfoMapper materialInfoMapper;
    @Autowired
    MaterialImageInfoMapper materialImageInfoMapper;
    @Autowired
    private IFileInfoService fileInfoService;
    @Autowired
    private IMaterialParameterService materialParameterService;
    @Autowired
    private IMaterialUploadImageService materialUploadImageService;
    @Autowired
    private ISendMessageService sendMessageService;
    @Autowired
    private IMessageTemplate messageTemplate;
    @Autowired
    private IUserAllocationService userAllocationService;
    @Autowired
    private IKuaishouInterfaceService kuaishouInterfaceService;
    @Autowired
    private IProjectService projectService;

    /**
     * 同步素材到账号下
     *
     * @param mediaId
     * @param materialArray
     * @param accountArray
     */
    @Override
    public void uploadAccount(String mediaId, JSONArray materialArray, JSONArray accountArray, String userId) {
        try {
            if ("2".equals(mediaId) || "4".equals(mediaId)) {
                this.kuaiShouUpload(mediaId, materialArray, accountArray, userId);
            } else if ("1".equals(mediaId) || "3".equals(mediaId)) {
                this.touTiaoUpload(mediaId, materialArray, accountArray, userId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void touTiaoUpload(String mediaId, JSONArray materialArray, JSONArray accountArray, String userId) {
        for (int j = 0; j < materialArray.size(); j++) {
            String materialId = materialArray.getString(j);
            MaterialInfo materialInfo = materialInfoMapper.selectById(materialId);
            MaterialImageInfo materialImageInfo = materialImageInfoMapper.selectById(materialId);
            if (Check.isNull(materialInfo) && Check.isNull(materialImageInfo)) {
                continue;
            }
            try {
                String url = "";
                if (Check.isNull(materialInfo)) {
                    url = (String) materialImageInfo.getUrl();
                } else {
                    url = materialInfo.getUrl();
                }
                String localUrl = LoadFileUtil.downLoadFromUrl(url, downloadUrl);

                for (int i = 0; i < accountArray.size(); i++) {
                    Long accountId = accountArray.getLong(i);
                    if (Check.isNull(accountId)) {
                        continue;
                    }
                    String finalUrl = url;
                    touTiaoExecutorService.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                log.info("头条文件多线程上传:{}，accountId:{}", Thread.currentThread().getName(), accountId);
                                if (materialInfo != null && "VIDEO".equals(materialInfo.getType())) {
                                    fileInfoService.uploadVideoToBytedance(String.valueOf(accountId), localUrl, userId, materialInfo.getMaterialName());

                                } else if ("IMAGE".equals(materialImageInfo.getType())) {
                                    fileInfoService.uploadImageToBytedance(String.valueOf(accountId), finalUrl);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Autowired
    private IKuaiShouAdvertiserBaseInfoService advertiserBaseInfoService;

    private void kuaiShouUpload(String mediaId, JSONArray materialArray, JSONArray accountArray, String userId) {
        for (int j = 0; j < materialArray.size(); j++) {
            String materialId = materialArray.getString(j);
            MaterialInfo materialInfo = materialInfoMapper.selectById(materialId);
            if (Check.isNull(materialInfo) || Check.isNull(materialInfo.getUrl())) {
                continue;
            }
            try {
                String url = materialInfo.getUrl();
                log.info("replaceUrl:{}", url);
                String localUrl = LoadFileUtil.downLoadFromUrl(url, downloadUrl);
                FileSystemResource resource = new FileSystemResource(new File(localUrl));
                Map<String, String> headerMap = new HashMap<>();
                headerMap.put("Content-Type", "multipart/form-data");
                JSONObject requestJson = new JSONObject();
                requestJson.put("file", resource);
                requestJson.put("signature", materialInfo.getCode());

                QueryWrapper<MaterialParameter> parameterQueryWrapper = new QueryWrapper<>();
                parameterQueryWrapper.eq("material_id", materialInfo.getCode());
                parameterQueryWrapper.orderByDesc("create_time").last("limit 1");
                MaterialParameter materialParameter = materialParameterService.getOne(parameterQueryWrapper);
                if (!Check.isNull(materialParameter)) {
                    Integer type = MaterialEnum.getTypeBySize(Integer.valueOf(materialParameter.getWidth()), Integer.valueOf(materialParameter.getHeight()));
                    if (!Check.isNull(type) && type != 0) {
                        requestJson.put("type", type);
                    }
                }
                for (int i = 0; i < accountArray.size(); i++) {
                    Long accountId = accountArray.getLong(i);
                    QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
                    tokenQueryWrapper.eq("account_id", accountId);
                    tokenQueryWrapper.orderByDesc("create_time");
                    tokenQueryWrapper.last("limit 1");
                    CtopOauthToken ctopOauthToken = oauthTokenMapper.selectOne(tokenQueryWrapper);
                    if (Check.isNull(ctopOauthToken)) {
                        continue;
                    }
                    requestJson.put("advertiser_id", accountId);
                    headerMap.put("Access-Token", ctopOauthToken.getAccessToken());
                    kuaiShouExecutorService.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                log.info("快手文件多线程上传:{}，accountId:{}", Thread.currentThread().getName(), accountId);
                                String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.VIDEO_UPLOAD;
                                String result = exceptInfoForRestTemplate(url, requestJson, headerMap);
                                JSONObject resultJson = JSONObject.parseObject(result);
                                if (!Check.isNull(resultJson)) {
                                    KuaiShouAdvertiserBaseInfo baseInfo = advertiserBaseInfoService.getBaseInfo(accountId);

                                    if (resultJson.getInteger("code") == 0) {
                                        JSONObject dataJson = resultJson.getJSONObject("data");
                                        if (!Check.isNull(dataJson)) {
                                            String signature = dataJson.getString("signature");
                                            //同步 视频关联的封面
                                            materialUploadImageService.uploadImage(signature, accountId, ctopOauthToken.getAccessToken());
                                            // 发送推送成功通知
                                            UserAllocation allocation = userAllocationService.getByAccountId(accountId);
                                            Project project = projectService.getById(allocation.getProjectId());
                                            String message = messageTemplate.getMaterialSyncSucessTemplate(project.getProjectName(), baseInfo.getUserId(), baseInfo.getUserName(), materialInfo.getMaterialName(), resultJson.getString("message"));
                                            sendMessageService.sendMessage(userId, message);

                                            /**
                                             * 异步获取视频信息
                                             */
                                            Thread thread = new Thread() {
                                                @Override
                                                public void run() {
                                                    try {
                                                        Thread.sleep(2 * 1000L);
                                                        kuaishouInterfaceService.getVideoInfo(ctopOauthToken.getAccessToken(), ctopOauthToken.getAccountId(), dataJson.getString("photo_id"));
                                                    } catch (InterruptedException e) {
                                                        e.printStackTrace();
                                                    }
                                                }
                                            };
                                            thread.start();
                                        }
                                        log.info("快手素材同步完成，accountId：{}，code：{},返回信息：{}", accountId, materialInfo.getCode(), resultJson);
                                    } else {
                                        log.error("快手同步素材失败，返回信息：{}，请求参数：{}", resultJson, requestJson);
                                        //  发送推送失败消息到上传人
                                        UserAllocation allocation = userAllocationService.getByAccountId(accountId);
                                        Project project = projectService.getById(allocation.getProjectId());
                                        String message = messageTemplate.getMaterialSyncTemplate(project.getProjectName(), baseInfo.getUserId(), baseInfo.getUserName(), materialInfo.getMaterialName(), resultJson.getString("message"));
                                        sendMessageService.sendMessage(userId, message);
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private String exceptInfoForRestTemplate(String url, Map<String, Object> paramMap, Map<String, String> headerMap) {
        try {
            long l = System.currentTimeMillis();
            MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
            if (!Check.isNullMap(paramMap)) {
                for (String key : paramMap.keySet()) {
                    param.add(key, paramMap.get(key));
                }
                HttpHeaders headers = new HttpHeaders();
                if (!Check.isNullMap(headerMap)) {
                    for (String key : headerMap.keySet()) {
                        headers.add(key, headerMap.get(key));
                    }
                }
                SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
                requestFactory.setConnectTimeout(1000 * 500);// 设置超时
                requestFactory.setReadTimeout(1000 * 500);
                RestTemplate rest = new RestTemplate(requestFactory);
                HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers);
                ResponseEntity<String> responseEntity = rest.exchange(url, HttpMethod.POST, httpEntity, String.class);
                log.info("上传素材时间:{} s ,账户：{}。code:{}", (System.currentTimeMillis() - l) / 1000, paramMap.get("advertiser_id"), paramMap.get("signature"));
                return responseEntity.getBody();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
