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

import cn.com.ctop.common.module.entity.*;
import cn.com.ctop.common.module.mapper.MaterialAscriptionMapper;
import cn.com.ctop.common.module.mapper.MaterialInfoMapper;
import cn.com.ctop.common.module.mapper.MaterialParameterMapper;
import cn.com.ctop.common.module.mapper.MaterialTagMapper;
import cn.com.ctop.common.module.service.IMaterialCutFrameService;
import cn.com.ctop.common.module.service.IMaterialInfoService;
import cn.com.ctop.common.module.service.IVideoWatermarkTaskService;
import cn.com.ctop.common.module.service.IVideoWatermarkTemplateService;
import cn.com.ctop.common.module.utils.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.mts.model.v20140618.QueryJobListResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import it.sauronsoftware.jave.Encoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.channels.FileChannel;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

/**
 * 素材信息
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2019-10-11
 */
@Slf4j
@Service
public class MaterialInfoServiceImpl extends ServiceImpl<MaterialInfoMapper, MaterialInfo> implements IMaterialInfoService {
    private static ExecutorService uploadExecutorService = Executors.newFixedThreadPool(5);
    @Autowired
    private IVideoWatermarkTemplateService videoWatermarkTemplateService;
    @Autowired
    private IVideoWatermarkTaskService videoWatermarkTaskService;

    @Override
    public void watermarkVideo(String materialId, Integer videoWatermarkTemplateId, String userId) {
        VideoWatermarkTemplate videoWatermarkTemplate = videoWatermarkTemplateService.getById(videoWatermarkTemplateId);
        MaterialInfo materialInfo = this.getById(materialId);
        MpsUtils mpsUtils = new MpsUtils();
        String path = materialInfo.getUrl().substring(materialInfo.getUrl().indexOf("/", 10) + 1, materialInfo.getUrl().length());
        System.out.println(path);
        String jobId = mpsUtils.videoWaterMark(path, videoWatermarkTemplate.getTemplatePath(), videoWatermarkTemplate.getTemplateId(), videoWatermarkTemplate.getHeight());
        QueryJobListResponse.Job job = mpsUtils.getJobStatus(jobId);
        VideoWatermarkTask videoWatermarkTask = new VideoWatermarkTask();
        videoWatermarkTask.setJobId(jobId);
        videoWatermarkTask.setUserId(userId);
        videoWatermarkTask.setStatus(job.getState());
        videoWatermarkTaskService.save(videoWatermarkTask);
        materialInfo.setWatermarkCode(jobId);
        this.updateById(materialInfo);
    }

    @Override
    public MaterialInfo getMaterialInfoByCode(String code) {
        QueryWrapper<MaterialInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", code).orderByDesc("id").last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public Map<String, Object> checkMaterialInfo(String code) {
        Map<String, Object> result = new HashMap<>();
        MaterialInfo info = this.getMaterialInfoByCode(code);
        if (null != info) {
            //文件已存在
            ResultMapUtils.setResultMap(result, StatusCode.FILE_HAS_UPLOAD.getCode());
            result.put("url", info.getUrl());
            return result;
        } else {
            //文件尚未上传
            ResultMapUtils.setResultMap(result, StatusCode.FILE_HAS_NOT_UPLOAD.getCode());
            return result;
        }
    }

    public boolean imgLocation(String fileName) throws IOException {
        String reg = "(mp4|flv|avi|rm|rmvb|wmv|MP4)";
        Pattern p = Pattern.compile(reg);
        return p.matcher(fileName).find();
    }

    public static void main(String[] args) {
        String reg = "(mp4|flv|avi|rm|rmvb|wmv)";
        Pattern p = Pattern.compile(reg);
        System.out.println(p.matcher("https://ctop-media.oss-cn-beijing.aliyuncs.com/video/2019-10-30/ios%E6%8E%A8%E5%B9%BF%E8%A7%86%E9%A2%91-1572437289724.mp4").find());
    }

    @Autowired
    private MaterialAscriptionMapper materialAscriptionMapper;
    @Autowired
    private MaterialTagMapper materialTagMapper;

    @Override
    public Map<String, Object> insert(JSONObject jsonObject) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            String type = jsonObject.getString("type");
            if ("IMAGE".equals(type)) {
                JSONArray imageArr = jsonObject.getJSONArray("imageArr");
                if (!Check.isNull(imageArr)) {
                    jsonObject.remove("imageArr");
                    for (int i = 0; i < imageArr.size(); i++) {
                        String url = imageArr.getString(i);
                        if (!Check.isNull(url)) {
                            jsonObject.remove("code");
                            jsonObject.remove("materialName");
                            url = "https:" + url;
                            String localPath = LoadFileUtil.downLoadFromUrl(url, PropertiesUtils.getValue("kuaishou_config", "video_sava_path"));
                            //  String localPath = LoadFileUtil.downLoadFromUrl(url, "D:\\tets1\\image");
                            String md5 = LoadFileUtil.getMD5(localPath);
                            jsonObject.put("code", md5);
                            LoadFileUtil.delFile(localPath);
                            String fileName = url.substring(url.lastIndexOf("/") + 1);
                            String fileNameStr = null;
                            if (!Check.isNull(fileName)) {
                                String[] split = fileName.split("-");
                                fileNameStr = split[0];
                            }
                            jsonObject.put("materialName", AesEncryptUtil.getUrlDecoderString(fileNameStr));

                            insertMaterialInfo(url, type, jsonObject);
                        }

                    }
                }

            } else {
                String url = "";
                if (!Check.isNull(jsonObject.getString("url"))) {
                    url = "https:" + jsonObject.getString("url");
                }
                insertMaterialInfo(url, type, jsonObject);
            }

            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
        } catch (Exception e) {
            ResultMapUtils.setResultMap(resultMap, StatusCode.MATERIAL_UPLOAD_FAIL.getCode());
            e.printStackTrace();

        }


        return resultMap;
    }

    @Autowired
    private IMaterialCutFrameService materialCutFrameService;

    private void insertMaterialInfo(String url, String type, JSONObject jsonObject) {
        MaterialInfo info = new MaterialInfo();
        info.setId(jsonObject.getString("code"));
        info.setCode(jsonObject.getString("code"));

        if (!Check.isNull(jsonObject.getString("watermarkUrl"))) {
            info.setWatermarkUrl(jsonObject.getString("watermarkUrl"));
        }
        info.setUrl(url);
        info.setUserId(jsonObject.getString("userId"));
        info.setProjectId(jsonObject.getLong("projectId"));
        info.setWatermarkCode(jsonObject.getString("watermarkCode"));
        info.setStatus(0);
        info.setMaterialName(jsonObject.getString("materialName"));
        info.setWatermarkMaterialName(jsonObject.getString("watermarkMaterialName"));
        info.setMaterialDescribe(jsonObject.getString("materialDescribe"));
        info.setCreateTime(new Date());
        info.setUpdateTime(new Date());
        info.setType(type);
        this.save(info);

        Map<String, Object> deleteMap = new HashMap<>();
        deleteMap.put("material_id", info.getId());

        JSONObject ascription = jsonObject.getJSONObject("ascription");
        if (!Check.isNull(ascription)) {
            MaterialAscription materialAscription = new MaterialAscription();
            materialAscription.setMaterialId(info.getId());
            // 剪辑人
            materialAscription.setClipId(ascription.getString("clipId"));
            // 拍摄人id
            materialAscription.setShotId(ascription.getString("shotId"));
            // 策划id
            materialAscription.setPlanId(ascription.getString("planId"));
            //平面id
            materialAscription.setPlaneId(ascription.getString("planeId"));
            materialAscriptionMapper.deleteByMap(deleteMap);
            int i = materialAscriptionMapper.insert(materialAscription);
            if (i > 0) {
                log.info("素材归属信息入库完成，MaterialId:{}", info.getId());
            }

        }

        JSONArray tag = jsonObject.getJSONArray("tag");
        if (!Check.isNull(tag)) {
            materialTagMapper.deleteByMap(deleteMap);
            for (int i = 0; i < tag.size(); i++) {
                String tagStr = tag.getString(i);
                if (!Check.isNull(tagStr)) {
                    MaterialTag materialTag = new MaterialTag();
                    materialTag.setMaterialId(info.getId());
                    materialTag.setTag(tagStr);
                    materialTagMapper.insert(materialTag);
                }
            }
        }

        getFile(info);

    }


    /**
     * 获取素材详细信息
     *
     * @param materialId
     * @return
     */

    @Autowired
    private MaterialInfoMapper materialInfoMapper;


    @Override
    public JSONObject getDetail(String materialId) {
        JSONObject json = new JSONObject();

        MaterialInfo materialInfo = this.getById(materialId);
        if (!Check.isNull(materialInfo.getAuditorId())) {
            String auditorName = materialInfoMapper.selectUserNameById(materialInfo.getAuditorId());
            json.put("auditorName", auditorName);
        } else {
            json.put("auditorName", "");
        }

        List<String> tagList = materialTagMapper.selectByMaterialId(materialId);
        if (!Check.isNull(tagList)) {
            json.put("tag", tagList);
        }
        QueryWrapper<MaterialParameter> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("material_id", materialId);
        queryWrapper.orderByDesc("create_time");
        queryWrapper.last("limit 1");
        MaterialParameter materialParameter = materialParameterMapper.selectOne(queryWrapper);

        if (!Check.isNull(materialParameter)) {
            json.put("parameter", materialParameter);
        } else {
            MaterialParameter materialParameter1 = new MaterialParameter();
            materialParameter1.setMaterialId(materialId);
            json.put("parameter", materialParameter1);
        }
        JSONObject ascriptionJson = materialAscriptionMapper.selectByMaterialId(materialId);
        if (!Check.isNull(ascriptionJson)) {
            json.put("ascription", ascriptionJson);
        }

        return json;
    }

    /**
     * 工作台报表
     *
     * @param userId
     * @return
     */
    @Override
    public JSONObject report(String userId) {

        JSONObject json = new JSONObject();
        try {
            Map<String, Object> requestMap = new HashMap<>();
            requestMap.put("userId", userId);

            Integer totalCount = materialInfoMapper.selectCountByMap(requestMap);
            json.put("total", totalCount);

            requestMap.put("status", 0);
            Integer waitAudit = materialInfoMapper.selectCountByMap(requestMap);
            json.put("waitAudit", waitAudit);

            requestMap.put("status", 1);
            Integer passAudit = materialInfoMapper.selectCountByMap(requestMap);
            json.put("passAudit", passAudit);

            requestMap.put("status", 2);
            Integer refuseAudit = materialInfoMapper.selectCountByMap(requestMap);
            json.put("refuseAudit", refuseAudit);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    @Override
    public String getRoleCodeByUserId(String userId) {
        return materialInfoMapper.getRoleCodeByUserId(userId);
    }


    @Autowired
    private MaterialParameterMapper materialParameterMapper;

    @Override
    public void getFile(MaterialInfo materialInfo) {
        uploadExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    log.info("获取素材基本信息，code:{}", materialInfo.getCode());
                    if (!Check.isNull(materialInfo)) {
                        String url = materialInfo.getUrl();
                        long l = System.currentTimeMillis();
                        String localUrl = LoadFileUtil.downLoadFromUrl(url, PropertiesUtils.getValue("kuaishou_config", "video_sava_path"));
                        File file = new File(localUrl);
                        it.sauronsoftware.jave.Encoder encoder = new Encoder();
                        try {
                            it.sauronsoftware.jave.MultimediaInfo m = encoder.getInfo(file);
                            long duration = m.getDuration();
                            long secondDuration = duration / 1000;
                            MaterialParameter materialParameter = new MaterialParameter();
                            materialParameter.setMaterialId(materialInfo.getId());
                            // 视频秒数
                            materialParameter.setSecond(secondDuration);
                            // 视频格式
                            materialParameter.setFormat(m.getFormat());
                            // 视频宽
                            String width = String.valueOf(m.getVideo().getSize().getWidth());
                            materialParameter.setWidth(width);
                            // 视频高
                            String height = String.valueOf(m.getVideo().getSize().getHeight());
                            materialParameter.setHeight(height);
                            FileInputStream fis = new FileInputStream(file);
                            FileChannel fc = fis.getChannel();
                            BigDecimal fileSize = new BigDecimal(fc.size());
                            String size = fileSize.divide(new BigDecimal(1048576), 2, RoundingMode.HALF_UP) + "MB";
                            materialParameter.setSize(size);
                            materialParameter.setUpdateTime(new Date());

                            Map<String, Object> deleteMap = new HashMap<>();
                            deleteMap.put("material_id", materialInfo.getId());
                            materialParameterMapper.deleteByMap(deleteMap);
                            int insert = materialParameterMapper.insert(materialParameter);
                            if (insert > 0) {
                                log.info("素材基本信息入库完成，用时：{} s", (System.currentTimeMillis() - l) / 1000);

                            }
                            /*Thread thread = new Thread() {
                                @Override
                                public void run() {
                                    try {
                                        Thread.sleep(5 * 1000);
                                        materialCutFrameService.getCutFrame(url, materialInfo.getCode(), height, width);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            };
                            thread.start();*/

                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            file.delete();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        });
    }


}
