package cn.com.ctop.common.module.service.impl;

import cn.com.ctop.common.module.constant.OssConstant;
import cn.com.ctop.common.module.entity.MaterialCutFrame;
import cn.com.ctop.common.module.entity.MaterialCutFrameTask;
import cn.com.ctop.common.module.mapper.MaterialCutFrameMapper;
import cn.com.ctop.common.module.service.IMaterialCutFrameService;
import cn.com.ctop.common.module.service.IMaterialCutFrameTaskService;
import cn.com.ctop.common.module.utils.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.mts.model.v20140618.QuerySnapshotJobListRequest;
import com.aliyuncs.mts.model.v20140618.QuerySnapshotJobListResponse;
import com.aliyuncs.mts.model.v20140618.SubmitSnapshotJobRequest;
import com.aliyuncs.mts.model.v20140618.SubmitSnapshotJobResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 截屏
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2019-12-25
 */
@Slf4j
@Service
public class MaterialCutFrameServiceImpl extends ServiceImpl<MaterialCutFrameMapper, MaterialCutFrame> implements IMaterialCutFrameService {

    private static String ossLocation = "oss-cn-beijing";
    private static String ossBucket = "ctop-media";
    private static String ossOutputObject = "output_{Count}.jpg";

    @Value("${jeecg.path.image-upload}")
    private String imageUpLoadPath;


    @Autowired
    private IMaterialCutFrameTaskService cutFrameTaskService;
    @Autowired
    private MaterialCutFrameMapper materialCutFrameMapper;

    /**
     * 获取素材关键帧
     *
     * @param url
     */
    @Override
    public void getCutFrame(String url, String materialId, Long secondDuration, String height, String width) throws IOException {
        try {

            QueryWrapper<MaterialCutFrameTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("video_signature", materialId);
            queryWrapper.last("limit 1");
            MaterialCutFrameTask checkCutFrame = cutFrameTaskService.getOne(queryWrapper);
            if (!Check.isNull(checkCutFrame)) {
                log.info("已存推荐封面");
                return;

            }

            String zeroFrameUrl = url + "?x-oss-process=video/snapshot,t_00000,m_fast";
            String localPath = LoadFileUtil.downLoadFromUrl(zeroFrameUrl, imageUpLoadPath);
            String md5 = LoadFileUtil.getMD5(localPath);
            LoadFileUtil.delFile(localPath);

            MaterialCutFrame cutFrame = new MaterialCutFrame();
            cutFrame.setSignature(md5);
            cutFrame.setUrl(zeroFrameUrl);
            cutFrame.setVideoSignature(materialId);
            cutFrame.setImageIndex(0);
            this.save(cutFrame);


            // DefaultAcsClient
            // 地域ID // RAM账号的AccessKey ID // RAM账号Access Key Secret
            String ossOutputObject1 = "cutFrame/" + materialId + "/";
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-beijing",
                    "LTAIbNbqWzSOklQV",
                    "1rkPz7JNoXk8sJevPaeYHWqfkQXBGh");
            IAcsClient client = new DefaultAcsClient(profile);
            // request
            SubmitSnapshotJobRequest request = new SubmitSnapshotJobRequest();
            // Input
            JSONObject input = new JSONObject();
            input.put("Location", ossLocation);
            input.put("Bucket", ossBucket);
            //   https://ctop-media.oss-cn-beijing.aliyuncs.com/video/2020-06-03/bp%E8%95%89%E4%B8%8B%E7%9B%B4%E6%92%AD2-1591188835505.mp4
            String replaceUrl = url.replace("https://ctop-media.oss-cn-beijing.aliyuncs.com/", "");
            input.put("Object", replaceUrl);

            request.setInput(input.toJSONString());


            // SnapshotConfig
            JSONObject snapshotConfig = new JSONObject();
            // SnapshotConfig->OutputFile
            JSONObject output = new JSONObject();
            output.put("Location", ossLocation);
            output.put("Bucket", ossBucket);


            output.put("Object", URLEncoder.encode(ossOutputObject1 + ossOutputObject, "utf-8"));

            snapshotConfig.put("OutputFile", output.toJSONString());
            // SnapshotConfig->Time
            //   Integer time = ((secondDuration.intValue() - 2) / 14) + 1; // 时长 / 14 == 间隔时间

            double num = (double) (secondDuration - 2) / 15;
            long rint = Math.round(num);
            log.info("相隔时间数：{}", rint);
            snapshotConfig.put("Time", 2000);
            // SnapshotConfig->Interval/Num
            snapshotConfig.put("Interval", rint);
            snapshotConfig.put("Num", "14");
            // SnapshotConfig->Width/Height
            snapshotConfig.put("Height", height);
            snapshotConfig.put("Width", width);
            // SnapshotConfig
            request.setSnapshotConfig(snapshotConfig.toJSONString());
            // PipelineId
            String pipelineId = MpsUtils.getPipelineId(client);
            request.setPipelineId(pipelineId);
            SubmitSnapshotJobResponse response = client.getAcsResponse(request);
            String jobId = response.getSnapshotJob().getId();
            MaterialCutFrameTask cutFrameTask = new MaterialCutFrameTask();
            cutFrameTask.setJobStatus(0);
            cutFrameTask.setJobId(jobId);
            cutFrameTask.setVideoSignature(materialId);
            cutFrameTaskService.save(cutFrameTask);
        } catch (Exception e) {
            log.error(e.getMessage());
        }


    }


    @Override
    public void loadCutFrame(String jobId, String videoSignature) {
        try {
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-beijing",
                    "LTAIbNbqWzSOklQV",
                    "1rkPz7JNoXk8sJevPaeYHWqfkQXBGh");
            IAcsClient client = new DefaultAcsClient(profile);

            QuerySnapshotJobListRequest request = new QuerySnapshotJobListRequest();
            request.setSnapshotJobIds(jobId);
            QuerySnapshotJobListResponse response = client.getAcsResponse(request);
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(response));
            if (jsonObject == null) {
                return;
            }
            JSONObject json = (JSONObject) jsonObject.getJSONArray("snapshotJobList").get(0);
            String state = json.getString("state");
            if (null == state || !"Success".equals(state)) {
                return;
            }
            String loadImage = "cutFrame/" + videoSignature + "/";

            Integer count = json.getInteger("count");
            for (int j = 1; j <= count; j++) {
                String urlStr = null;
                if (j < 10) {
                    urlStr = String.format(
                            OssConstant.formatUrl + loadImage + "output_0000" + j + ".jpg",
                            ossBucket,
                            ossLocation);
                } else if (j < 100) {
                    urlStr = String.format(
                            OssConstant.formatUrl + loadImage + "output_000" + j + ".jpg",
                            ossBucket,
                            ossLocation);
                } else if (j > 100) {
                    urlStr = String.format(
                            OssConstant.formatUrl + loadImage + "output_00" + j + ".jpg",
                            ossBucket,
                            ossLocation);
                }
                String cutFramePath = LoadFileUtil.downLoadFromUrl(urlStr, imageUpLoadPath);
                String cutFrameMd5 = LoadFileUtil.getMD5(cutFramePath);

                MaterialCutFrame cutFrame = new MaterialCutFrame();
                cutFrame.setSignature(cutFrameMd5);
                cutFrame.setUrl(urlStr);
                cutFrame.setVideoSignature(videoSignature);
                cutFrame.setImageIndex(j);
                this.save(cutFrame);
                LoadFileUtil.delFile(cutFramePath);

            }

            QueryWrapper<MaterialCutFrameTask> updateQueryWrapper = new QueryWrapper<>();
            updateQueryWrapper.eq("job_id", jobId);
            updateQueryWrapper.eq("video_signature", videoSignature);
            MaterialCutFrameTask updateTask = new MaterialCutFrameTask();
            updateTask.setJobStatus(1);
            cutFrameTaskService.update(updateTask, updateQueryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }

    @Override
    public List<MaterialCutFrame> getListByVideoSignature(String videoSignature) {
        return materialCutFrameMapper.getListByVideoSignature(videoSignature);
    }


    //腾讯云抽帧
    @Override
    public void getCosCutFrame(String url, String materialId) throws IOException {
        try {

            QueryWrapper<MaterialCutFrameTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("video_signature", materialId);
            queryWrapper.last("limit 1");
            MaterialCutFrameTask checkCutFrame = cutFrameTaskService.getOne(queryWrapper);
            if (!Check.isNull(checkCutFrame)) {
                log.info("已存推荐封面");
                return;
            }

            //抽帧ossOutputObject1
            String ossOutputObject1 = "/cutFrame/" + materialId + "/_";
            String replaceUrl = url.replace("https://" + CosUtil.bucket + ".cos.ap-chongqing.myqcloud.com", "");  //地址
            String resp = CosUtil.processMedia(replaceUrl, ossOutputObject1);
            JSONObject respJson = JSONObject.parseObject(resp);
            String jobId = respJson.getString("TaskId"); //{"Response": {"TaskId": "2600000655-WorkflowTask-c0b385f27c4993437029b5da175542aet0","RequestId": "4c23ce23-087f-4d4b-b73b-907d77d6d78d" } }
            MaterialCutFrameTask cutFrameTask = new MaterialCutFrameTask();
            cutFrameTask.setJobStatus(0);
            cutFrameTask.setJobId(jobId);
            cutFrameTask.setCloud_type(2);
            cutFrameTask.setVideoSignature(materialId);
            cutFrameTaskService.save(cutFrameTask);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }


    //抽帧任务状态查询，如果完成则把抽帧入库
    @Override
    public void loadCosCutFrame(String jobId, String videoSignature) {
        try {
            String resp = CosUtil.describeTaskDetail(jobId);
            if (StringUtils.isBlank(resp)) {
                return;
            }

            JSONObject respJson = JSONObject.parseObject(resp);
            String status = respJson.getString("Status");

            if (!"FINISH".equals(status)) {
                return;
            }


            JSONArray resultSetArray = respJson.getJSONObject("WorkflowTask").getJSONArray("MediaProcessResultSet");
            if (Check.isNull(resultSetArray)) {
                return;
            }
            JSONObject resultSetObject = resultSetArray.getJSONObject(0);
            if (Check.isNull(resultSetObject)) {
                return;
            }
            JSONArray snapshotArray = resultSetObject.getJSONObject("SampleSnapshotTask").getJSONObject("Output").getJSONArray("ImagePathSet");

            if (Check.isNull(snapshotArray)) {
                return;
            }

            for (int i = 0; i < snapshotArray.size(); i++) {
                String imagePath = snapshotArray.getString(i);
                String urlStr = "https://" + CosUtil.bucket + ".cos.ap-chongqing.myqcloud.com" + imagePath;

                //下载到本地获取图片md5
                String cutFramePath = LoadFileUtil.downLoadFromUrl(urlStr, imageUpLoadPath);
                String cutFrameMd5 = LoadFileUtil.getMD5(cutFramePath);

                MaterialCutFrame cutFrame = new MaterialCutFrame();
                cutFrame.setSignature(cutFrameMd5);
                cutFrame.setUrl(urlStr);
                cutFrame.setVideoSignature(videoSignature);
                cutFrame.setImageIndex(i);
                this.save(cutFrame);
            }

            QueryWrapper<MaterialCutFrameTask> updateQueryWrapper = new QueryWrapper<>();
            updateQueryWrapper.eq("job_id", jobId);
            updateQueryWrapper.eq("video_signature", videoSignature);
            MaterialCutFrameTask updateTask = new MaterialCutFrameTask();
            updateTask.setJobStatus(1);
            cutFrameTaskService.update(updateTask, updateQueryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }


    @Override
    public void getTencentCutFrame(String videoUrl, String materialId, String coveUrl) {
        try {

            if (Check.isNull(materialId)) {
                return;
            }
            String loadImage = "cutFrame/" + materialId + "/${Number}.jpg";
            QueryWrapper<MaterialCutFrame> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("video_signature", materialId);
            queryWrapper.last("limit 1");
            MaterialCutFrame checkMaterialCutFrame = this.getOne(queryWrapper);
            if (!Check.isNull(checkMaterialCutFrame)) {
                log.info("已存推荐封面");
                return;
            }
            // 添加首帧
            String coverCutFramePath = LoadFileUtil.downLoadFromUrl(coveUrl, imageUpLoadPath);
            String CutFrameMd5 = LoadFileUtil.getMD5(coverCutFramePath);
            MaterialCutFrame coveCutFrame = new MaterialCutFrame();
            coveCutFrame.setSignature(CutFrameMd5);
            coveCutFrame.setUrl(coveUrl);
            coveCutFrame.setVideoSignature(materialId);
            coveCutFrame.setImageIndex(0);
            this.save(coveCutFrame);
            LoadFileUtil.delFile(coverCutFramePath);
            // 请求从数据接口 获取其余14张截图
            getCut(materialId, videoUrl, loadImage, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    private void getCut(String materialId, String videoUrl, String loadImage, Integer count) {
        try {
            Map<String, Object> coverMap = CloudVideoProcessUtil.videoCutFrameHandle(videoUrl, loadImage);
            for (int i = 0; i <= 13; i++) {
                String url = (String) coverMap.get(String.valueOf(i));
                if (!Check.isNull(url)) {
                    String cutFramePath = LoadFileUtil.downLoadFromUrl(url, imageUpLoadPath);
                    String cutFrameMd5 = LoadFileUtil.getMD5(cutFramePath);
                    Map<String, Object> deleteMap = new HashMap<>();
                    deleteMap.put("video_signature", materialId);
                    deleteMap.put("signature", cutFrameMd5);
                    this.removeByMap(deleteMap);
                    MaterialCutFrame cutFrame = new MaterialCutFrame();
                    cutFrame.setSignature(cutFrameMd5);
                    cutFrame.setUrl(url);
                    cutFrame.setVideoSignature(materialId);
                    cutFrame.setImageIndex(i + 1);
                    this.save(cutFrame);
                    LoadFileUtil.delFile(cutFramePath);
                }
            }

        } catch (Exception e) {
            log.info("抽帧异常,code:{}", materialId);
            e.printStackTrace();
            if (count >= 4) {
                return;
            }
            getCut(materialId, videoUrl, loadImage, count + 1);

        }

    }

    @Override
    public boolean updateTencentCutFrame(String videoMD5) {
        boolean result = true;
        Map<String, Object> coverMap = CloudVideoProcessUtil.supplementFrameUrl(videoMD5);
        for (int i = 0; i <= 13; i++) {
            String url = (String) coverMap.get(String.valueOf(i));
            if (!Check.isNull(url)) {
                String cutFramePath = LoadFileUtil.downLoadFromUrl(url, imageUpLoadPath);
                String cutFrameMd5 = null;
                try {
                    cutFrameMd5 = LoadFileUtil.getMD5(cutFramePath);
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
                QueryWrapper<MaterialCutFrame> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("video_signature", videoMD5);
                queryWrapper.eq("image_index", i + 1);
                MaterialCutFrame cutFrame = new MaterialCutFrame();
                cutFrame.setSignature(cutFrameMd5);
                cutFrame.setUrl(url);
                result = this.update(cutFrame, queryWrapper);
                LoadFileUtil.delFile(cutFramePath);
            }
        }
        return result;
    }

    @Override
    public MaterialCutFrame getCutFrameByCode(String code) {
        QueryWrapper<MaterialCutFrame> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("video_signature", code);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }


}
