package com.pcloud.book.pcloudkeyword.biz.impl;

import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.dao.BookDao;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.content.ResourceConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.constant.BookBusinessConstants;
import com.pcloud.book.group.enums.AppAndProductTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.guide.biz.PcloudGuideBiz;
import com.pcloud.book.guide.biz.PcloudRobotWakeUpBiz;
import com.pcloud.book.guide.mapper.PcloudRobotSilenceMapper;
import com.pcloud.book.pcloudKeyword.dto.RobotClassifyDTO;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotBiz;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotClassifyBiz;
import com.pcloud.book.pcloudkeyword.dao.PcloudClassifyTemplateDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudKeywordClassifyDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudKeywordNameDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudRobotDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudRobotQrcodeDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudRobotWelcomeDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudTdDao;
import com.pcloud.book.pcloudkeyword.dao.PcloudTdRecordDao;
import com.pcloud.book.pcloudkeyword.dto.PcloudTdDTO;
import com.pcloud.book.pcloudkeyword.dto.PcloudTdReplyDTO;
import com.pcloud.book.pcloudkeyword.entity.*;
import com.pcloud.book.pcloudkeyword.enums.WelcomeReplyTypeEnum;
import com.pcloud.book.pcloudkeyword.set.PcloudRobotSet;
import com.pcloud.book.pcloudkeyword.facade.response.PcloudRobotResponseVO;
import com.pcloud.book.push.biz.SelfPushBiz;
import com.pcloud.book.skill.biz.PcloudSkillBiz;
import com.pcloud.book.skill.entity.PcloudSkill;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.contentcenter.resource.dto.ResourceDTO;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.wechatgroup.message.dto.SendTextDTO;
import com.pcloud.wechatgroup.selfrobot.dto.RobotBaseInfoDTO;
import com.sdk.wxgroup.SendFileVO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendPicMessageVO;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.pcloud.book.consumer.app.AppConsr;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Component("pcloudRobotBiz")
public class PcloudRobotBizImpl implements PcloudRobotBiz {

    private static final Logger LOGGER = LoggerFactory.getLogger(PcloudRobotBizImpl.class);


    @Autowired
    private PcloudRobotDao pcloudRobotDao;
    @Autowired
    private PcloudRobotWelcomeDao pcloudRobotWelcomeDao;
    @Autowired
    private ResourceConsr resourceConsr;
    @Autowired
    private PcloudKeywordClassifyDao pcloudKeywordClassifyDao;
    @Autowired
    private PcloudRobotQrcodeDao pcloudRobotQrcodeDao;
    @Value("${wechat.group.link.prefix}")
    private String wechatLinkPrefix;
    @Autowired
    private PcloudRobotSilenceMapper pcloudRobotSilenceMapper;
    @Autowired
    private PcloudClassifyTemplateDao pcloudClassifyTemplateDao;
    @Autowired
    private PcloudRobotClassifyBiz pcloudRobotClassifyBiz;
    @Autowired
    private PcloudTdDao pcloudTdDao;
    @Autowired
    private PcloudTdRecordDao pcloudTdRecordDao;
    @Autowired
    private PcloudKeywordNameDao pcloudKeywordNameDao;
    @Autowired
    private SelfPushBiz selfPushBiz;
    @Autowired
    private PcloudRobotWakeUpBiz pcloudRobotWakeUpBiz;
    @Autowired
    private PcloudGuideBiz pcloudGuideBiz;
    @Autowired
    private PcloudRobotSet pcloudRobotSet;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private PcloudSkillBiz pcloudSkillBiz;
    @Autowired
    private BookDao bookDao;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;

    @ParamLog(value = "[changeRobotRealStatus]", isAfterReturn = false)
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void changeRobotRealStatus(String wxId, Integer status) {
        PcloudRobot robot = pcloudRobotDao.getByWxId(wxId);
        if (Objects.isNull(robot)) {
            return;
        }
        if (!status.equals(robot.getRealStatus())) {
            pcloudRobotDao.updateRealStatus(wxId, status);
        }
        // 如果小号上线则缓存7s，心跳频率5s
        if (1 == status) {
            JedisClusterUtils.hset(BookBusinessConstants.ACTIVE_ROBOT_CACHE_KEY_PREFIX, wxId, String.valueOf(System.currentTimeMillis() + 7 * 1000));
        }
        //如果是手动上线，真实下线，发登录邮件
        if (0 == status && 1 == robot.getState()) {
            String emailKey = BookBusinessConstants.EMAIL_SPAN_TIME + wxId;
            String wxid = JedisClusterUtils.get(emailKey);
            if(wxid == null) {
                ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
                    LOGGER.info("发送登录二维码邮件===开始" + wxId);
                    wechatGroupConsr.sendQrcodeLoginEmail(wxId);
                    LOGGER.info("发送登录二维码邮件===结束" + wxId);
                });
                JedisClusterUtils.set(emailKey, wxId , 5 * 60);
            }
        }
        // 处理无响应的上线状态小号，更新为下线
        List<RobotClassifyDTO> allPcloudRobot = pcloudRobotDao.getAllPcloudRobot();
        List<String> ids = allPcloudRobot.stream().filter(x -> 1 == x.getRealStatus()).map(RobotClassifyDTO::getWxId).collect(Collectors.toList());
        Map<String, String> map = JedisClusterUtils.hgetAll(BookBusinessConstants.ACTIVE_ROBOT_CACHE_KEY_PREFIX);
        for (String id : ids) {
            String s = map.get(id);
            if (null == s) {
                JedisClusterUtils.hset(BookBusinessConstants.ACTIVE_ROBOT_CACHE_KEY_PREFIX, id, String.valueOf(System.currentTimeMillis() + 7 * 1000));
                continue;
            }
            // 如果超时没有收到心跳则下线
            if (System.currentTimeMillis() > Long.parseLong(s)) {
                pcloudRobotDao.updateRealStatus(id, 0);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPcloudRobot(PcloudRobot pcloudRobot) {
        pcloudRobotDao.insert(pcloudRobot);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePcloudRobot(PcloudRobot pcloudRobot) {
        if (!StringUtil.isEmpty(pcloudRobot.getUniqueNumber())){
            if (pcloudRobot.getUniqueNumber().length() > 20){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "编号长度不能超过20，请重新输入");
            }
            //校验编号是否重复
            PcloudRobot robot = pcloudRobotDao.getByUniqueNumber(pcloudRobot.getUniqueNumber());
            if (null != robot && !robot.getId().equals(pcloudRobot.getId())){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR, "编号重复，请重新输入");
            }
        }
        pcloudRobotDao.update(pcloudRobot);
        if(pcloudRobot.getRobotType() != null) {
            PcloudRobotQrcode robotQrcode = pcloudRobotQrcodeDao.getByRobotType(pcloudRobot.getRobotType());
            if(robotQrcode == null) {
                PcloudRobotQrcode pcloudRobotQrcode = new PcloudRobotQrcode();
                pcloudRobotQrcode.setRobotType(pcloudRobot.getRobotType());
                String linkUrl = wechatLinkPrefix + "/group/info?classify_id=" + pcloudRobot.getRobotType();
                String codeUrl = QrcodeUtils.create( UrlUtils.getShortUrl4Own(linkUrl));
                pcloudRobotQrcode.setLinkUrl(linkUrl);
                pcloudRobotQrcode.setQrcodeUrl(codeUrl);
                pcloudRobotQrcodeDao.insert(pcloudRobotQrcode);
            }
        }
        List<PcloudRobotWelcome> robotWelcomeList = pcloudRobot.getRobotWelcomeList();
        pcloudRobotWelcomeDao.deleteByPcloudRobotId(pcloudRobot.getId());
        if (ListUtils.isEmpty(robotWelcomeList)){
            return;
        }
        pcloudRobotWelcomeDao.batchInsert(robotWelcomeList);
    }

    @Override
    public void updatePcloudRobotByWxId(PcloudRobot pcloudRobot) {
        pcloudRobotDao.updatePcloudRobotByWxId(pcloudRobot);
    }

    public void updateRobotState(Long id, Integer state) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("state", state);
        pcloudRobotDao.updateRobotState(map);
    }

    @Override
    @ParamLog
    public PageBeanNew<PcloudRobot> getPcloudRobotList(Integer classifyId, String nickName, Integer currentPage, Integer numPerPage) {
        if (currentPage == null || currentPage < 0 || numPerPage == null || numPerPage <= 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "分页参数错误");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("classifyId", classifyId);
        map.put("nickName", nickName);
        PageBeanNew<PcloudRobot> pageBeanNew = pcloudRobotDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getPcloudRobotList");
        /*
        for (PcloudRobot pcloudRobot : pageBeanNew.getRecordList()) {
            List<PcloudRobotWelcome> robotWelcomeList = pcloudRobotWelcomeDao.getRobotWelcomeListByPcloudRobotId(pcloudRobot.getId());
            fillRobotWelcome(robotWelcomeList);
            pcloudRobot.setRobotWelcomeList(robotWelcomeList);
            if(pcloudRobot.getKeywordClassifyId() != null) {
                PcloudKeywordClassify pcloudKeywordClassify = pcloudKeywordClassifyDao.getById(pcloudRobot.getKeywordClassifyId());
                pcloudRobot.setKeywordClassifyName(pcloudKeywordClassify == null ? "" : pcloudKeywordClassify.getKeywordClassify());
            }
            if(pcloudRobot.getRobotType() != null) {
                PcloudRobotQrcode robotQrcode = pcloudRobotQrcodeDao.getByRobotType(pcloudRobot.getRobotType());
                pcloudRobot.setEntryQrcodeUrl(robotQrcode == null ? "" : robotQrcode.getQrcodeUrl());
            } else {
                pcloudRobot.setEntryQrcodeUrl("");
            }
        }
        */
        return pageBeanNew;
    }

    @Override
    @ParamLog
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdatePcloudRobotWelcome(List<PcloudRobotWelcome> robotWelcomeList) {
        if (ListUtils.isEmpty(robotWelcomeList)){
            return;
        }
        Long pcloudRobotId = robotWelcomeList.get(0).getPcloudRobotId();
        pcloudRobotWelcomeDao.deleteByPcloudRobotId(pcloudRobotId);
        pcloudRobotWelcomeDao.batchInsert(robotWelcomeList);
    }

    @Override
    @ParamLog
    public PcloudRobot getPcloudRobot(Long id) {
        PcloudRobot pcloudRobot = pcloudRobotDao.getById(id);
        if(pcloudRobot != null) {
            pcloudRobot.setSilenceDuration(pcloudRobotSilenceMapper.getSilenceDurationByRobotWxId(null, pcloudRobot.getRobotType()));
            List<PcloudRobotWelcome> robotWelcomeList = pcloudRobotWelcomeDao.getRobotWelcomeListByPcloudRobotId(pcloudRobot.getId());
            pcloudRobotSet.fillRobotWelcome(robotWelcomeList);
            pcloudRobot.setRobotWelcomeList(robotWelcomeList);
        }
        return pcloudRobot;
    }

    @Override
    public void sendWelcomeReply(String robotWxId, String userWxId, String ip) {
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            Map<String, Object> map = new HashMap<>();
            map.put("robotWxId", robotWxId);
            PcloudRobot pcloudRobot = (PcloudRobot)pcloudRobotDao.getBy(map, "getByRobotWxId");
            PcloudRobotClassify robotClassify=new PcloudRobotClassify();
            if(pcloudRobot != null) {
                if (pcloudRobot.getRobotType() != null) {
                    Integer welcomeDuration = 3;
                    robotClassify = pcloudRobotClassifyBiz.getClassifyById(pcloudRobot.getRobotType().longValue());
                    if (robotClassify != null && robotClassify.getWelcomeDuration() != null) {
                        welcomeDuration = robotClassify.getWelcomeDuration();
                    }
                    List<PcloudRobotWelcome> robotWelcomeList = pcloudRobotWelcomeDao.getRobotWelcomeListByPcloudClassifyId(pcloudRobot.getRobotType().longValue());
                    pcloudRobotSet.fillRobotWelcome(robotWelcomeList);
                    for (PcloudRobotWelcome robotWelcome : robotWelcomeList) {
                        try {
                            Thread.sleep(1000 * welcomeDuration);
                        } catch (InterruptedException e) {
                            LOGGER.error("线程睡眠出错==", e);
                        }
                        Integer replyType = robotWelcome.getReplyType();
                        if (WelcomeReplyTypeEnum.TEXT.value.equals(replyType)) {
                            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                            sendTextMessageVO.setContent(robotWelcome.getContent());
                            sendTextMessageVO.setAltId(robotWxId);
                            sendTextMessageVO.setWxGroupId(userWxId);
                            sendTextMessageVO.setIp(ip);
                            sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                            WxGroupSDK.sendTextMessage(sendTextMessageVO);
                        } else if (WelcomeReplyTypeEnum.IMAGE.value.equals(replyType)) {
                            SendPicMessageVO sendPicMessageVO = new SendPicMessageVO();
                            sendPicMessageVO.setWxGroupId(userWxId);
                            sendPicMessageVO.setAltId(robotWxId);
                            sendPicMessageVO.setPicUrl(robotWelcome.getPicUrl());
                            sendPicMessageVO.setIp(ip);
                            sendPicMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                            WxGroupSDK.sendPicMessage(sendPicMessageVO);
                        } else if (WelcomeReplyTypeEnum.RESOURCE.value.equals(replyType)) {
                            SendFileVO sendFileVO = new SendFileVO();
                            sendFileVO.setFileUrl(robotWelcome.getResourceUrl());
                            String fileName = robotWelcome.getResourceName();
                            String fileType = robotWelcome.getFileType();
                            if (fileName.contains(fileType)) {//去掉后缀
                                fileName = fileName.substring(0, fileName.indexOf(fileType) - 1);
                            }
                            sendFileVO.setFileName(fileName);
                            sendFileVO.setIp(ip);
                            sendFileVO.setAltId(robotWxId);
                            sendFileVO.setWxId(userWxId);
                            sendFileVO.setCode(SendMessageTypeEnum.SELF.getCode());
                            WxGroupSDK.sendFile(sendFileVO);
                        }
                    }
                }
                if (robotClassify != null && robotClassify.getIsOpenPushH5url() != null && robotClassify.getIsOpenPushH5url() == 1) {
                    //发送H5链接
                    String endUrl = wechatLinkPrefix + "/dialog" + "?book_group_id=" + 0 + "&wxId=" + userWxId + "&robotWxId=" + robotWxId;
                    String resultUrl = UrlUtils.getShortUrl4Own(endUrl);
                    String h5Content = "你可以通过点击" + resultUrl + "，或者输入【】内关键词唤醒我\n" + "小睿会在这里时时陪伴你";
                    SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                    sendTextMessageVO.setContent(h5Content);
                    sendTextMessageVO.setAltId(robotWxId);
                    sendTextMessageVO.setWxGroupId(userWxId);
                    sendTextMessageVO.setIp(ip);
                    sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                    WxGroupSDK.sendTextMessage(sendTextMessageVO);
                }
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void relateKeywordClassify(Long pcloudRobotId, Long keywordClassifyId) {
        PcloudRobot pcloudRobot = new PcloudRobot();
        pcloudRobot.setId(pcloudRobotId);
        pcloudRobot.setKeywordClassifyId(keywordClassifyId);
        pcloudRobotDao.update(pcloudRobot);
    }

    @Override
    public PcloudRobot getPcloudRobotByType(Integer robotType) {
        return pcloudRobotDao.getPcloudRobotByType(robotType);
    }

    @Override
    public PageBeanNew<PcloudClassifyTemplate> listClassifyTemplate(Integer classifyId, Integer currentPage, Integer numPerPage) {
        if (currentPage == null || currentPage < 0 || numPerPage == null || numPerPage <= 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "分页参数错误");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("classifyId", classifyId);
        return pcloudClassifyTemplateDao.listPageNew(new PageParam(currentPage, numPerPage), map, "listClassifyTemplate");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void openTemplate(Integer classifyId, Long templateId) {
        PcloudClassifyTemplate template = new PcloudClassifyTemplate();
        template.setClassifyId(classifyId);
        template.setIsOpen(false);
        pcloudClassifyTemplateDao.updateOpenStateByClassifyId(template);
        template.setId(templateId);
        template.setIsOpen(true);
        pcloudClassifyTemplateDao.updateOpenStateById(template);
    }

    @Override
    public void uploadTemplateAudio(PcloudClassifyTemplate classifyTemplate) {
        pcloudClassifyTemplateDao.update(classifyTemplate);
    }

    @Override
    public PcloudClassifyTemplate getTemplateByClassifyId(Integer classifyId) {
        return pcloudClassifyTemplateDao.getTemplateByClassifyId(classifyId);
    }

    @Override
    @ParamLog(value = "批量获取个人号分类")
    public Map<String, RobotClassifyDTO> mapByIds4Classify(List<String> robotIds) {
        if (ListUtils.isEmpty(robotIds)){
            return new HashMap<>();
        }
        return pcloudRobotDao.mapByIds4Classify(robotIds);
    }

    @Override
    public List<RobotClassifyDTO> getAllPcloudRobot() {
        return  pcloudRobotDao.getAllPcloudRobot();
    }

    @Override
    public PcloudRobot getPcloudRobotByWxId(String robotId) {
        return pcloudRobotDao.getByWxId(robotId);
    }

    @ParamLog("编辑全局退订信息")
    public void editPcloudTd(PcloudTdDTO pcloudTdDTO) {
        if(StringUtil.isEmpty(pcloudTdDTO.getTdKeyword()) || StringUtil.isEmpty(pcloudTdDTO.getTdGuide())) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"引导语或关键词为空！");
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("keywordName", pcloudTdDTO.getTdKeyword());
        Object obj = pcloudKeywordNameDao.getBy(paramMap, "getByKeywordName");
        if(obj != null) {
            throw new BookBizException(BookBizException.ERROR,"退订关键词与全平台关键词冲突！");
        }
        pcloudTdDao.deleteAll();
        List<PcloudTdReplyDTO> replyDTOList = pcloudTdDTO.getTdReplyDTOS();
        List<PcloudTd> pcloudTdList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(replyDTOList)) {
            for(PcloudTdReplyDTO replyDTO : replyDTOList) {
                PcloudTd pcloudTd = new PcloudTd();
                BeanUtils.copyProperties(replyDTO, pcloudTd);
                pcloudTd.setTdGuide(pcloudTdDTO.getTdGuide());
                pcloudTd.setTdKeyword(pcloudTdDTO.getTdKeyword());
                pcloudTdList.add(pcloudTd);
            }
        } else {
            PcloudTd pcloudTd = new PcloudTd();
            pcloudTd.setTdGuide(pcloudTdDTO.getTdGuide());
            pcloudTd.setTdKeyword(pcloudTdDTO.getTdKeyword());
            pcloudTdList.add(pcloudTd);
        }
        pcloudTdDao.batchInsert(pcloudTdList);
    }

    @Override
    @ParamLog("获取全局退订信息")
    public PcloudTdDTO getPcloudTdInfo() {
        List<PcloudTd> pcloudTdList = pcloudTdDao.listAll();
        PcloudTd pcloudTd = pcloudTdList.get(0);
        PcloudTdDTO pcloudTdDTO = new PcloudTdDTO();
        pcloudTdDTO.setTdGuide(pcloudTd.getTdGuide());
        pcloudTdDTO.setTdKeyword(pcloudTd.getTdKeyword());
        List<PcloudTdReplyDTO> replyDTOS = new ArrayList<>();
        for(PcloudTd td : pcloudTdList) {
            PcloudTdReplyDTO replyDTO = new PcloudTdReplyDTO();
            BeanUtils.copyProperties(td, replyDTO);
            replyDTOS.add(replyDTO);
        }
        this.fillTdReplyResource(replyDTOS);
        pcloudTdDTO.setTdReplyDTOS(replyDTOS);
        return pcloudTdDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ParamLog("全局退订回复")
    public void handlePcloudTdReply(SendTextDTO sendTextDTO) {
        String robotWxId = sendTextDTO.getWxId();
        String userWxId = sendTextDTO.getWechatUserId();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("robotWxId", robotWxId);
        paramMap.put("userWxId", userWxId);
        PcloudTdRecord pcloudTdRecord = (PcloudTdRecord)pcloudTdRecordDao.getBy(paramMap, "getByUserAndRobotWxId");
        if(pcloudTdRecord != null && pcloudTdRecord.getTdState() == 1) {
            return;
        }
        //修改退订记录
        PcloudTdRecord tdRecord = new PcloudTdRecord();
        tdRecord.setRobotWxId(robotWxId);
        tdRecord.setUserWxId(userWxId);
        tdRecord.setTdState(1);
        if(pcloudTdRecord == null) {
            pcloudTdRecordDao.insert(tdRecord);
        } else {
            pcloudTdRecordDao.updateUserTdState(tdRecord);
        }
        //发送退订回复
        List<PcloudTd> pcloudTdList = pcloudTdDao.listAll();
        List<PcloudTdReplyDTO> replyDTOS = new ArrayList<>();
        for(PcloudTd td : pcloudTdList) {
            PcloudTdReplyDTO replyDTO = new PcloudTdReplyDTO();
            BeanUtils.copyProperties(td, replyDTO);
            replyDTOS.add(replyDTO);
        }
        this.fillTdReplyResource(replyDTOS);
        this.sendTdReplyMessage(sendTextDTO.getIp(), robotWxId, userWxId, replyDTOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserTdState(String robotWxId, String userWxId, Integer tdState) {
        //修改退订记录
        PcloudTdRecord tdRecord = new PcloudTdRecord();
        tdRecord.setRobotWxId(robotWxId);
        tdRecord.setUserWxId(userWxId);
        tdRecord.setTdState(tdState);
        pcloudTdRecordDao.updateUserTdState(tdRecord);
    }

    @Override
    public Integer getUserTdState(String robotWxId, String userWxId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("robotWxId", robotWxId);
        paramMap.put("userWxId", userWxId);
        Integer tdState = (Integer) pcloudTdRecordDao.getBy(paramMap, "getUserTdState");
        return tdState == null ? 0 : tdState;
    }

    @Override
    public String getTdKeyword() {
        String tdKeyword = pcloudTdDao.getTdKeyword();
        return StringUtil.isEmpty(tdKeyword) ? "" : tdKeyword;
    }

    @Override
    public void copyRobotWelcome(String sourceRobotWxId, String targetRobotWxId) {
        PcloudRobot sourceRobot = pcloudRobotDao.getByWxId(sourceRobotWxId);
        if(sourceRobot == null) {
            throw new BookBizException(BookBizException.ERROR,"源个人号未录入！");
        }
        PcloudRobot targetRobot = pcloudRobotDao.getByWxId(targetRobotWxId);
        if(targetRobot == null) {
            throw new BookBizException(BookBizException.ERROR,"目标个人号未录入！");
        }
        targetRobot.setClassifyId(sourceRobot.getClassifyId());
        targetRobot.setKeywordClassifyId(sourceRobot.getKeywordClassifyId());
        pcloudRobotDao.update(targetRobot);
        List<PcloudRobotWelcome> sourceWelcomeList = pcloudRobotWelcomeDao.getRobotWelcomeListByPcloudRobotId(sourceRobot.getId());
        List<PcloudRobotWelcome> targetWelcomeList = new ArrayList<>();
        for(PcloudRobotWelcome sourceWelcome : sourceWelcomeList) {
            PcloudRobotWelcome targetWelcome = new PcloudRobotWelcome();
            BeanUtils.copyProperties(sourceWelcome, targetWelcome);
            targetWelcome.setPcloudRobotId(targetRobot.getId());
            targetWelcomeList.add(targetWelcome);
        }
        pcloudRobotWelcomeDao.batchInsert(targetWelcomeList);
    }

    @Override
    public void copyRobotConfiguration(String sourceRobotWxId, String targetRobotWxId) {
        //欢迎语
        copyRobotWelcome(sourceRobotWxId, targetRobotWxId);
        //全部好友设置的群发复制
        selfPushBiz.copyRobotData(sourceRobotWxId, targetRobotWxId);
        // 复制自动唤醒配置
        pcloudRobotWakeUpBiz.copyRobotWakeUp(sourceRobotWxId,targetRobotWxId);
        //复制引导语
        pcloudGuideBiz.copyGuideSetting(sourceRobotWxId, targetRobotWxId);
    }

    @Override
    public PageBeanNew<PcloudRobotResponseVO> listSelfRobotByClassify(Integer largeTemplet, Long classifyId, String keyword, Integer currentPage, Integer numPerPage) {
        List<PcloudRobotResponseVO> vos = new ArrayList<>();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("classifyId", classifyId);
        paramMap.put("keyword", keyword);
        if (!new Integer(6).equals(largeTemplet)){
            List<RobotBaseInfoDTO> baseInfoDTOList = wechatGroupConsr.getRobotInfoByTemplet(largeTemplet);
            if (ListUtils.isEmpty(baseInfoDTOList)){
                return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
            }
            List<String> wxIds = baseInfoDTOList.stream().map(RobotBaseInfoDTO::getWxId).collect(Collectors.toList());
            if (null == classifyId && StringUtil.isEmpty(keyword)){
                Integer totalCount = baseInfoDTOList.size();
                if (wxIds.size() <= numPerPage*currentPage){
                    return new PageBeanNew<>(currentPage, numPerPage, totalCount, new ArrayList<>());
                }
                if (wxIds.size() >= numPerPage*(currentPage+1)){
                    baseInfoDTOList = baseInfoDTOList.subList(numPerPage*currentPage, numPerPage*(currentPage+1));
                }else {
                    baseInfoDTOList = baseInfoDTOList.subList(numPerPage*currentPage, baseInfoDTOList.size());
                }
                wxIds = baseInfoDTOList.stream().map(RobotBaseInfoDTO::getWxId).collect(Collectors.toList());
                Map<String, RobotClassifyDTO> robotClassifyDTOMap = pcloudRobotDao.mapByIds4Classify(wxIds);
                for (RobotBaseInfoDTO dto : baseInfoDTOList){
                    PcloudRobotResponseVO pcloudRobotResponseVO = new PcloudRobotResponseVO();
                    pcloudRobotResponseVO.setWxId(dto.getWxId());
                    pcloudRobotResponseVO.setNickName(dto.getNickName());
                    RobotClassifyDTO robotClassifyDTO = robotClassifyDTOMap.get(dto.getWxId());
                    if (null != robotClassifyDTO){
                        pcloudRobotResponseVO.setClassifyId(robotClassifyDTO.getClassifyId());
                        pcloudRobotResponseVO.setClassifyName(robotClassifyDTO.getClassifyName());
                        pcloudRobotResponseVO.setUniqueNum(robotClassifyDTO.getUniqueNumber());
                    }
                    vos.add(pcloudRobotResponseVO);
                }
                return new PageBeanNew<>(currentPage, numPerPage, totalCount, vos);
            }
            paramMap.put("wxIds", wxIds);
        }
        PageBeanNew<RobotClassifyDTO> pageBeanNew = pcloudRobotDao.listPageNew(new PageParam(currentPage, numPerPage),paramMap, "listSelfRobotByClassify");
        List<RobotClassifyDTO> robotClassifyDTOS  =  pageBeanNew.getRecordList();
        if (ListUtils.isEmpty(robotClassifyDTOS)) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        for (RobotClassifyDTO e : robotClassifyDTOS) {
            PcloudRobotResponseVO pcloudRobotResponseVO = new PcloudRobotResponseVO();
            pcloudRobotResponseVO.setWxId(e.getWxId());
            pcloudRobotResponseVO.setNickName(e.getNickName());
            pcloudRobotResponseVO.setClassifyId(e.getClassifyId());
            pcloudRobotResponseVO.setClassifyName(e.getClassifyName());
            pcloudRobotResponseVO.setUniqueNum(e.getUniqueNumber());
            vos.add(pcloudRobotResponseVO);
        }
        return new PageBeanNew<>(currentPage, numPerPage, pageBeanNew.getTotalCount(), vos);
    }

    @Override
    public PageBeanNew<PcloudRobot> listNoClassifyRobot(Integer currentPage, Integer numPerPage) {
        return pcloudRobotDao.listPageNew(new PageParam(currentPage, numPerPage), new HashMap<>(), "listNoClassifyRobot");
    }

    @Override
    public void setClassifyRobot(String wxId, Integer classifyId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("wxId", wxId);
        paramMap.put("classifyId", classifyId);
        pcloudRobotDao.updateRobotType(paramMap);
    }

    @Override
    public void removeClassifyRobot(String wxId, Integer classifyId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("wxId", wxId);
        paramMap.put("classifyId", null);
        pcloudRobotDao.updateRobotType(paramMap);
    }

    @Override
    public void updateUniqueNumber(Long id, String uniqueNumber) {
        //校验编号是否重复
        PcloudRobot robot = pcloudRobotDao.getByUniqueNumber(uniqueNumber);
        if (null != robot && !robot.getId().equals(id)){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "编号重复，请重新输入");
        }
        PcloudRobot pcloudRobot = new PcloudRobot();
        pcloudRobot.setId(id);
        pcloudRobot.setUniqueNumber(uniqueNumber);
        pcloudRobotDao.update(pcloudRobot);
    }

    private void sendTdReplyMessage(String ip, String robotWxId, String userWxId, List<PcloudTdReplyDTO> replyDTOS) {
        for (PcloudTdReplyDTO tdReplyDTO : replyDTOS) {
            Integer replyType = tdReplyDTO.getReplyType();
            if(WelcomeReplyTypeEnum.TEXT.value.equals(replyType)) {
                SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                sendTextMessageVO.setContent(tdReplyDTO.getContent());
                sendTextMessageVO.setAltId(robotWxId);
                sendTextMessageVO.setWxGroupId(userWxId);
                sendTextMessageVO.setIp(ip);
                sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                WxGroupSDK.sendTextMessage(sendTextMessageVO);
            } else if(WelcomeReplyTypeEnum.IMAGE.value.equals(replyType)) {
                SendPicMessageVO sendPicMessageVO = new SendPicMessageVO();
                sendPicMessageVO.setWxGroupId(userWxId);
                sendPicMessageVO.setAltId(robotWxId);
                sendPicMessageVO.setPicUrl(tdReplyDTO.getPicUrl());
                sendPicMessageVO.setIp(ip);
                sendPicMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                WxGroupSDK.sendPicMessage(sendPicMessageVO);
            } else if(WelcomeReplyTypeEnum.RESOURCE.value.equals(replyType)) {
                String fileName = tdReplyDTO.getResourceName();
                String fileType = tdReplyDTO.getFileType();
                if (fileName.contains(fileType)) {//去掉后缀
                    fileName = fileName.substring(0, fileName.indexOf(fileType) - 1);
                }
                SendFileVO sendFileVO = new SendFileVO();
                sendFileVO.setFileUrl(tdReplyDTO.getResourceUrl());
                sendFileVO.setFileName(fileName);
                sendFileVO.setIp(ip);
                sendFileVO.setAltId(robotWxId);
                sendFileVO.setWxId(userWxId);
                sendFileVO.setCode(SendMessageTypeEnum.SELF.getCode());
                WxGroupSDK.sendFile(sendFileVO);
            }
        }
    }

    private void fillTdReplyResource(List<PcloudTdReplyDTO> tdReplyDTOS) {
        if(ListUtils.isEmpty(tdReplyDTOS)){
            return;
        }
        List<Long> resourceIds = tdReplyDTOS.stream().filter(s -> s.getResourceId() != null).map(PcloudTdReplyDTO::getResourceId).distinct().collect(Collectors.toList());
        if (!ListUtils.isEmpty(resourceIds)){
            Map<Long, ResourceDTO> resourceDTOMap = resourceConsr.mapByIds(resourceIds);
            for (PcloudTdReplyDTO replyDTO : tdReplyDTOS){
                if (replyDTO.getReplyType() != null && WelcomeReplyTypeEnum.RESOURCE.value.equals(replyDTO.getReplyType())){
                    ResourceDTO resourceDTO = resourceDTOMap.get(replyDTO.getResourceId());
                    if (resourceDTO != null){
                        replyDTO.setResourceName(resourceDTO.getResourceName());
                        replyDTO.setResourceUrl(resourceDTO.getFileUrl());
                        replyDTO.setResourceTypeCode(resourceDTO.getTypeCode());
                        replyDTO.setResourceTypeName(resourceDTO.getTypeName());
                        replyDTO.setFileType(resourceDTO.getFileType());
                        replyDTO.setFileSize(resourceDTO.getFileSize());
                    }
                }
            }
        }
    }

    @Override
    @ParamLog
    public PageBeanNew<PcloudRobot> listPcloudRobot4Service(Integer classifyId, String nickName, Integer currentPage, Integer numPerPage) {
        if (currentPage == null || currentPage < 0 || numPerPage == null || numPerPage <= 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "分页参数错误");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("classifyId", classifyId);
        map.put("nickName", nickName);
        PageBeanNew<PcloudRobot> pageBeanNew = pcloudRobotDao.listPageNew(new PageParam(currentPage, numPerPage), map, "getPcloudRobotList");
        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0,new ArrayList<>());
        }
        List<PcloudRobot> list = pageBeanNew.getRecordList();
        List<String> robotIds = list.stream().filter(s->s.getWxId()!=null).map(PcloudRobot::getWxId).distinct().collect(Collectors.toList());
        //接收消息数量
        Map<String, Integer> msgCountMap = new HashMap<>();
        if (!ListUtils.isEmpty(robotIds)){
            msgCountMap = wechatGroupConsr.mapReceiveMsgCountByIds(robotIds);
        }
        for (PcloudRobot pcloudRobot : pageBeanNew.getRecordList()) {
            if (!MapUtils.isEmpty(msgCountMap) && msgCountMap.containsKey(pcloudRobot.getWxId())){
                pcloudRobot.setReceiveMsgCount(msgCountMap.get(pcloudRobot.getWxId()));
            }
        }
        return pageBeanNew;
    }

    @Override
    public String generateLinkBySkill(Long skillId, String userWxId, String robotId){
        String content ="";
        PcloudSkill pcloudSkill = pcloudSkillBiz.getPcloudSkill(skillId);
        if (null!= pcloudSkill){
            content = pcloudSkill.getTitle();
        }
        String h5link = wechatLinkPrefix +"/dialog?wxId=" + userWxId +"&robotWxId=" + robotId +"&skillId="+ skillId;
        String linkUrl = content +"\n"+ UrlUtils.getShortUrl4Own(h5link);
        return linkUrl;
    }

    @Override
    public String generateLinkByBook(Long bookId, Long adviserId, Long channelId, String userWxId, String robotId){
        String content ="";
        BookDto bookDto = bookDao.getBaseById(bookId);
        if (null!= bookDto){
            content = bookDto.getBookName();
        }
        String h5link = wechatLinkPrefix +"/dialog/resource?bookId="+bookId+"&adviserId="+adviserId+"&channelId="+channelId+"&wxId=" + userWxId +"&robotWxId=" + robotId;
        String linkUrl = content +"\n"+ UrlUtils.getShortUrl4Own(h5link);
        return linkUrl;
    }

    @Override
    public String generateLinkbyAppProduct(String link, Long serveId, String serveType, String userWxId, String robotId){
        String title = "";
        String resultUrl="";
        String linkUrl ="";
        if (AppAndProductTypeEnum.APP.value.equalsIgnoreCase(serveType)) {
            AppDto appDto = appConsr.getBaseById(serveId);
            if (appDto != null) {
                title = appDto.getTitle();
                AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
                String endUrl = link + "&wxId=" + userWxId + "&robotWxId=" + robotId;
                linkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, endUrl);

            }
        } else if (AppAndProductTypeEnum.PRODUCT.value.equalsIgnoreCase(serveType)){
            ProductDto productDto = productConsr.getProBaseById(serveId);
            if (productDto != null) {
                title = productDto.getProductName();
                linkUrl = link + "&wxId=" + userWxId + "&robotWxId=" + robotId;
            }
        }
        resultUrl = title +"\n"+ UrlUtils.getShortUrl4Own(linkUrl);
        return resultUrl;
    }

    @Override
    public List<String> getPcloudRobotByTypes(List<Integer> classifyIds){
        return pcloudRobotDao.getPcloudRobotByTypes(classifyIds);
    }

    @Override
    public List<String> getPcloudRobotByClassify(Integer classifyId){
        return pcloudRobotDao.getPcloudRobotByClassify(classifyId);
    }
}
