package com.yiqi.crm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.yiqi.common.exception.GlobalException;
import com.yiqi.common.utils.DateUtils;
import com.yiqi.common.utils.file.ImageUtils;
import com.yiqi.crm.domain.WxReply;
import com.yiqi.crm.mapper.WxReplyMapper;
import com.yiqi.crm.service.CrmWechatSettingService;
import com.yiqi.crm.service.IWxReplyService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 微信内容管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-07-27
 */
@Service
public class WxReplyServiceImpl extends ServiceImpl<WxReplyMapper, WxReply> implements IWxReplyService {
    @Autowired
    private WxReplyMapper wxReplyMapper;

    @Autowired
    private CrmWechatSettingService crmWechatSettingService;
    /**
     * 查询微信内容管理
     *
     * @param replyId 微信内容管理主键
     * @return 微信内容管理
     */
    @Override
    public WxReply selectWxReplyByReplyId(Long replyId) {
        return baseMapper.selectWxReplyByReplyId(replyId);
    }

    /**
     * 查询微信内容管理列表
     *
     * @param wxReply 微信内容管理
     * @return 微信内容管理
     */
    @Override
    public List<WxReply> selectWxReplyList(WxReply wxReply) {
        return wxReplyMapper.selectWxReplyList(wxReply);
    }

    /**
     * 新增微信内容管理
     *
     * @param wxReply 微信内容管理
     * @return 结果
     */
    @Override
    public int insertWxReply(WxReply wxReply) throws Exception {
        wxReply.setCreateTime(DateUtils.getNowDate());
        wxReply.setUpdateTime(DateUtils.getNowDate());
        wxReply.setLookNumber("0");
        wxReply.setStatus("0");
        // 查询重复关键字
        if ("10730".equals(wxReply.getReplyType()) || "10740".equals(wxReply.getReplyType())){
            Map<String, Object> param = Maps.newHashMap();
            param.put("keyWords", wxReply.getKeyWords());
            param.put("keyWordsType", "10520");
            List<WxReply> keyWordsReplyList = wxReplyMapper.getKeyWordsReplyList(param);
            if (CollUtil.isNotEmpty(keyWordsReplyList)){
                throw  new GlobalException("【" + wxReply.getKeyWords() + "】该关键字已存在");
            }
        }
        // 图文需要上传图片逻辑
        if ("10610".equals(wxReply.getContentType())){
            if(StrUtil.isNotEmpty(wxReply.getPictureUrl())){
                // 下载图片到临时文件,并执行上传素材管理
                String mediaId = crmWechatSettingService.uploadPicToMaterial(wxReply.getPictureUrl());
                wxReply.setMediaId(mediaId);
            }
        }
        return baseMapper.insert(wxReply);
    }

    /**
     * 修改微信内容管理
     *
     * @param wxReply 微信内容管理
     * @return 结果
     */
    @Override
    public int updateWxReply(WxReply wxReply) throws Exception {
        if ("10730".equals(wxReply.getReplyType()) || "10740".equals(wxReply.getReplyType())){
            // 查询重复关键字
            Map<String, Object> param = Maps.newHashMap();
            param.put("keyWords", wxReply.getKeyWords());
            param.put("keyWordsType", "10520");
            List<WxReply> keyWordsReplyList = wxReplyMapper.getKeyWordsReplyList(param);
            if (CollUtil.isNotEmpty(keyWordsReplyList)){
                List<WxReply> collect = keyWordsReplyList.stream().filter(wxReply1 -> !wxReply1.getReplyId().equals(wxReply.getReplyId())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(collect)){
                    throw  new GlobalException("【" + wxReply.getKeyWords() + "】该关键字已存在");
                }
            }
        }

        // 图文需要上传图片逻辑
        if ("10610".equals(wxReply.getContentType()) && StrUtil.isNotEmpty(wxReply.getPictureUrl())){
            // 查询 数据库的原来的
            WxReply reply = baseMapper.selectById(wxReply.getReplyId());
            //  原来回复不是图文,直接上传素材管理
            if (!"10610".equals(reply.getContentType())){
                String mediaId = crmWechatSettingService.uploadPicToMaterial(wxReply.getPictureUrl());
                wxReply.setMediaId(mediaId);
            }else {
                // 原来是图文,但是老的和新的不一样,则把来的删除了.上传新的. 否则如果一样,不需要操作上传图片.直接更新其他内容
                if (!StrUtil.equals(reply.getPictureUrl(),wxReply.getPictureUrl())){
                    crmWechatSettingService.deleteMaterial(reply.getMediaId());
                    String mediaId = crmWechatSettingService.uploadPicToMaterial(wxReply.getPictureUrl());
                    wxReply.setMediaId(mediaId);
                }
            }
        }
        wxReply.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(wxReply);
    }

    /**
     * 批量删除微信内容管理
     *
     * @param replyIds 需要删除的微信内容管理主键
     * @return 结果
     */
    @Override
    public int deleteWxReplyByReplyIds(Long[] replyIds) {
        return wxReplyMapper.deleteWxReplyByReplyIds(replyIds);
    }

    /**
     * 删除微信内容管理信息
     *
     * @param replyId 微信内容管理主键
     * @return 结果
     */
    @Override
    public int deleteWxReplyByReplyId(Long replyId) {
        return wxReplyMapper.deleteWxReplyByReplyId(replyId);
    }

    @Override
    public WxReply selectWxReplyByReplyType(String replyType) {
        List<WxReply> replyList = wxReplyMapper.selectWxReplyByReplyType(replyType);
        if(CollUtil.isEmpty(replyList)){
            return null;
        }
        return replyList.get(0);
    }

    /**
     * 查询图文回复列表 给多图文添加用
     * @return 结果
     */
    @Override
    public List<WxReply> getPicTextReplyList() {
        Map<String, Object> param = Maps.newHashMap();
        param.put("replyType", "10730");
        param.put("contentType", "10610");
        param.put("status", "0");
        return wxReplyMapper.getKeyWordsReplyList(param);
    }

    /**
     * 获取包含对应关键词信息
     *
     * @param keyWords 关键词
     * @return 结果
     */
    @Override
    public List<WxReply> getKeyWordsReplyListByContain(String keyWords) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("keyWords", keyWords);
        param.put("isUseKeyWords", "0");
        param.put("replyType", "10730");
        param.put("keyWordsType", "10510");
        param.put("status", "0");
        return wxReplyMapper.getKeyWordsReplyList(param);
    }

    /**
     * 获取完全匹配对应关键词信息
     *
     * @param keyWords 关键词
     * @return 结果
     */
    @Override
    public List<WxReply> getKeyWordsReplyListByEqual(String keyWords) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("keyWords", keyWords);
        param.put("isUseKeyWords", "0");
        param.put("replyType", "10730");
        param.put("keyWordsType", "10520");
        param.put("status", "0");
        return wxReplyMapper.getKeyWordsReplyList(param);
    }

    /**
     * 获取默认回复信息
     *
     * @return 结果
     */
    @Override
    public WxReply getKeyWordsReplyListByDefault() {
        Map<String, Object> param = Maps.newHashMap();
        param.put("replyType", "10710");
        param.put("status", "0");
        List<WxReply> list = wxReplyMapper.getKeyWordsReplyList(param);
        if (CollUtil.isNotEmpty(list)) {
            return list.stream().sorted(Comparator.comparing(WxReply::getSort)).collect(Collectors.toList()).get(0);
        }
        return null;
    }

    @Override
    public WxReply getKeyWordsReplyListBySubscribe() {
        Map<String, Object> param = Maps.newHashMap();
        param.put("replyType", "10720");
        param.put("status", "0");
        List<WxReply> list = wxReplyMapper.getKeyWordsReplyList(param);
        if (CollUtil.isNotEmpty(list)) {
            return list.stream().sorted(Comparator.comparing(WxReply::getSort)).collect(Collectors.toList()).get(0);
        }
        return null;
    }

    @Override
    public Integer countLookNumber(WxReply wxReply) {
        return wxReplyMapper.countLookNumber(wxReply);
    }


    /**
     * 根据回复内容类型，构建回复信息
     *
     * @param wxReply
     * @param wxMessage
     * @param wxMpService
     * @return
     */

    public WxMpXmlOutMessage getWxReplyInfo(WxReply wxReply, WxMpXmlMessage wxMessage, WxMpService wxMpService) {
        if (wxReply == null) {
            return null;
        }
        // 文本回复
        if ("10620".equals(wxReply.getContentType())) {
            return WxMpXmlOutMessage
                    .TEXT()
                    .content(wxReply.getPicTextDetailContent())
                    .fromUser(wxMessage.getToUser())
                    .toUser(wxMessage.getFromUser())
                    .build();
        }
        // 图文回复
        if ("10610".equals(wxReply.getContentType())) {
            return this.buildOne(wxReply, wxMessage, wxMpService);
        }
        // 多图文回复
        if ("10630".equals(wxReply.getContentType())) {
            List<WxReply> wxReplyList = new ArrayList<>();
            wxReplyList.add(wxReply);
            return this.buildMore(wxReplyList, wxMessage, wxMpService);
        }
        return null;
    }

    /**
     * 根据关键字，查询回复信息
     *
     * @param keyWords
     * @return 返回优先级最高的一条
     */
    public WxReply handleKeyWordsText(String keyWords) {
        if (StrUtil.isEmpty(keyWords)) {
            return null;
        }
        // 通过关键词,查询完全匹配的回复内容
        List<WxReply> equalList = this.getKeyWordsReplyListByEqual(keyWords);
        if (CollUtil.isEmpty(equalList)) {
            // 通过关键词,查询包含匹配的回复内容
            List<WxReply> ContainList = this.getKeyWordsReplyListByContain(keyWords);
            if (CollUtil.isEmpty(ContainList)) {
                return null;
            }
            return ContainList.stream().sorted(Comparator.comparing(WxReply::getSort)).collect(Collectors.toList()).get(0);
        }
        return equalList.stream().sorted(Comparator.comparing(WxReply::getSort)).collect(Collectors.toList()).get(0);
    }

    /**
     * 处理单图文回复内容
     *
     * @param wxReply
     * @return
     */
    public WxMpXmlOutMessage buildOne(WxReply wxReply, WxMpXmlMessage wxMessage,
                                      WxMpService service) {
        if (wxReply == null) {
            return null;
        }
        List<WxMpXmlOutNewsMessage.Item> content = this.handleOneNewsInfo(wxReply);

        return WxMpXmlOutMessage
                .NEWS()
                .articles(content)
                .fromUser(wxMessage.getToUser())
                .toUser(wxMessage.getFromUser())
                .build();
    }

    /**
     * 处理多图文回复内容
     *
     * @param wxReplyList
     * @return
     */
    public WxMpXmlOutMessage buildMore(List<WxReply> wxReplyList, WxMpXmlMessage wxMessage,
                                       WxMpService service) {
        if (CollUtil.isEmpty(wxReplyList)) {
            return null;
        }
        List<WxMpXmlOutNewsMessage.Item> content = this.handleMoreNewsInfo(wxReplyList);

        return WxMpXmlOutMessage
                .NEWS()
                .articles(content)
                .fromUser(wxMessage.getToUser())
                .toUser(wxMessage.getFromUser())
                .build();
    }

    /**
     * 处理单图文回复内容
     *
     * @param wxReply
     * @return
     */
    public List<WxMpXmlOutNewsMessage.Item> handleOneNewsInfo(WxReply wxReply) {
        if (wxReply == null) {
            return null;
        }
        WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
        item.setTitle(wxReply.getTitle());
        item.setDescription(wxReply.getPicTextDetailContent());
        item.setPicUrl(wxReply.getPictureUrl());
        item.setUrl(wxReply.getPicTextUrl());
        List<WxMpXmlOutNewsMessage.Item> content = new ArrayList<>();
        content.add(item);
        return content;
    }

    /**
     * 处理多图文回复内容
     *
     * @param wxReplyList
     * @return
     */
    public List<WxMpXmlOutNewsMessage.Item> handleMoreNewsInfo(List<WxReply> wxReplyList) {
        if (CollUtil.isEmpty(wxReplyList)) {
            return null;
        }
        List<WxMpXmlOutNewsMessage.Item> content = new ArrayList<>();
        wxReplyList.forEach(wxReply -> {
            WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
            item.setTitle(wxReply.getTitle());
            item.setDescription(wxReply.getPicTextDetailContent());
            item.setPicUrl(wxReply.getPictureUrl());
            item.setUrl(wxReply.getPicTextUrl());
            content.add(item);
        });
        return content;
    }
}

