package com.gic.haoban.manage.service.service.impl;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.gic.commons.util.HttpClient;
import com.gic.enterprise.api.dto.EnterpriseDTO;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.haoban.manage.service.util.ApolloUtils;
import com.gic.haoban.manage.api.qdto.combined.CombinedQDTO;
import com.gic.haoban.manage.service.context.combined.ImageCombined;
import com.gic.redis.data.util.RedisUtil;
import com.gic.thirdparty.cloudfile.CloudFileUtil;
import com.gic.thirdparty.cloudfile.enums.CloudFileBusinessOptEnum;
import com.gic.thirdparty.cloudfile.enums.CloudFileTypeEnum;
import com.gic.thirdparty.cloudfile.pojo.CloudFileInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gic.api.base.commons.JSONResponse;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.ContentMaterialDTO;
import com.gic.haoban.manage.api.dto.MaterialDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanMaterialMapper;
import com.gic.haoban.manage.service.dao.mapper.TabMaterialContentMapper;
import com.gic.haoban.manage.service.entity.TabHaobanMaterial;
import com.gic.haoban.manage.service.entity.TabMaterialContent;
import com.gic.haoban.manage.service.service.MaterialService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.wechat.api.enums.QywxMediaTypeEnum;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import com.gic.weimob.common.Md5Util;
import com.github.pagehelper.Page;

@Service
public class MaterialServiceImpl implements MaterialService {

    private static final Logger logger = getLogger(MaterialService.class);
    
    @Autowired
    private TabHaobanMaterialMapper mapper;
    @Autowired
    private TabMaterialContentMapper materialContentMapper ;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;
    @Autowired
    private EnterpriseService enterpriseService;
    @Autowired
    private QywxSuiteApiService qywxSuiteApiService ;
    @Autowired
    private Config config;

    @Override
    public List<MaterialDTO> listMaterialByCategoryId(String categoryId) {
        return EntityUtil.changeEntityListByJSON(MaterialDTO.class, mapper.listMaterialByCategoryId(categoryId));
    }

    @Override
    public void insertMaterial(MaterialDTO materialDTO) {
        materialDTO.setCreateTime(new Date());
        materialDTO.setUpdateTime(materialDTO.getCreateTime());
        materialDTO.setStatusFlag(1);
        materialDTO.setMaterialId(StringUtil.randomUUID());
        mapper.insert(EntityUtil.changeEntityByJSON(TabHaobanMaterial.class, materialDTO));

    }

    @Override
    public void batchInsertMaterial(List<MaterialDTO> materialList) {
        mapper.batchInsert(EntityUtil.changeEntityListByOrika(TabHaobanMaterial.class, materialList));
    }

    @Override
    public MaterialDTO selectMaterialById(String materialId) {
        return EntityUtil.changeEntityByJSON(MaterialDTO.class, mapper.selectByPrimaryKey(materialId));
    }

    @Override
    public List<MaterialDTO> listMaterialByIds(List<String> materialIds) {
        return EntityUtil.changeEntityListByOrika(MaterialDTO.class, mapper.listByids(materialIds));
    }

    @Override
    public void edit(MaterialDTO materialDTO) {
        materialDTO.setUpdateTime(new Date());
        mapper.updateByPrimaryKeySelective(EntityUtil.changeEntityByJSON(TabHaobanMaterial.class, materialDTO));
    }

    @Override
    public Page<TabHaobanMaterial> listMaterial(String wxEnterpriseId, String keyword, String categoryId, Integer materialType) {
        return mapper.listMaterial(wxEnterpriseId,keyword,categoryId,materialType);
    }

    @Override
    public Page<TabHaobanMaterial> listMaterial(String wxEnterpriseId, String keyword, List<String> categoryIds, Integer materialType) {
        List<TabHaobanMaterial> materials = mapper.listMaterialByCategoryIds(wxEnterpriseId, keyword, categoryIds, materialType);
        return (Page) materials;
    }

    @Override
    public MaterialDTO getMaterialByFromMaterialId(String fromMaterialId, String wxEnterpriseId) {
        TabHaobanMaterial tabHaobanMaterial = mapper.selectByfromMaterialId(fromMaterialId, wxEnterpriseId);
        return EntityUtil.changeEntityByJSON(MaterialDTO.class, tabHaobanMaterial);
    }

    @Override
    public List<MaterialDTO> listMaterialByFromMateralId(String fromMaterialId) {
        List<TabHaobanMaterial> list = mapper.listByfromMaterialId(fromMaterialId);
        return EntityUtil.changeEntityListByOrika(MaterialDTO.class, list);
    }

    @Override
    public void delmaterialByIds(List<String> ids) {
        mapper.delMaterialByIds(ids);
    }

    @Override
    public MaterialDTO getHasChangeMadieMaterialById(String materialId, int from) {
        MaterialDTO materialDTO = null ;
        TabMaterialContent entity =null ;
        if(from == 1) {
            materialDTO = this.selectMaterialById(materialId);
        }
        if(from == 2) {
            entity =this.materialContentMapper.selectById(materialId) ;
            if(null != entity) {
                materialDTO = EntityUtil.changeEntityByJSON(MaterialDTO.class, entity) ;
            }
        }
        if (null == materialDTO) {
            return null;
        }
        Date lastUploadTime = materialDTO.getWxLastUploadTime();
        Date date = new Date();
        Date compareDate = DateUtils.addDays(date, -3);
        if (lastUploadTime != null && lastUploadTime.after(compareDate) && StringUtils.isNotBlank(materialDTO.getMediaId())) {
            return materialDTO;
        }
        Integer materialType = materialDTO.getMaterialType();
        String madiaId = materialDTO.getMediaId();
        //需要上传的类型
        List<Integer> typeList = Arrays.asList(2, 4, 5, 6 , 7);
        if (typeList.contains(materialType)) {
            madiaId = this.reUpdalodMetail(materialId,from);
        }
        materialDTO.setMediaId(madiaId);
        materialDTO.setWxLastUploadTime(date);
        return materialDTO;
        
    }

      private String reUpdalodMetail(String materialId,int from) {
          JSONResponse jp = this.reUpdalodMetailJson(materialId, from) ;
          if(null == jp) {
              return "";
          }
          if (jp.getErrorCode() == 0) {
              return jp.getResult().toString() ;
          }
          return "";
      }

      public JSONResponse reUpdalodMetailJson(String materialId,int from) {
          JSONResponse jp = new JSONResponse() ;
          MaterialDTO old = null ;
          TabMaterialContent entity =null ;
          int qwUploadFrom = 1 ;
          if(from == 1) {
              old = this.selectMaterialById(materialId);
          }
          if(from == 2) {
              entity =this.materialContentMapper.selectById(materialId) ;
              if(null != entity) {
                  old = EntityUtil.changeEntityByJSON(MaterialDTO.class, entity) ;
              }
              // 1群发 2朋友圈
              qwUploadFrom = entity.getMediaType() ;
          }
          Integer type = old.getMaterialType();
          if (type == null) {
              return jp;
          }
          String wxEnterpriseId = old.getWxEnterpriseId();
          WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
          if (qwDTO == null) {
              logger.info("qwDTO is null");
              return jp;
          }
          String url = "";
          QywxMediaTypeEnum fileType = null;
          if (type == 2) {
              fileType = QywxMediaTypeEnum.IMAGE;
              url = old.getImgUrl();
          }
          if (type == 4) {
              fileType = QywxMediaTypeEnum.VIDEO;
              url = old.getLink();
          }
          if (type == 5) {
              fileType = QywxMediaTypeEnum.FILE;
              url = old.getLink();
          } else if (type == 6 || type ==7) {
              fileType = QywxMediaTypeEnum.IMAGE;
              url = old.getImgUrl();
          }
          if (fileType == null) {
              logger.error("materialId无类型,materialId:{}", materialId);
              return jp;
          }
          if(from == 2) {
              url = entity.getImgUrl() ;
          }
          String[] arr = null ;
          if(url.contains("?")) {
              arr = url.split("\\?")[0].split("/") ;
          }else {
             arr = url.split("/");
          }
          int count = arr.length;
          boolean selfFlag = qwDTO.isSelf() ;
          if(qwUploadFrom==2) {
              // 朋友圈上传接口
              if (type == 2) {
                  if(url.contains("?")) {
                     logger.info("url有参数={}",url);
                     url = url.split("\\?")[0] ;
                  }
                  String key = "haoban:material:" + url;
                  String cache = (String)RedisUtil.getCache(key);
                  JSONObject jsonObject = null;
                  if (StringUtils.isBlank(cache)) {
                      String imageInfoUrl = url + "?imageInfo";
                      Map<String, Object> map = HttpClient.getHttpByGet(imageInfoUrl);
                      String response = (String) map.get("response");
                      if (StringUtils.isBlank(response)) {
                          throw new RuntimeException();
                      }
                      jsonObject = JSONObject.parseObject(response);
                      RedisUtil.setCache(key, response, 1L, TimeUnit.DAYS);
                  }else {
                      jsonObject = JSONObject.parseObject(cache);
                  }
                  Integer width = jsonObject.getInteger("width");
                  Integer height = jsonObject.getInteger("height");
                  Integer size = jsonObject.getInteger("size");
                  String extensions = url.substring(url.lastIndexOf(".") + 1);
                  //朋友圈类型图片，长边不超过10800像素，短边不超过1080像素
                  //图片宽高超过限制 或 大小大于2m 处理图片
                  if (size / 1000 > 2000 || width > 1080 || height > 10800 ||
                          (Objects.equals(extensions, "png") && size / 1000 > 1000 && ApolloUtils.compressShareEid(wxEnterpriseId))) {
                      url += "?imageView2/2/w/1080/h/10800/format/jpg";
                  }
                  logger.info("url={}",url);
              }
              jp = qywxSuiteApiService.uploadAttachment(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), url, arr[count - 1], fileType.getCode() , selfFlag , qwDTO.getUrlHost());
          }else {
              // 群发上传
              jp = qywxSuiteApiService.uploadMedia(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), url, arr[count - 1], fileType.getCode() , selfFlag , qwDTO.getUrlHost());
          }
          if (jp.getErrorCode() == 0) {
              if(from==1) {
                  old.setWxLastUploadTime(new Date());
                  old.setMediaId(jp.getResult().toString());
                  this.edit(old);
              }
              if(from==2) {
                  entity.setWxLastUploadTime(new Date());
                  entity.setMediaId(jp.getResult().toString());
                  this.materialContentMapper.updateByPrimaryKey(entity) ;
              }
          }
          return jp;
      }

    public static void main(String[] args) {
        String url = "https://platform-1251519181.cos.ap-shanghai.myqcloud.com/image/jhdm/common-fbcae3533d414bf8baac917df600b20e.png";
//        Map<String, Object> map = HttpClient.getHttpByGet(url + "?imageInfo");
//        String response = (String) map.get("response");
//        if (StringUtils.isBlank(response)) {
//            throw new RuntimeException();
//        }
//        JSONObject jsonObject = null;
//        jsonObject = JSONObject.parseObject(response);
//        Integer width = jsonObject.getInteger("width");
//        Integer height = jsonObject.getInteger("height");
//        Integer size = jsonObject.getInteger("size");
//        //图片宽高超过限制 或 大小大于2m 处理图片
//        if (size / 1000 > 2000 || width > 1440 || height > 1080) {
//            url+= "?imageView2/2/w/1440/h/1080" ;
//        }
        String substring = url.substring(url.lastIndexOf(".") + 1);
        logger.info("url={}",substring);
    }

      public List<String> getImageMediaId(String wxEnterpriseId, List<ContentMaterialDTO> imageList, int mediaType) {
            List<String> materialIdList = new ArrayList<>();
            imageList.forEach(dto -> {
                String imageUrl = dto.getImgUrl();
                int type = dto.getMaterialType();
                String md5 = null ;
                if(type==7) {
                    md5 = Md5Util.MD5(imageUrl + type + dto.getCanvasCouponUUID());
                }else {
                    md5 = Md5Util.MD5(imageUrl+type);
                }
                TabMaterialContent tab = this.materialContentMapper.selectByUrl(wxEnterpriseId, md5, mediaType);
                if (null != tab) {
                    Integer materialType = tab.getMaterialType();
                    //兼容视频没有封面图
                    if (materialType == 4 && StringUtils.isBlank(tab.getVideoImgUrl()) && StringUtils.isNotBlank(dto.getVideoImgUrl())) {
                        this.materialContentMapper.updateVideoImgUrl(tab.getMaterialId(),dto.getVideoImgUrl());
                    }
                    materialIdList.add(tab.getMaterialId());
                } else {
                    String id = StringUtil.randomUUID();
                    tab = new TabMaterialContent();
                    tab.setMaterialId(id);
                    tab.setMaterialType(type);
                    tab.setImgUrl(imageUrl);
                    tab.setUrlMd5(md5);
                    tab.setMediaType(mediaType);
                    tab.setWxEnterpriseId(wxEnterpriseId);
                    tab.setVideoImgUrl(dto.getVideoImgUrl());
                    tab.setAppid(dto.getAppid());
                    tab.setMaterialTitle(dto.getMaterialTitle());
                    tab.setLink(dto.getLink());
                    if(mediaType==7) {
                        tab.setLink(dto.getCanvasCouponUUID());
                    }
                    this.materialContentMapper.insert(tab);
                    materialIdList.add(id);
                }
            });
            return materialIdList;
        }

    @Override
    public List<MaterialDTO> listContentMaterialByIds(List<String> materialIds,Integer mediaType) {
        List<TabMaterialContent> contentList = materialContentMapper.listByIds(materialIds,mediaType);
        List<MaterialDTO> materialDTOS = contentList.stream().map(material -> {
            MaterialDTO materialDTO = new MaterialDTO();
            materialDTO.setMaterialId(material.getMaterialId());
            materialDTO.setMaterialType(material.getMaterialType());
            if (material.getMaterialType() == 1) {
                materialDTO.setMaterialContent(material.getImgUrl());
            } else if (material.getMaterialType() == 4) {
                materialDTO.setImgUrl(material.getVideoImgUrl());
                materialDTO.setLink(material.getImgUrl());
            } else {
                materialDTO.setImgUrl(material.getImgUrl());
            }
            materialDTO.setWxLastUploadTime(material.getWxLastUploadTime());
            materialDTO.setMediaId(material.getMediaId());
            materialDTO.setWxEnterpriseId(material.getWxEnterpriseId());
            materialDTO.setStatusFlag(1);
            materialDTO.setCreateTime(material.getCreateTime());
            materialDTO.setUpdateTime(material.getUpdateTime());
            return materialDTO;
        }).collect(Collectors.toList());
        return materialDTOS;
    }

    @Override
    public JSONResponse getMaterialIdByCombined(String wxEnterpriseId, CombinedQDTO combinedQDTO) {
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        JSONResponse jsonResponse = new JSONResponse();
        jsonResponse.setErrorCode(9999);
        jsonResponse.setErrorMessage("获取媒体id失败");
        try {
            String[] arr = null ;
            String imageUrl = combinedQDTO.getImageUrl();
            //合成图片
            byte[] combinedImageData = ImageCombined.getCombinedImage(combinedQDTO);
            if (combinedImageData == null) {
                logger.info("合成图片的数据为空");
                return jsonResponse;
            }
            if(imageUrl.contains("?")) {
                arr = imageUrl.split("\\?")[0].split("/") ;
            }else {
                arr = imageUrl.split("/");
            }
            JSONResponse json = null;

            Integer mediaType = combinedQDTO.getMediaType();
            if (Objects.equals(1,mediaType)) {
                json = qywxSuiteApiService.uploadMedia(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), combinedImageData, arr[arr.length - 1], QywxMediaTypeEnum.IMAGE.getCode(), qwDTO.isSelf(), qwDTO.getUrlHost());
            }else if (Objects.equals(2,mediaType)) {
                json = qywxSuiteApiService.uploadAttachment(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), combinedImageData, arr[arr.length - 1], QywxMediaTypeEnum.IMAGE.getCode(), qwDTO.isSelf(), qwDTO.getUrlHost());
            } else if (Objects.equals(3, mediaType)) {
                EnterpriseDTO enterprise = enterpriseService.getEnterpriseById(combinedQDTO.getEnterpriseId());
                if (enterprise == null) {
                    return jsonResponse;
                }
                CloudFileInfo uploadInfo = CloudFileUtil.uploadFile(combinedImageData, "jpg",  CloudFileTypeEnum.IMAGE,  enterprise.getFactoryCode(), CloudFileBusinessOptEnum.COMMON) ;
                String orgFileUrl = uploadInfo.getOrgFileUrl();
                if (StringUtils.isBlank(orgFileUrl)) {
                    return jsonResponse;
                }
                json = new JSONResponse();
                json.setErrorCode(0);
                json.setSuccess(true);
                json.setResult(orgFileUrl);
            }
            return json;
        } catch (Exception e) {
            logger.info("合成图片获取媒体id异常",e);
            return jsonResponse;
        }
    }
}
