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

import com.alibaba.fastjson.JSON;
import com.dcg.coolq.sdk.message.MessageBuilder;
import com.dcg.coolq.sdk.message.vos.send.PrivateMsgSendVO;
import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.erp.ErpConsr;
import com.pcloud.book.consumer.feedback.FeedbackConsr;
import com.pcloud.book.consumer.shareimage.ShareImageConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.custom.biz.CustomPlanBiz;
import com.pcloud.book.custom.dao.CustomTimeControlDao;
import com.pcloud.book.custom.dto.CustomTimeControlDTO;
import com.pcloud.book.custom.dto.PlanReadTypeDto;
import com.pcloud.book.custom.entity.CustomPlan;
import com.pcloud.book.custom.entity.CustomPlanModule;
import com.pcloud.book.custom.entity.CustomPlanModuleSuggestion;
import com.pcloud.book.custom.entity.CustomPlanRightsSetting;
import com.pcloud.book.custom.entity.CustomRightsItemDescription;
import com.pcloud.book.custom.entity.CustomRightsSettingItem;
import com.pcloud.book.custom.enums.PlanModuleTypeEnum;
import com.pcloud.book.custom.enums.PlanRightsEnum;
import com.pcloud.book.custom.enums.PlanUseStateEnum;
import com.pcloud.book.custom.mapper.CustomPlanMapper;
import com.pcloud.book.custom.mapper.CustomPlanModuleMapper;
import com.pcloud.book.custom.mapper.CustomPlanModuleSuggestionMapper;
import com.pcloud.book.custom.mapper.CustomPlanRightsSettingMapper;
import com.pcloud.book.custom.mapper.CustomRightsItemDescriptionMapper;
import com.pcloud.book.custom.mapper.CustomRightsSettingItemMapper;
import com.pcloud.book.custom.vo.AddBookNameVO;
import com.pcloud.book.custom.vo.AddCustomPlan4UserVO;
import com.pcloud.book.custom.vo.AddSuggestionListVO;
import com.pcloud.book.custom.vo.AddSuggestionVO;
import com.pcloud.book.custom.vo.CustomPlanModuleVO;
import com.pcloud.book.custom.vo.CustomPlanPaperVO;
import com.pcloud.book.custom.vo.EditCustomPlanModuleVO;
import com.pcloud.book.custom.vo.EditCustomRightsSettingVO;
import com.pcloud.book.custom.vo.ModuleSuggestionVO;
import com.pcloud.book.custom.vo.SuggestionListVO;
import com.pcloud.book.custom.vo.ToPdfVO;
import com.pcloud.book.custom.vo.UserBookServiceVO;
import com.pcloud.book.group.biz.WeixinQrcodeBiz;
import com.pcloud.book.group.tools.Kit;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.pcloudkeyword.enums.PcloudGroupRobotTypeEnum;
import com.pcloud.book.rightsSetting.dao.RightsSettingItemDao;
import com.pcloud.book.rightsSetting.entity.RightsSettingClassify;
import com.pcloud.book.skill.dao.PcloudGroupActivityDao;
import com.pcloud.book.skill.dao.PcloudResourceDao;
import com.pcloud.book.skill.dao.PcloudSkillDao;
import com.pcloud.book.skill.entity.PcloudGroupActivity;
import com.pcloud.book.skill.entity.PcloudResource;
import com.pcloud.book.skill.entity.PcloudSkill;
import com.pcloud.book.skill.enums.SkillTypeEnum;
import com.pcloud.book.timecontrol.dto.TaskDto;
import com.pcloud.book.timecontrol.entity.TimeControlTask;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskMapper;
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.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.NumberUtil;
import com.pcloud.common.utils.QrcodeUtils;
import com.pcloud.common.utils.UUIDUitl;
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.feedback.paper.dto.PaperDto;
import com.pcloud.wechatgroup.group.dto.GroupRobotDTO;
import com.pcloud.wechatgroup.group.dto.GroupUserDTO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendTextMessageVO;
import java.util.Set;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.dcg.coolq.sdk.CoolQSDK.sendPrivateMsg;

@Component
public class CustomPlanBizImpl implements CustomPlanBiz {

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

    @Autowired
    private CustomPlanMapper customPlanMapper;
    @Autowired
    private CustomPlanModuleMapper customPlanModuleMapper;
    @Value("${wechat.group.link.prefix}")
    private String wechatLinkPrefix;
    @Autowired
    private FeedbackConsr feedbackConsr;
    @Autowired
    private ShareImageConsr shareImageConsr;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private CustomPlanModuleSuggestionMapper customPlanModuleSuggestionMapper;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private WeixinQrcodeBiz weixinQrcodeBiz;
    @Autowired
    private BookBiz bookBiz;
    @Autowired
    private ErpConsr erpConsr;
    @Autowired
    private CustomTimeControlDao customTimeControlDao;
    @Autowired
    private TimeControlTaskMapper timeControlTaskMapper;
    @Autowired
    private CustomPlanRightsSettingMapper customPlanRightsSettingMapper;
    @Autowired
    private CustomRightsSettingItemMapper customRightsSettingItemMapper;
    @Autowired
    private CustomRightsItemDescriptionMapper customRightsItemDescriptionMapper;
    @Autowired
    private RightsSettingItemDao rightsSettingItemDao;
    @Autowired
    private PcloudSkillDao pcloudSkillDao;
    @Autowired
    private TimeControlTaskMapper taskMapper;
    @Autowired
    private PcloudResourceDao pcloudResourceDao;
    @Autowired
    private PcloudGroupActivityDao pcloudGroupActivityDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createCustomPlan(CustomPlan customPlan) {
        customPlanMapper.insert(customPlan);
        this.fillCustomPlanInfo(customPlan);
        return customPlan.getId();
    }

    private void fillCustomPlanInfo(CustomPlan customPlan) {
        Integer planId = customPlan.getId();
        customPlan.setPlanNumber(StringUtil.getByObj(100000 + planId));
        String h5Url = wechatLinkPrefix + "/personalCenter/madeProject?planId=" + planId + "&preview=1";
        String previewQrcodeUrl = QrcodeUtils.create(UrlUtils.getShortUrl4Own(h5Url));
        customPlan.setH5Url(h5Url);
        customPlan.setPreviewQrcodeUrl(previewQrcodeUrl);
        customPlan.setUseState(PlanUseStateEnum.NO.value);
        customPlanMapper.update(customPlan);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyCustomPlan(Integer planId) {
        CustomPlan customPlan = customPlanMapper.getById(planId);
        CustomPlan newCustomPlan = new CustomPlan();
        BeanUtils.copyProperties(customPlan, newCustomPlan);
        customPlanMapper.insert(newCustomPlan);
        this.fillCustomPlanInfo(newCustomPlan);
        //复制方案模块
        Integer copyPlanId = newCustomPlan.getId();
        List<CustomPlanModuleVO> planModuleVOList = this.getCustomPlanModule(planId);
        this.addPlanModule(copyPlanId, planModuleVOList);
        //复制权益
        EditCustomRightsSettingVO editCustomRightsSettingVO = this.getCustomRightsSettingModule(planId);
        editCustomRightsSettingVO.setPlanId(copyPlanId);
        editCustomRightsSetting(editCustomRightsSettingVO);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCustomPlan(CustomPlan customPlan) {
        customPlanMapper.update(customPlan);
    }

    @Override
    public CustomPlan getCustomPlanById(Integer planId) {
        CustomPlan customPlan = customPlanMapper.getById(planId);
        if(null!=customPlan && null!=customPlan.getBookId()){
            Map<Long, String> bookNames = erpConsr.getBookNames(Arrays.asList(customPlan.getBookId()));
            if(MapUtils.isNotEmpty(bookNames) && bookNames.containsKey(customPlan.getBookId()))
            customPlan.setBookName(bookNames.get(customPlan.getBookId()));
        }
        // 设置标题
        this.setTitle(customPlan);
        /*
        if (null!=customPlan.getCustomTimeControlId()){
            CustomTimeControlDTO control = customTimeControlDao.getCustomTimeControlById(customPlan.getCustomTimeControlId());
            if (control!=null){
                TimeControlTask timeControlTask = timeControlTaskMapper.selectByPrimaryKey(control.getTimeControlTaskId());
                if (customPlan!=null){
                    customPlan.setTaskName(timeControlTask.getTaskName());
                }
            }

        }
        */
        return customPlan;
    }

    /**
     * 设置标题
     * @param customPlan
     */
    private void setTitle(CustomPlan customPlan) {
        if(!NumberUtil.isNumber(customPlan.getPcloudSkillId())){
            return;
        }
        PcloudSkill pcloudSkill = pcloudSkillDao.getById(customPlan.getPcloudSkillId());
        if (pcloudSkill==null){
            return;
        }
        if (SkillTypeEnum.TIME_MANAGE.value.equals(pcloudSkill.getSkillType())){
            Map<Integer, TaskDto> taskDtoMap = taskMapper.mapByIds(Arrays.asList(pcloudSkill.getRelSkillId().intValue()));
            TaskDto taskDto=taskDtoMap.get(pcloudSkill.getRelSkillId().intValue());
            if (taskDto!=null){
                customPlan.setTaskName(taskDto.getTaskName());
            }
        }
        if (SkillTypeEnum.READING.value.equals(pcloudSkill.getSkillType())){
            Map<Long, PcloudGroupActivity> activityMap = pcloudGroupActivityDao.mayByIds(Arrays.asList(pcloudSkill.getRelSkillId()));
            PcloudGroupActivity groupActivity = activityMap.get(pcloudSkill.getRelSkillId());
            if (groupActivity!=null){
                customPlan.setTaskName(groupActivity.getName());
            }
        }
        if (SkillTypeEnum.RESOURCE.value.equals(pcloudSkill.getSkillType())){
            Map<Long, PcloudResource> resourceMap = pcloudResourceDao.mayByIds(Arrays.asList(pcloudSkill.getRelSkillId()));
            PcloudResource pcloudResource=resourceMap.get(pcloudSkill.getRelSkillId());
            if (pcloudResource!=null){
                customPlan.setTaskName(pcloudResource.getName());
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCustomPlanById(Integer planId) {
        customPlanMapper.deleteById(planId);
    }

    @Override
    public PageBeanNew<CustomPlan> listCustomPlanByPage(Integer currentPage, Integer numPerPage, String content, Integer useState,
                                                        Integer hasPdf, Integer robotType, Integer readType, String erpBookName) {
        List<Long> projectIds = erpConsr.getIdsByBookName(erpBookName);
        int count = customPlanMapper.getCustomPlanCount(content, useState, hasPdf,robotType, readType, projectIds);
        if(count <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        List<CustomPlan> customPlanList = customPlanMapper.listCustomPlanByPage(currentPage * numPerPage,
                numPerPage, content, useState, hasPdf, robotType, readType, projectIds);
        List<Long> bookIds = customPlanList.stream().filter(a -> null != a.getBookId()).map(a -> a.getBookId()).distinct().collect(Collectors.toList());
        Map<Long, String> bookNameMap = new HashMap<>();
        if(!ListUtils.isEmpty(bookIds)){
            bookNameMap=erpConsr.getBookNames(bookIds);
        }
        for (CustomPlan customPlan : customPlanList) {
            if(null!=customPlan.getBookId() && MapUtils.isNotEmpty(bookNameMap) && bookNameMap.containsKey(customPlan.getBookId())){
                String bookName = bookNameMap.get(customPlan.getBookId());
                customPlan.setBookName(bookName);
            }
        }
        return new PageBeanNew<>(currentPage, numPerPage, count, customPlanList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editCustomPlanModule(EditCustomPlanModuleVO editCustomPlanModuleVO) {
        Integer planId = editCustomPlanModuleVO.getPlanId();
        CustomPlan plan = customPlanMapper.getById(planId);
        if(plan == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "方案不存在！");
        }
        customPlanModuleMapper.deleteByPlanId(planId);
        this.addPlanModule(planId, editCustomPlanModuleVO.getPlanModuleVOS());
        //异步生成PDF，并更新数据库
        String htmlUrl= plan.getH5Url();
        if(!StringUtil.isEmpty(htmlUrl)) {
            ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
                try {
                    Thread.sleep(2000);

                    ToPdfVO toPdfVO = new ToPdfVO();
                    toPdfVO.setUrl(htmlUrl);
                    toPdfVO.setContainer("#App");
                    toPdfVO.setFileName(UUIDUitl.generateMixString(10));
                    LOGGER.info("=========toPdfVO========Start" + toPdfVO.toString());
                    String resultStr = Kit.post("https://puppeteer.5rs.me/generator/imgGenerator/generatorPdfByUrl", JSON.toJSONString(toPdfVO));
                    LOGGER.info("=========resultStr========End" + resultStr);
                    Map map = JSON.parseObject(resultStr, Map.class);
                    String pdfUrl = (String) ((Map) map.get("data")).get("url");
                    if (StringUtil.isEmpty(pdfUrl)){
                        pdfUrl = "https://oss.5rs.me/rays/img-generator/uPMprBxxHD.pdf";
                    }
                    LOGGER.info("=========pdfUrl========" + pdfUrl);
                    if(pdfUrl != null) {
                        CustomPlan customPlan = new CustomPlan();
                        customPlan.setId(planId);
                        customPlan.setPdfUrl(pdfUrl);
                        customPlanMapper.updatePdfUrl(customPlan);
                    }
                } catch (Exception e) {
                    LOGGER.error("转PDF失败", e);
                    String pdfUrl = "https://oss.5rs.me/rays/img-generator/uPMprBxxHD.pdf";
                    CustomPlan customPlan = new CustomPlan();
                    customPlan.setId(planId);
                    customPlan.setPdfUrl(pdfUrl);
                    customPlanMapper.updatePdfUrl(customPlan);
                }
            });
        }

    }

    private void addPlanModule(Integer planId, List<CustomPlanModuleVO> planModuleVOList) {
        for(CustomPlanModuleVO parentPlanModuleVO : planModuleVOList) {
            CustomPlanModule parentPlanModule = new CustomPlanModule();
            BeanUtils.copyProperties(parentPlanModuleVO, parentPlanModule);
            parentPlanModule.setParentId(0);
            parentPlanModule.setPlanId(planId);
            customPlanModuleMapper.insert(parentPlanModule);
            if(PlanModuleTypeEnum.GROUP.value.equals(parentPlanModuleVO.getModuleType())
                    && !CollectionUtils.isEmpty(parentPlanModuleVO.getCustomPlanModuleVOList())) {
                for(CustomPlanModuleVO planModuleVO : parentPlanModuleVO.getCustomPlanModuleVOList()) {
                    CustomPlanModule planModule4Second = new CustomPlanModule();
                    BeanUtils.copyProperties(planModuleVO, planModule4Second);
                    planModule4Second.setParentId(parentPlanModule.getId());
                    planModule4Second.setPlanId(planId);
                    customPlanModuleMapper.insert(planModule4Second);
                    if (PlanModuleTypeEnum.GROUP.value.equals(planModuleVO.getModuleType())
                            && !CollectionUtils.isEmpty(planModuleVO.getCustomPlanModuleVOList())) {
                        List<CustomPlanModule> itemList4Second = new ArrayList<>();
                        for (CustomPlanModuleVO planModuleVO4Second : planModuleVO.getCustomPlanModuleVOList()) {
                            CustomPlanModule planModule = new CustomPlanModule();
                            BeanUtils.copyProperties(planModuleVO4Second, planModule);
                            planModule.setParentId(planModule4Second.getId());
                            planModule.setPlanId(planId);
                            itemList4Second.add(planModule);
                        }
                        if (!ListUtils.isEmpty(itemList4Second)) {
                            customPlanModuleMapper.batchInsert(itemList4Second);
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<CustomPlanModuleVO> getCustomPlanModule(Integer planId) {
        List<CustomPlanModuleVO> parentPlanModuleVOList = customPlanModuleMapper.getCustomPlanModuleByPlanId(planId, 0);
        CustomPlan customPlan = customPlanMapper.getById(planId);
        for(CustomPlanModuleVO planModuleVO : parentPlanModuleVOList) {
            if(PlanModuleTypeEnum.GROUP.value.equals(planModuleVO.getModuleType())) {
                List<CustomPlanModuleVO> planModuleVOList = customPlanModuleMapper.getCustomPlanModuleByPlanId(planId, planModuleVO.getId());
                if(!CollectionUtils.isEmpty(planModuleVOList)) {
                    for (CustomPlanModuleVO customPlanModuleVO : planModuleVOList){
                        if(PlanModuleTypeEnum.GROUP.value.equals(customPlanModuleVO.getModuleType())) {
                            List<CustomPlanModuleVO> planModuleVOList4Second = customPlanModuleMapper.getCustomPlanModuleByPlanId(planId, customPlanModuleVO.getId());
                            if (!ListUtils.isEmpty(planModuleVOList4Second)){
                                customPlanModuleVO.setCustomPlanModuleVOList(planModuleVOList4Second);
                            }
                        }
                    }
                    planModuleVO.setCustomPlanModuleVOList(planModuleVOList);
                }
            }
            if(PlanModuleTypeEnum.TOP.value.equals(planModuleVO.getModuleType())){
                planModuleVO.setReadType(null != customPlan ? customPlan.getReadType() : null);
                planModuleVO.setBookName(null);
                if (null != customPlan && null != customPlan.getBookId()) {
                    BookDto bookDto = bookBiz.getBaseById(customPlan.getBookId());
                    planModuleVO.setBookName(null != bookDto ? bookDto.getBookName() : null);
                }
            }
        }
        return parentPlanModuleVOList;
    }

    @Override
    public PageBeanNew<CustomPlanPaperVO> listPlanPaperByPage(Integer currentPage, Integer numPerPage, Integer paperState, String content) {
        List<Long> paperIds = new ArrayList<>();
        if(paperState != null) {
            paperIds = feedbackConsr.getPaperIdsByState(paperState);
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("paperIds", paperIds);
        paramMap.put("content", content);
        int count = customPlanMapper.getPlanPaperCount(paramMap);
        if(count <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        paramMap.put("pageNum", currentPage * numPerPage);
        paramMap.put("numPerPage", numPerPage);
        List<CustomPlanPaperVO> planPaperVOList = customPlanMapper.listPlanPaperByPage(paramMap);
        List<Long> resultPaperIds = new ArrayList<>();
        for(CustomPlanPaperVO planPaperVO : planPaperVOList) {
            resultPaperIds.add(planPaperVO.getPaperId().longValue());
        }
        Map<Long, PaperDto> paperDtoMap = feedbackConsr.getPaperListByIds(resultPaperIds);
        for(CustomPlanPaperVO planPaperVO : planPaperVOList) {
            if(paperDtoMap.containsKey(planPaperVO.getPaperId().longValue())) {
                PaperDto paperDto = paperDtoMap.get(planPaperVO.getPaperId().longValue());
                if(paperDto != null) {
                    planPaperVO.setPaperState(paperDto.getState());
                    planPaperVO.setPaperUserCount(paperDto.getUsefulCount());
                }
            }
        }
        return new PageBeanNew<>(currentPage, numPerPage, count, planPaperVOList);
    }

    @Override
    public Map<String, Object> getShortLinkUrl(Long appId, Long productId, String linkUrl) {
        if(appId == null && productId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "作品ID或应用ID不能为空！");
        }
        if(appId != null && productId != null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "作品ID或应用ID不能同时存在！");
        }
        if(StringUtil.isEmpty(linkUrl)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "链接URL不能为空！");
        }
        Map<String, Object> resultMap = new HashMap<>();
        if(appId != null) {
            resultMap.put("appId", appId);
            AppDto appDto = appConsr.getBaseById(appId);
            if (appDto != null) {
                AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
                String shortUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, linkUrl);
                resultMap.put("shortUrl", UrlUtils.getShortUrl4Own(shortUrl));
            }

        }
        if(productId != null) {
            resultMap.put("productId", productId);
            resultMap.put("shortUrl", UrlUtils.getShortUrl4Own(linkUrl));
        }
        return resultMap;
    }

    @Override
    public PageBeanNew<SuggestionListVO> listSuggestion4Plan(Integer currentPage, Integer numPerPage, String startTime,
                                                             String endTime, String search, Integer planId,Integer userType) {
        List<SuggestionListVO> list = new ArrayList<>();
        List<String> wxIdList = null;
        if (!StringUtil.isEmpty(search)) {
            List wxIds = wechatGroupConsr.getByUserQuery(search);
            List<String> qqIds = wechatGroupConsr.getByQqUserQuery(search);
            if (!ListUtils.isEmpty(wxIds) && !ListUtils.isEmpty(qqIds)) {
                wxIds.addAll(qqIds);
                wxIdList = wxIds;
            }
            if (ListUtils.isEmpty(wxIds) && !ListUtils.isEmpty(qqIds)) {
                wxIdList = qqIds;
            }
            if (!ListUtils.isEmpty(wxIds) && ListUtils.isEmpty(qqIds)) {
                wxIdList = wxIds;
            }
            if (ListUtils.isEmpty(wxIdList)) {
                return new PageBeanNew<>(currentPage, numPerPage, list);
            }
        }
        Integer count = customPlanModuleSuggestionMapper.getSuggestionCount(startTime, endTime, wxIdList, planId,userType);
        if (count <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, list);
        }
        list = customPlanModuleSuggestionMapper.listSuggestion4Plan(currentPage * numPerPage, numPerPage, startTime, endTime, wxIdList, planId,userType);
        List<String> wxUserIds = list.stream().filter(a->a.getUserType()!=null && PcloudGroupRobotTypeEnum.WXROBOT.value.equals(a.getUserType())).map(SuggestionListVO::getWxId).distinct().collect(Collectors.toList());
        List<String> qqUserIds = list.stream().filter(a->a.getUserType()!=null && PcloudGroupRobotTypeEnum.QQROBOT.value.equals(a.getUserType())).map(SuggestionListVO::getWxId).distinct().collect(Collectors.toList());
        Map<String, GroupUserDTO> userDTOMap = wechatGroupConsr.mapWxUserInfoByWxIdList(wxUserIds);
        Map<String, GroupUserDTO> qqUserMap = wechatGroupConsr.mapQqUserInfoByWxIdList(qqUserIds);

            list.forEach(suggestionListVO -> {
                //封装用户信息
                String wxId = suggestionListVO.getWxId();
                if (MapUtils.isNotEmpty(userDTOMap) && userDTOMap.get(wxId) != null) {
                    GroupUserDTO groupUserDTO = userDTOMap.get(wxId);
                    suggestionListVO.setNickName(groupUserDTO.getNickName());
                    suggestionListVO.setHeadUrl(groupUserDTO.getHeadPic());
                    suggestionListVO.setSex(groupUserDTO.getSex());
                }
                if (MapUtils.isNotEmpty(qqUserMap) && qqUserMap.get(wxId) != null) {
                    GroupUserDTO groupUserDTO = qqUserMap.get(wxId);
                    suggestionListVO.setNickName(groupUserDTO.getNickName());
                    suggestionListVO.setHeadUrl(groupUserDTO.getHeadPic());
                    suggestionListVO.setSex(groupUserDTO.getSex());
                }

            });
        return new PageBeanNew<>(currentPage, numPerPage, count, list);
    }

    @Override
    public List<ModuleSuggestionVO> getSuggestionInfo(Integer batchId, Integer planId) {
        return customPlanModuleSuggestionMapper.getSuggestionInfo(batchId, planId);
    }

    @Override
    public Integer addSuggestion4Module(AddSuggestionVO addSuggestionVO) {
        String wxId = addSuggestionVO.getWxId();
        Integer userType = null!=addSuggestionVO.getUserType()?addSuggestionVO.getUserType():1;
        Integer planId = addSuggestionVO.getPlanId();
        int maxBatchId = customPlanModuleSuggestionMapper.getMaxBatchId();
        List<AddSuggestionListVO> suggestionList = addSuggestionVO.getSuggestionList();
        List<CustomPlanModuleSuggestion> list = new ArrayList<>();
        suggestionList.forEach(addSuggestionListVO -> {
            if (null == addSuggestionListVO.getSuggestionLevel()) {
                addSuggestionListVO.setSuggestionLevel(0);
                addSuggestionListVO.setSuggestion(null);
            }
            CustomPlanModuleSuggestion suggestion = CustomPlanModuleSuggestion.builder().wxId(wxId).planId(planId)
                    .suggestionLevel(addSuggestionListVO.getSuggestionLevel()).suggestion(addSuggestionListVO.getSuggestion())
                    .batchId(maxBatchId + 1).moduleId(addSuggestionListVO.getModuleId()).moduleType(addSuggestionListVO.getModuleType())
                    .openFeedback(addSuggestionListVO.getOpenFeedback()).userType(userType).build();
            list.add(suggestion);
        });
        customPlanModuleSuggestionMapper.batchInsert(list);
        //添加填写记录缓存
        String key = "BOOK:CUSTOMER_PLAN_SUGGESTION_RECORD:"+wxId+"-"+planId;
        JedisClusterUtils.setJson(key, wxId);
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            CustomPlan customPlan = customPlanMapper.getById(planId);
            if (!StringUtil.isEmpty(customPlan.getConfirmFeedbackReply()) && addSuggestionVO.getRobotWxId() != null) {
                //发送return消息
                String robotWxId = addSuggestionVO.getRobotWxId();
                if(1==userType) {
                    //微信发送消息
                    GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
                    String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
                    SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                    sendTextMessageVO.setContent(customPlan.getConfirmFeedbackReply());
                    sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                    sendTextMessageVO.setWxId(robotWxId);
                    sendTextMessageVO.setAltId(robotWxId);
                    sendTextMessageVO.setWxGroupId(wxId);
                    sendTextMessageVO.setIp(ip);
                    // TODO sdk.message
                    wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));
                }else{
                    //qq发送消息
                    PrivateMsgSendVO privateMsgSendVO = new PrivateMsgSendVO();
                    // 构造一个消息
                    String message = new MessageBuilder()
                            .text(customPlan.getConfirmFeedbackReply()) // 文本消息
                            .toString();
                    privateMsgSendVO.setMessage(message);
                    privateMsgSendVO.setSenderQQCode(Long.valueOf(wxId));
                    privateMsgSendVO.setReceiverQQCode(Long.valueOf(robotWxId));
                    sendPrivateMsg(privateMsgSendVO);
                }
            }
        });
        return maxBatchId + 1;
    }

    @Override
    public Integer addCustomPlan4User(AddCustomPlan4UserVO addCustomPlan4UserVO) {
        return customPlanModuleSuggestionMapper.addCustomPlan4User(addCustomPlan4UserVO);
    }

    @Override
    public Boolean getUserInputPermission(String userWxId, Integer planId) {
        Boolean canInput = true;
        String key = "BOOK:CUSTOMER_PLAN_SUGGESTION_RECORD:"+userWxId+"-"+planId;
        String value = JedisClusterUtils.getJson(key, String.class);
        if (!StringUtil.isEmpty(value)){
            canInput = false;
        }
        return canInput;
    }

    @Override
    public List<Integer> getPlanIdListByUser(String wxId){
        return customPlanModuleSuggestionMapper.getPlanIdListByUser(wxId);
    }

    @Override
    public Integer addBookNameAndServiceType(AddBookNameVO addBookNameVO) {
        return customPlanModuleSuggestionMapper.addBookNameAndServiceType(addBookNameVO);
    }

    @Override
    public AddBookNameVO getUserBookAdnServiceType(String wxId, String robotWxId, Integer type) {
        return customPlanModuleSuggestionMapper.getUserBookAdnServiceType(wxId, robotWxId, type);
    }

    @ParamLog("根据id获取用户埋点书名")
    @Override
    public UserBookServiceVO getUserBookServiceById(Long userBookServiceId) {
        return customPlanModuleSuggestionMapper.getUserBookServiceById(userBookServiceId);
    }

    @ParamLog("根据书Id获取定制计划")
    @Override
    public List<PlanReadTypeDto> getPlanReadTypesByBookId(Long bookId) {
        if (bookId==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"书id为空！");
        }
        List<PlanReadTypeDto> list=customPlanMapper.getPlanReadTypesByBookId(bookId);
        return list;
    }

    @Override
    @ParamLog(value = "批量获取定制服务",isAfterReturn = false)
    public List<CustomPlan> listByCustomPlanIds(List<Long> customPlanIds) {
        return customPlanMapper.getCustomPlanByIds(customPlanIds);
    }

    @Override
    public Map<Long, CustomPlan> getByIds(List<Long> planIds) {
        List<CustomPlan> customPlan = customPlanMapper.getCustomPlanByIds(planIds);
        if(ListUtils.isEmpty(customPlan)){
            return new HashMap<>();
        }
        return customPlan.stream().collect(Collectors.toMap(x -> x.getId().longValue(), Function.identity()));
    }

    @Override
    @ParamLog("编辑定制计划权益")
    @Transactional(rollbackFor = Exception.class)
    public void editCustomRightsSetting(EditCustomRightsSettingVO editCustomRightsSettingVO) {
        Integer planId = editCustomRightsSettingVO.getPlanId();
        CustomPlan plan = customPlanMapper.getById(planId);
        if (plan == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "方案不存在！");
        }
        customRightsItemDescriptionMapper.deleteByPlanId(planId);
        customRightsSettingItemMapper.deleteByPlanId(planId);
        customPlanRightsSettingMapper.deleteByPlanId(planId);
        List<CustomPlanRightsSetting> customPlanRightsSettings = editCustomRightsSettingVO.getCustomPlanRightsSettings();
        if (ListUtils.isEmpty(customPlanRightsSettings)) {
            return;
        }
        if (customPlanRightsSettings.size() > 5) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "列表数量最多5条");
        }
        //描述列表
        List<CustomRightsItemDescription> customRightsItemDescriptionList = new ArrayList<>();
        customPlanRightsSettings.forEach(customPlanRightsSetting -> {
            customPlanRightsSetting.setCustomPlanId(Long.valueOf(planId.toString()));
            customPlanRightsSettingMapper.insert(customPlanRightsSetting);
            List<CustomRightsSettingItem> customRightsSettingItemVOS = customPlanRightsSetting.getCustomRightsSettingItems();
            if (ListUtils.isEmpty(customRightsSettingItemVOS)) {
                return;
            }
            customRightsSettingItemVOS.forEach(customRightsSettingItem -> {
                customRightsSettingItem.setCustomRightsSettingId(customPlanRightsSetting.getId());
                customRightsSettingItemMapper.insert(customRightsSettingItem);
                List<CustomRightsItemDescription> customRightsItemDescriptions = customRightsSettingItem.getCustomRightsItemDescriptions();
                if (ListUtils.isEmpty(customRightsItemDescriptions)) {
                    return;
                }
                if (customRightsItemDescriptions.size() > 5) {
                    throw new BookBizException(BookBizException.PARAM_IS_NULL, "描述最多有5条");
                }
                customRightsItemDescriptions.forEach(customRightsItemDescription -> {
                    customRightsItemDescription.setCustomRightsSettingItemId(customRightsSettingItem.getId());
                    customRightsItemDescriptionList.add((customRightsItemDescription));
                });
            });
        });
        if (ListUtils.isEmpty(customRightsItemDescriptionList)) {
            return;
        }
        customRightsItemDescriptionMapper.batchInsert(customRightsItemDescriptionList);
    }

    @Override
    @ParamLog("编辑定制服务权益")
    public EditCustomRightsSettingVO getCustomRightsSettingModule(Integer planId) {
        CustomPlan customPlan = customPlanMapper.getById(planId);
        if (null == customPlan) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "定制方案不存在");
        }
        EditCustomRightsSettingVO editCustomRightsSettingVO = customPlanRightsSettingMapper.getCustomRightsSettingModule(planId);
        if (null == editCustomRightsSettingVO) {
            return new EditCustomRightsSettingVO();
        }
        List<CustomPlanRightsSetting> customPlanRightsSettings = editCustomRightsSettingVO.getCustomPlanRightsSettings();
        if (ListUtils.isEmpty(customPlanRightsSettings)) {
            return editCustomRightsSettingVO;
        }
        List<CustomRightsSettingItem> customRightsSettingItems = new ArrayList<>();
        for (CustomPlanRightsSetting customPlanRightsSetting : customPlanRightsSettings) {
            if (!PlanRightsEnum.TOP.value.equals(customPlanRightsSetting.getModuleType()) || !PlanRightsEnum.BOTTOM.value.equals(customPlanRightsSetting.getModuleType())) {
                List<CustomRightsSettingItem> customRightsSettingItemList = customPlanRightsSetting.getCustomRightsSettingItems();
                if (!ListUtils.isEmpty(customRightsSettingItemList)){
                    customRightsSettingItems.addAll(customRightsSettingItemList);
                }
                continue;
            }
            if (null != customPlan && null != customPlan.getBookId()) {
                Map<Long, String> bookNames = erpConsr.getBookNames(Arrays.asList(customPlan.getBookId()));
                if (MapUtils.isNotEmpty(bookNames) && bookNames.containsKey(customPlan.getBookId())) {
                    customPlanRightsSetting.setBookName(bookNames.get(customPlan.getBookId()));
                }
            }
            customPlanRightsSetting.setReadType(customPlan.getReadType());
        }
        //填充每个权益分类的图片
        fillItemPicUrl(customPlanRightsSettings, customRightsSettingItems);
        return editCustomRightsSettingVO;
    }

    //填充项目图片
    private void fillItemPicUrl(List<CustomPlanRightsSetting> customPlanRightsSettings,
            List<CustomRightsSettingItem> customRightsSettingItems) {
        if (ListUtils.isEmpty(customRightsSettingItems)){
            return;
        }
        Set<Long> rightsSettingClassifyIdSet =
                customRightsSettingItems.stream().map(e -> e.getRightsSettingClassifyId()).collect(Collectors.toSet());
        Map<Long, RightsSettingClassify> rightsSettingClassifyMap =
                rightsSettingItemDao.getRightsClassifyMap(new ArrayList<>(rightsSettingClassifyIdSet));
        if (MapUtils.isEmpty(rightsSettingClassifyMap)) {
            return;
        }
        customPlanRightsSettings.forEach(customPlanRightsSetting -> {
            if (ListUtils.isEmpty(customPlanRightsSetting.getCustomRightsSettingItems())) {
                return;
            }
            customPlanRightsSetting.getCustomRightsSettingItems().forEach(customRightsSettingItem -> {
                if (!rightsSettingClassifyMap.containsKey(customRightsSettingItem.getRightsSettingClassifyId())) {
                    return;
                }
                customRightsSettingItem
                        .setPicUrl(rightsSettingClassifyMap.get(customRightsSettingItem.getRightsSettingClassifyId()).getPicUrl());
            });
        });
    }


}
