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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.collection.ListUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.JSONResponse;
import com.gic.api.base.commons.Page;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.base.api.common.ServiceResponse;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.BatchAddMaterialDTO;
import com.gic.haoban.manage.api.dto.ContentMaterialDTO;
import com.gic.haoban.manage.api.dto.MaterialCategoryDTO;
import com.gic.haoban.manage.api.dto.MaterialDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.service.MaterialApiService;
import com.gic.haoban.manage.service.config.Config;
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.entity.TabMiniprogramSetting;
import com.gic.haoban.manage.service.service.MaterialCategoryService;
import com.gic.haoban.manage.service.service.MaterialService;
import com.gic.haoban.manage.service.service.MiniprogramSettingService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.util.CommonUtil;
import com.gic.wechat.api.enums.QywxMediaTypeEnum;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import com.github.pagehelper.PageHelper;

@Service
public class MaterialApiServiceImpl implements MaterialApiService {

    @Autowired
    private MaterialCategoryService materialCategoryService;

    @Autowired
    private MaterialService materialService;

    @Autowired
    private QywxSuiteApiService qywxSuiteApiService;

    @Autowired
    private WxEnterpriseService wxEnterpriseService;

    @Autowired
    private Config config;

    @Autowired
    private MiniprogramSettingService miniprogramSettingService;
    @Autowired
    private TabMaterialContentMapper materialContentMapper ;

    private static Logger logger = LoggerFactory.getLogger(MaterialApiServiceImpl.class);

    @Override
    public boolean hasCategoryNameExsit(String categoryName, String categoryParentId, String categoryId,String wxEnterpriseId) {
        MaterialCategoryDTO category = materialCategoryService.hasCategoryNameExsit(categoryName, categoryParentId,wxEnterpriseId);
        if (category != null) {
            if (category.getCategoryId().equals(categoryId)) {
                return false;
            } else {
                return true;
            }
        }
        return false;

    }

    @Override
    public void insertCategory(MaterialCategoryDTO materialCategoryDTO) {
        materialCategoryService.insert(materialCategoryDTO);

    }

    @Override
    public List<MaterialCategoryDTO> listCategory(String wxEnterpriseId) {
        return materialCategoryService.listCategory(wxEnterpriseId);
    }

    @Override
    public MaterialCategoryDTO selectMaterialCategoryById(String categoryId) {
        return materialCategoryService.selectMaterialCategoryById(categoryId);
    }

    @Override
    public void editCategory(MaterialCategoryDTO materialCategoryDTO) {
        materialCategoryService.editCategory(materialCategoryDTO);


    }

    @Override
    public List<MaterialDTO> listMaterialByCategoryId(String categoryId) {
        return materialService.listMaterialByCategoryId(categoryId);
    }

    @Override
    public void insertMaterial(MaterialDTO materialDTO) {
        Integer type = materialDTO.getMaterialType();
        if (type == null) {
            logger.info("type is null");
            return;
        }
        String wxEnterpriseId = materialDTO.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if (qwDTO == null) {
            logger.info("qwDTO is null");
            return;
        }
        QywxMediaTypeEnum fileType = null;
        String url = "";
        if (type == 2) {
            fileType = QywxMediaTypeEnum.IMAGE;
            url = materialDTO.getImgUrl();
        }
        if (type == 4) {
            fileType = QywxMediaTypeEnum.VIDEO;
            url = materialDTO.getLink();
        }
        if (type == 5) {
            fileType = QywxMediaTypeEnum.FILE;
            url = materialDTO.getLink();
        }
        if (type == 6) {
            fileType = QywxMediaTypeEnum.IMAGE;
            url = materialDTO.getImgUrl();
        }
        if (type == 3) {
            String imgUrl = materialDTO.getImgUrl();
            logger.info("【上传图片】imgUrl={}", imgUrl);
            JSONResponse response = qywxSuiteApiService.uploadImage(qwDTO.getThirdCorpid() , qwDTO.getSelf3thSecret(), imgUrl , qwDTO.isSelf(),qwDTO.getUrlHost());
            logger.info("【上传图片返回】response={}", JSON.toJSONString(response));
            String wxImgUrl = response.getResult() == null ? "" : response.getResult().toString();
            materialDTO.setWxImgUrl(wxImgUrl);
        }
        if (fileType != null) {
            String[] arr = url.split("/");
            int count = arr.length;
            boolean selfFlag = qwDTO.isSelf() ;
            JSONResponse jp = qywxSuiteApiService.uploadMedia(qwDTO.getThirdCorpid() , qwDTO.getSelf3thSecret(), url, arr[count - 1], fileType.getCode(),selfFlag,qwDTO.getUrlHost());
            if (jp.getErrorCode() == 0) {
                materialDTO.setWxLastUploadTime(new Date());
                materialDTO.setMediaId(jp.getResult().toString());
                materialService.insertMaterial(materialDTO);
            }
        } else {
            materialService.insertMaterial(materialDTO);
        }
    }

    @Override
    public MaterialDTO selectMaterialById(String materialId) {
        return materialService.selectMaterialById(materialId);
    }

    @Override
    public List<MaterialDTO> listMaterialByIds(List<String> materialIds) {
        return materialService.listMaterialByIds(materialIds);
    }

    @Override
    public List<MaterialDTO> listContentMaterialByIds(List<String> materialIds) {
        return materialService.listContentMaterialByIds(materialIds,1);
    }

    @Override
    public List<MaterialDTO> listMaterialByIds(List<String> materialIds, Integer materialFrom) {
        if (materialFrom == null || materialFrom == 1) {
            return materialService.listMaterialByIds(materialIds);
        }else {
            List<MaterialDTO> materialDTOS = materialService.listContentMaterialByIds(materialIds, 1);
            materialDTOS.sort(((o1, o2) -> {
                int io1 = materialIds.indexOf(o1.getMaterialId());
                int io2 = materialIds.indexOf(o2.getMaterialId());
                return io1 - io2;
            }));
            return materialDTOS;
        }
    }

    @Override
    public void editMaterial(MaterialDTO materialDTO) {
        Integer type = materialDTO.getMaterialType();
        String materialId = materialDTO.getMaterialId();
        MaterialDTO old = materialService.selectMaterialById(materialId);
        String wxEnterpriseId = old.getWxEnterpriseId();
        if (type == null) {
            return;
        }
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if (qwDTO == null) {
            logger.info("qwDTO is null");
            return;
        }
        QywxMediaTypeEnum fileType = null;
        String url = "";
        String oldUrl = "";
        if (type == 2 || type == 6) {
            fileType = QywxMediaTypeEnum.IMAGE;
            url = materialDTO.getImgUrl();
            oldUrl = old.getImgUrl();
        }
        if (type == 4) {
            fileType = QywxMediaTypeEnum.VIDEO;
            url = materialDTO.getLink();
            oldUrl = old.getLink();
        }
        if (type == 5) {
            fileType = QywxMediaTypeEnum.FILE;
            url = materialDTO.getLink();
            oldUrl = old.getLink();
        }
        if (type == 3) {
            String imgUrl = materialDTO.getImgUrl();
            String oldImgUrl = materialDTO.getImgUrl();
            if (!imgUrl.equals(oldImgUrl)) {
                JSONResponse response = qywxSuiteApiService.uploadImage(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), imgUrl ,qwDTO.isSelf(),qwDTO.getUrlHost());
                String wxImgUrl = response.getResult() == null ? "" : response.getResult().toString();
                materialDTO.setWxImgUrl(wxImgUrl);
            }
        }
        if (fileType != null && !url.equals(oldUrl)) {
            String[] arr = url.split("/");
            int count = arr.length;
            boolean selfFlag = qwDTO.isSelf() ;
            JSONResponse jp = qywxSuiteApiService.uploadMedia(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), url , arr[count - 1], fileType.getCode(),selfFlag,qwDTO.getUrlHost());
            if (jp.getErrorCode() == 0) {
                materialDTO.setWxLastUploadTime(new Date());
                materialDTO.setMediaId(jp.getResult().toString());
                materialService.edit(materialDTO);
            }
        } else {
            materialService.edit(materialDTO);
        }

    }

    @Override
    public String reUpdalodMetail(String materialId) {
        MaterialDTO old = materialService.selectMaterialById(materialId);
        Integer type = old.getMaterialType();
        if (type == null) {
            return "";
        }
        String wxEnterpriseId = old.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if (qwDTO == null) {
            logger.info("qwDTO is null");
            return "";
        }
        String url = "";
        String oldUrl = "";
        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) {
            fileType = QywxMediaTypeEnum.IMAGE;
            url = old.getImgUrl();
        }
        if (fileType == null) {
            logger.error("materialId无类型,materialId:{}", materialId);
            return "";
        }
        String[] arr = url.split("/");
        int count = arr.length;
        JSONResponse jp = qywxSuiteApiService.uploadMedia(qwDTO.getThirdCorpid(), qwDTO.getSelf3thSecret(), url, arr[count - 1], fileType.getCode(),qwDTO.isSelf(),qwDTO.getUrlHost());
        if (jp.getErrorCode() == 0) {
            old.setWxLastUploadTime(new Date());
            old.setMediaId(jp.getResult().toString());
            materialService.edit(old);
        }
        return old.getMediaId();
    }

    private List<String> listSubCategoryIdsByParentId(String categoryId) {
        List<String> categoryIds = new ArrayList<>();
        categoryIds.add(categoryId);
        if (StringUtils.isBlank(categoryId)) {
            return categoryIds;
        }
        List<MaterialCategoryDTO> categoryDTOList = materialCategoryService.listByParentCategory(categoryId);
        if (CollectionUtils.isEmpty(categoryDTOList)) {
            return categoryIds;
        }
        for (MaterialCategoryDTO categoryDTO : categoryDTOList) {
            categoryIds.addAll(this.listSubCategoryIdsByParentId(categoryDTO.getCategoryId()));
        }
        return categoryIds;
    }

    @Override
    public Page<MaterialDTO> listMaterial(String wxEnterpriseId, String keyword, String categoryId,
                                          Integer materialType, BasePageInfo pageInfo) {
        List<String> categoryIds;
        if ("-1".equals(categoryId)) {
            // 传入-1默认查询全部
            categoryIds = Collections.emptyList();
        } else {
            categoryIds = this.listSubCategoryIdsByParentId(categoryId);
        }
        PageHelper.startPage(pageInfo.getPageNum(), pageInfo.getPageSize());
        com.github.pagehelper.Page<TabHaobanMaterial> page = materialService.listMaterial(wxEnterpriseId, keyword, categoryIds, materialType);
        List<TabHaobanMaterial> result = page.getResult();
        List<TabMiniprogramSetting> settings = miniprogramSettingService.listMiniprogram(wxEnterpriseId);
        if (CollectionUtils.isNotEmpty(result) && CollectionUtils.isNotEmpty(settings)) {
            Map<String, TabMiniprogramSetting> settingMap = settings.stream()
                    .collect(Collectors.toMap(
                            TabMiniprogramSetting::getAppId,
                            Function.identity(),
                            (a, b) -> a
                    ));
            result.forEach(dto -> {
                //小程序去判断逻辑
                if (dto.getMaterialType() != null && dto.getMaterialType() == 6) {
                    TabMiniprogramSetting miniprogramSetting = settingMap.get(dto.getAppId());
                    dto.setMaterialDesc(miniprogramSetting == null ? "--" : miniprogramSetting.getMiniprogramName());
                }
            });
        }
        return PageUtil.changePageHelperToCurrentPage(page, MaterialDTO.class);
    }

    @Override
    public List<MaterialCategoryDTO> listByParentCategory(String categoryId) {
        return materialCategoryService.listByParentCategory(categoryId);
    }

    @Override
    public ServiceResponse<Void> shareMaterial(String wxEnterpriseId, String toWxEnterpriseId, String materialId) {
        ServiceResponse<Void> res = new ServiceResponse<>();
        MaterialDTO materialDTO = materialService.selectMaterialById(materialId);
        if (null == materialDTO) {
            logger.info("不存在该素材");
            res.setCode(2);
            res.setMessage("不存在该素材");
            return res;
        }
        if (!materialDTO.getFromMaterialId().equals("-1")) {
            logger.info("该素材不允许分享");
            res.setCode(3);
            res.setMessage("该素材不允许分享");
            return res;
        }
        MaterialDTO fromMaterialDTO = materialService.getMaterialByFromMaterialId(materialId, toWxEnterpriseId);
        if (fromMaterialDTO != null) {
            logger.info("已经存在素材，不能重复分享");
            res.setCode(4);
            res.setMessage("已经存在素材，不能重复分享");
            return res;
        }
        materialDTO.setWxEnterpriseId(toWxEnterpriseId);
        materialDTO.setFromMaterialId(materialId);
        materialDTO.setMediaId(null);
        materialDTO.setWxLastUploadTime(null);
        materialService.insertMaterial(materialDTO);
        return res;
    }

    @Override
    public List<MaterialDTO> listByFromMaterialId(String materialId) {
        List<MaterialDTO> materialDTOS = materialService.listMaterialByFromMateralId(materialId);
        return materialDTOS;
    }

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

    @Override
    public MaterialDTO getHasChangeMadieMaterialById(String materialId) {
        MaterialDTO materialDTO = this.selectMaterialById(materialId);
        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);
        if (typeList.contains(materialType)) {
            madiaId = this.reUpdalodMetail(materialId);
        }
        materialDTO.setMediaId(madiaId);
        materialDTO.setWxLastUploadTime(date);
        return materialDTO;
    }

    @Override
    public void batchInsertMaterial(BatchAddMaterialDTO dto) {
        // 构造素材实体类
        BatchAddMaterialDTO.Material material = dto.getMaterial();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(material.getWxEnterpriseId()) ;
        if (qwDTO == null) {
            return;
        }
        List<BatchAddMaterialDTO.MaterialMedia> materialMediaList = dto.getMaterialMediaList();
        if (CollectionUtils.isEmpty(materialMediaList)) {
            return;
        }
        List<MaterialDTO> materialList = materialMediaList.stream().map(one -> {
            MaterialDTO materialDTO = new MaterialDTO();
            // 必填字段
            materialDTO.setCreateTime(new Date());
            materialDTO.setUpdateTime(materialDTO.getCreateTime());
            materialDTO.setStatusFlag(1);
            materialDTO.setMaterialId(StringUtil.randomUUID());
            // 传入字段
            materialDTO.setCategoryId(material.getCategoryId());
            materialDTO.setMaterialType(material.getMaterialType());
            materialDTO.setWxEnterpriseId(material.getWxEnterpriseId());
            materialDTO.setStaffId(material.getStaffId());
            materialDTO.setStaffName(material.getStaffName());
            // 图片类型素材标题为图片实际名称
            if (material.getMaterialType() == 2) {
                materialDTO.setMaterialTitle(one.getMediaName());
            } else {
                materialDTO.setMaterialTitle(material.getMaterialTitle());
            }
            materialDTO.setImgUrl(one.getMediaUrl());
            String mediaId = uploadMediaToWx(qwDTO.getThirdCorpid(), one.getMediaUrl(),qwDTO);
            if (StringUtils.isNotEmpty(mediaId)) {
                materialDTO.setWxLastUploadTime(new Date());
                materialDTO.setMediaId(mediaId);
            }
            return materialDTO;
        }).collect(Collectors.toList());
        // batch-insert
        materialService.batchInsertMaterial(materialList);
    }

    private String uploadMediaToWx(String corPid, String url, WxEnterpriseQwDTO qwDTO) {
        String[] arr = url.split("/");
        // 先写死为图片类型, 以后有别的再扩展
        QywxMediaTypeEnum fileType = QywxMediaTypeEnum.IMAGE;
        int count = arr.length;
        boolean selfFlag = qwDTO.isSelf() ;
        JSONResponse jp = qywxSuiteApiService.uploadMedia(corPid, qwDTO.getSelf3thSecret(), url, arr[count - 1], fileType.getCode(),selfFlag,qwDTO.getUrlHost());
        if (jp.getErrorCode() == 0) {
            return jp.getResult().toString();
        }
        return null;
    }
    
    
    public com.gic.api.base.commons.ServiceResponse<String> getMaterialId(String wxEnterpriseId, ContentMaterialDTO dto) {
        List<ContentMaterialDTO> imageList = Arrays.asList(dto) ;
        List<String> materialIdList = this.materialService.getImageMediaId(wxEnterpriseId, imageList, dto.getMediaType());
        if (CollectionUtils.isEmpty(materialIdList)) {
            com.gic.api.base.commons.ServiceResponse.failure("9999", "素材记录不存") ;
        }
        String materialId = materialIdList.get(0) ;
        TabMaterialContent entity = this.materialContentMapper.selectById(materialId) ;
        if(null == entity) {
            com.gic.api.base.commons.ServiceResponse.failure("9999", "素材记录不存") ;
        }
        Date lastUploadTime = entity.getWxLastUploadTime();
        Date date = new Date();
        Date compareDate = DateUtils.addDays(date, -3);
        String madiaId= entity.getMediaId() ;
        if (lastUploadTime != null && lastUploadTime.after(compareDate) && StringUtils.isNotBlank(madiaId)) {
            return com.gic.api.base.commons.ServiceResponse.success(madiaId) ;
        }
        
        JSONResponse json = this.materialService.reUpdalodMetailJson(materialId,2) ;
        if (json.getErrorCode() == 0) {
            madiaId= json.getResult().toString() ;
            return com.gic.api.base.commons.ServiceResponse.success(madiaId) ;
        }else {
            return com.gic.api.base.commons.ServiceResponse.failure("9999",json.getErrorMessage()) ; 
        }
    }

    @Override
    public com.gic.api.base.commons.ServiceResponse<String> getMaterialIdByUrl(String wxEnterpriseId, ContentMaterialDTO dto) {
        List<ContentMaterialDTO> imageList = Lists.newArrayList(dto) ;
        List<String> materialIdList = this.materialService.getImageMediaId(wxEnterpriseId, imageList, dto.getMediaType());
        if (CollectionUtils.isEmpty(materialIdList)) {
            com.gic.api.base.commons.ServiceResponse.failure("9999", "素材记录不存") ;
        }
        String materialId = materialIdList.get(0) ;
        return com.gic.api.base.commons.ServiceResponse.success(materialId) ;
    }
}
