package org.jeecg.modules.fileupload.service.impl;

import cn.com.ctop.common.module.entity.MaterialCutFrame;
import cn.com.ctop.common.module.entity.TagInfo;
import cn.com.ctop.common.module.service.IMaterialCutFrameService;
import cn.com.ctop.common.module.service.ITagInfoService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.CloudVideoProcessUtil;
import cn.com.ctop.common.module.utils.CosUtils;
import cn.com.ctop.common.module.utils.ExportExcelUtils;
import cn.com.ctop.common.module.utils.ExternalMaterialCollection;
import cn.com.ctop.common.module.utils.LoadFileUtil;
import cn.com.ctop.common.module.vo.ResFileDTO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.fileupload.mapper.ExternalMaterialCollectionMapper;
import org.jeecg.modules.fileupload.service.IExternalMaterialCollectionService;
import org.jeecg.modules.system.entity.SysCategory;
import org.jeecg.modules.system.service.ISysCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 外部素材集信息表
 *
 * @author jeecg-boot
 * 2022-01-12
 * @version V1.0
 */
@Service
public class ExternalMaterialCollectionServiceImpl extends ServiceImpl<ExternalMaterialCollectionMapper, ExternalMaterialCollection> implements IExternalMaterialCollectionService {

    @Autowired
    private ExternalMaterialCollectionMapper mapper;

    @Resource
    private IMaterialCutFrameService materialCutFrameService;

    @Autowired
    private ITagInfoService tagInfoService;

    @Autowired
    private ISysCategoryService sysCategoryService;

    @Value("${oss.replace.download}")
    private String downloadUrl;

    private static ExecutorService uploadExecutorService = Executors.newFixedThreadPool(5);

    @Override
    public Result<Object> queryPageList(ExternalMaterialCollection externalMaterialCollection, Integer pageNo, Integer pageSize) {
        Long total = mapper.getListTotal(externalMaterialCollection);
        PageHelper.startPage(pageNo, pageSize, false);
        PageInfo pageInfo = new PageInfo(mapper.queryPageList(externalMaterialCollection));
        pageInfo.setTotal(total);
        return Result.ok(pageInfo);
    }

    @Override
    public void addByVideo(ExternalMaterialCollection materialCollection) throws Exception {
        uploadExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                materialCollection.setCreateType(1);// 1视频、2链接
                String url = materialCollection.getUrl();
                if (!Check.isNull(url)) {
                    url = "https:" + url;
                }
                materialCollection.setUrl(url);
                String localUrl = null;
                FileInputStream fis = null;
                try {
                    String videoName = null;
                    String industryName = materialCollection.getIndustry();
                    SysCategory category = sysCategoryService.getById(materialCollection.getIndustry());
                    if (!Check.isNull(category)) {
                        industryName = category.getName();
                    }
                    if (Check.isNull(materialCollection.getProduct())) {
                        videoName = industryName + "-" + UUID.randomUUID().toString().replace("-", "").substring(0, 8) + ".mp4";
                    } else {
                        videoName = industryName + "-" + materialCollection.getProduct() + "-" + UUID.randomUUID().toString().replace("-", "").substring(0, 8) + ".mp4";
                    }
                    localUrl = LoadFileUtil.downLoadFromUrlAndName(url, downloadUrl, videoName);
                    String md5 = LoadFileUtil.getMD5(localUrl);
                    materialCollection.setMd5(md5);
                    MaterialCutFrame cutFrame = materialCutFrameService.getCutFrameByCode(materialCollection.getMd5());
                    if (Check.isNull(cutFrame)) {
                        String videoUrl = URLDecoder.decode(url).replace("https://media-1301855440.cos.ap-chongqing.myqcloud.com/", "");
                        String loadImage = "cutFrame/" + md5 + "/zero.jpg";
                        String coverUrl = CloudVideoProcessUtil.videoCutPictureHandle(videoUrl, loadImage);
                        materialCollection.setCoverUrl(coverUrl);
                    } else {
                        materialCollection.setCoverUrl(cutFrame.getUrl());
                    }
                    File file = new File(localUrl);
                    it.sauronsoftware.jave.Encoder encoder = new Encoder();
                    MultimediaInfo m = encoder.getInfo(file);
                    long duration = m.getDuration();
                    long secondDuration = duration / 1000;
                    // 视频秒数
                    materialCollection.setSecond(secondDuration);
                    // 视频格式
                    materialCollection.setFormat(m.getFormat());
                    // 视频宽
                    String width = String.valueOf(m.getVideo().getSize().getWidth());
                    materialCollection.setWidth(width);
                    // 视频高
                    String height = String.valueOf(m.getVideo().getSize().getHeight());
                    materialCollection.setHeight(height);
                    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";
                    materialCollection.setSize(size);
                    materialCollection.setStatDate(DateUtils.formatDate(new Date()));
                    materialCollection.setMaterialName(videoName);
                    List<ExternalMaterialCollection> list = new ArrayList<>();
                    list.add(materialCollection);
                    mapper.replaceBatch(list);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (fis != null) {
                            fis.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    LoadFileUtil.delFile(localUrl);
                }
            }
        });
    }

    @Override
    public void addByUrl(ExternalMaterialCollection materialCollection) throws Exception {
        uploadExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                materialCollection.setCreateType(2);// 1视频、2链接
                String externalUrl = materialCollection.getExternalUrl();
                String localUrl = null;
                FileInputStream fis = null;
                try {
                    String videoName = null;
                    String industryName = materialCollection.getIndustry();
                    SysCategory category = sysCategoryService.getById(materialCollection.getIndustry());
                    if (!Check.isNull(category)) {
                        industryName = category.getName();
                    }
                    if (Check.isNull(materialCollection.getProduct())) {
                        videoName = industryName + "-" + UUID.randomUUID().toString().replace("-", "").substring(0, 8) + ".mp4";
                    } else {
                        videoName = industryName + "-" + materialCollection.getProduct() + "-" + UUID.randomUUID().toString().replace("-", "").substring(0, 8) + ".mp4";
                    }
                    localUrl = LoadFileUtil.downLoadFromUrlAndName(externalUrl, downloadUrl, videoName);
                    File file = new File(localUrl);
                    it.sauronsoftware.jave.Encoder encoder = new Encoder();
                    MultimediaInfo m = encoder.getInfo(file);
                    Thread.sleep(5000);
                    long duration = m.getDuration();
                    long secondDuration = duration / 1000;
                    // 视频秒数
                    materialCollection.setSecond(secondDuration);
                    // 视频格式
                    materialCollection.setFormat(m.getFormat());
                    // 视频宽
                    String width = String.valueOf(m.getVideo().getSize().getWidth());
                    materialCollection.setWidth(width);
                    // 视频高
                    String height = String.valueOf(m.getVideo().getSize().getHeight());
                    materialCollection.setHeight(height);
                    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";
                    //大小
                    materialCollection.setSize(size);
                    String url = null;
                    try {
                        String path = "external-videos/" + DateUtils.formatDate(new Date(), DateUtils.SHORT_FORMAT) + "/";
                        materialCollection.setMaterialName(videoName);
                        ResFileDTO resultFile = CosUtils.uploadDetailInputStreamV2(fis, videoName, "mp4", fc.size(), path);
                        url = resultFile.getFileUrl();
                        materialCollection.setUrl(url);
                    } catch (IOException e) {
                        log.error("上传COS异常", e);
                        throw new Exception("上传COS失败");
                    }
                    String md5 = LoadFileUtil.getMD5(localUrl);
                    materialCollection.setMd5(md5);
                    MaterialCutFrame cutFrame = materialCutFrameService.getCutFrameByCode(materialCollection.getMd5());
                    if (Check.isNull(cutFrame)) {
                        String videoUrl = URLDecoder.decode(url).replace("https://media-1301855440.cos.ap-chongqing.myqcloud.com/", "");
                        String loadImage = "cutFrame/" + md5 + "/zero.jpg";
                        String coverUrl = CloudVideoProcessUtil.videoCutPictureHandle(videoUrl, loadImage);
                        materialCollection.setCoverUrl(coverUrl);
                    } else {
                        materialCollection.setCoverUrl(cutFrame.getUrl());
                    }
                    materialCollection.setStatDate(DateUtils.formatDate(new Date()));
                    List<ExternalMaterialCollection> list = new ArrayList<>();
                    list.add(materialCollection);
                    mapper.replaceBatch(list);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (fis != null) {
                            fis.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    LoadFileUtil.delFile(localUrl);
                }
            }
        });
    }

    @Override
    public void addMoreVideos(JSONArray array) throws Exception {
        for (int i = 0; i < array.size(); i++) {
            ExternalMaterialCollection materialCollection = JSONObject.parseObject(array.getJSONObject(i).toJSONString(), ExternalMaterialCollection.class);
            if (materialCollection == null) {
                continue;
            }
            this.addByVideo(materialCollection);
        }
    }

    @Override
    public void addMoreVideosByUrl(JSONArray array) throws Exception {
        for (int i = 0; i < array.size(); i++) {
            ExternalMaterialCollection materialCollection = JSONObject.parseObject(array.getJSONObject(i).toJSONString(), ExternalMaterialCollection.class);
            if (materialCollection == null) {
                continue;
            }
            this.addByUrl(materialCollection);
        }
    }

    @Override
    public Result<Object> addMoreVideosByExcel(MultipartFile file, String materialSource, String userId, Integer mediaType) throws Exception {
        JSONObject returnJson = new JSONObject();
        Workbook workbook = null;
        String fileName = file.getOriginalFilename();
        String substring = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
        if ("XLS".equals(substring)) {
            workbook = new HSSFWorkbook(file.getInputStream());
        } else if ("XLSX".equals(substring)) {
            workbook = new XSSFWorkbook(file.getInputStream());
        } else {
            throw new Exception("文件不是Excel文件");
        }
        Sheet sheet = workbook.getSheet("Sheet1");
        if (Check.isNull(sheet)) {
            throw new Exception("Sheet标题不是默认的Sheet1");
        }
        int rows = sheet.getLastRowNum();// 指的行数，一共有多少行+
        if (rows == 0) {
            throw new Exception("请填写数据");
        }
        List<ExternalMaterialCollection> list = new ArrayList<>();
        ExportExcelUtils eeu = new ExportExcelUtils();
        for (int i = 1; i <= rows + 1; i++) {
            Row row = sheet.getRow(i);
            if (row != null) {
                //行业
                String industryLabel = eeu.getCellValue(row.getCell(0));
                if (Check.isNull(industryLabel)) {
                    return Result.error("解析数据失败，文档中第" + (i + 1) + "行，行业列缺失数据");
                }
                //产品
                String product = eeu.getCellValue(row.getCell(1));
                //链接
                String externalUrl = eeu.getCellValue(row.getCell(2));
                if (Check.isNull(externalUrl)) {
                    return Result.error("解析数据失败，文档中第" + (i + 1) + "行，素材链接列缺失数据");
                }
                if (!externalUrl.contains("http")) {
                    externalUrl = "https:" + externalUrl;
                }
                //板位
                String platePosition = eeu.getCellValue(row.getCell(3));
                //描述
                String materialDescribe = eeu.getCellValue(row.getCell(4));
                if (!Check.isNull(materialDescribe) && materialDescribe.length() > 10) {
                    materialDescribe = materialDescribe.substring(0, 10);
                }
                ExternalMaterialCollection materialCollection = new ExternalMaterialCollection();
                QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("name", industryLabel).last("limit 1");
                SysCategory one = sysCategoryService.getOne(queryWrapper);
                if (!Check.isNull(one)) {
                    materialCollection.setIndustry(one.getId());
                }
                materialCollection.setProduct(product);
                materialCollection.setExternalUrl(externalUrl);
                materialCollection.setPlatePosition(platePosition);
                materialCollection.setMaterialDescribe(materialDescribe);
                materialCollection.setMaterialSource(materialSource);
                materialCollection.setStatDate(DateUtils.formatDate(new Date()));
                materialCollection.setUserId(userId);
                materialCollection.setCreateType(3);
                materialCollection.setMediaType(mediaType);
                list.add(materialCollection);
            }
        }
        if (!list.isEmpty()) {
            for (ExternalMaterialCollection materialCollection : list) {
                this.addByUrl(materialCollection);
            }
        }
        return Result.ok("素材异步上传中");
    }

    @Override
    public boolean checkMaterialByMd5(String md5) throws Exception {
        QueryWrapper<ExternalMaterialCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5).last("limit 1");
        ExternalMaterialCollection one = this.getOne(queryWrapper);
        if (Check.isNull(one)) {
            return true;
        } else {
            return false;
        }
    }


    @Override
    public Result<Object> getIndustryLabel() {
        List<JSONObject> json = mapper.getParentIndustryLabel();
        List<Map<String, String>> industryLabels = mapper.getIndustryLabel();
        for (JSONObject obj : json) {
            JSONArray children = new JSONArray();
            String id = obj.getString("id");
            for (Map map : industryLabels) {
                if (id.equals(map.get("parentId"))) {
                    children.add(map.get("name"));
                }
            }
            obj.put("child", children);
        }
        return Result.ok(json);
    }

    @Override
    public Result<Object> createInternalMaterial() {
        List<JSONObject> md5List = mapper.getMd5ByMediaType(2);// 1头条，2快手
        Map<String, JSONObject> map = new HashMap<>();
        for (JSONObject object : md5List) {
            map.put(object.getString("md5"), object);
        }
        List<ExternalMaterialCollection> list = new ArrayList<>();
        if (!Check.isNull(md5List) && !md5List.isEmpty()) {
            list = mapper.getKuaiShouInternalMaterial(md5List);
            for (ExternalMaterialCollection materialCollection : list) {
                JSONObject entity2 = map.get(materialCollection.getMd5());
                if (!Check.isNull(entity2)) {
                    materialCollection.setUserId(entity2.getString("userId"));
                    materialCollection.setModalityTag(getList(entity2.getString("formTagList")));
                    materialCollection.setDaTag(getList(entity2.getString("moodTagList")));
                    materialCollection.setSceneTag(getList(entity2.getString("sceneTagList")));
                    materialCollection.setIndustry(entity2.getString("industry"));
                    materialCollection.setStatDate(entity2.getString("statDate"));
                }
            }
        }
        if (!Check.isNull(list)) {
            mapper.replaceBatch(list);
        }

        md5List = mapper.getMd5ByMediaType(1);// 1头条，2快手
        Map<String, JSONObject> map1 = new HashMap<>();
        for (JSONObject object : md5List) {
            map1.put(object.getString("md5"), object);
        }
        if (!Check.isNull(md5List) && !md5List.isEmpty()) {
            list = mapper.getBytedanceInternalMaterial(md5List);
            for (ExternalMaterialCollection materialCollection : list) {
                JSONObject entity1 = map1.get(materialCollection.getMd5());
                if (!Check.isNull(entity1)) {
                    materialCollection.setUserId(entity1.getString("userId"));
                    materialCollection.setModalityTag(getList(entity1.getString("formTagList")));
                    materialCollection.setDaTag(getList(entity1.getString("moodTagList")));
                    materialCollection.setSceneTag(getList(entity1.getString("sceneTagList")));
                    materialCollection.setIndustry(entity1.getString("industry"));
                    materialCollection.setStatDate(entity1.getString("statDate"));
                }
            }
        }
        if (!Check.isNull(list)) {
            mapper.replaceBatch(list);
        }
        return Result.ok("success");
    }

    private String getList(String str) {
        try {
            if (Check.isNull(str)) {
                return null;
            }
            String[] split = str.split(",");
            List<String> list = Arrays.asList(split);
            return JSONObject.toJSONString(list);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public Result<Object> getTagDetail(String md5, Integer mediaType) {
        QueryWrapper<ExternalMaterialCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("media_type", mediaType);
        queryWrapper.eq("md5", md5).last("limit 1");
        ExternalMaterialCollection one = this.getOne(queryWrapper);
        if (Check.isNull(one)) {
            return Result.error("未查询到素材");
        }
        List<TagInfo> modTagList = new ArrayList<>();
        List<TagInfo> modalityTagList = new ArrayList<>();
        List<TagInfo> sceneTagList = new ArrayList<>();
        JSONArray modTagArr = JSONArray.parseArray(one.getDaTag());
        if (!Check.isNull(modTagArr) && !modTagArr.isEmpty()) {
            modTagList = tagInfoService.getListByCode(modTagArr);
        }

        JSONArray ModalityTagArr = JSONArray.parseArray(one.getModalityTag());
        if (!Check.isNull(ModalityTagArr) && !ModalityTagArr.isEmpty()) {
            modalityTagList = tagInfoService.getListByCode(ModalityTagArr);
        }
        JSONArray sceneTagArr = JSONArray.parseArray(one.getSceneTag());
        if (!Check.isNull(sceneTagArr) && !sceneTagArr.isEmpty()) {
            sceneTagList = tagInfoService.getListByCode(sceneTagArr);
        }

        JSONObject result = new JSONObject();
        result.put("modTagList", modTagList);
        result.put("modalityTagList", modalityTagList);
        result.put("sceneTagList", sceneTagList);
        return Result.ok(result);
    }
}


