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

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookKeywordWarehouseBiz;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
import com.pcloud.book.group.dao.AppTouchRecordDao;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dao.BookGroupDao;
import com.pcloud.book.group.dao.GroupQrcodeDao;
import com.pcloud.book.group.dto.BookGroupDTO;
import com.pcloud.book.group.dto.GroupClassifyQrcodeDTO;
import com.pcloud.book.group.entity.AppTouchRecord;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.enums.TouchTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.group.vo.ClassifyNameVO;
import com.pcloud.book.keywords.biz.BookKeywordBiz;
import com.pcloud.book.keywords.dao.BookKeywordDao;
import com.pcloud.book.keywords.dao.BookKeywordRecordDao;
import com.pcloud.book.keywords.dao.KeywordDao;
import com.pcloud.book.keywords.dto.KeywordDTO;
import com.pcloud.book.keywords.dto.KeywordStatisticsDTO;
import com.pcloud.book.keywords.dto.ReplyKeywordDTO;
import com.pcloud.book.keywords.dto.ServiceResourceDTO;
import com.pcloud.book.keywords.entity.BookKeyword;
import com.pcloud.book.keywords.entity.BookKeywordRecord;
import com.pcloud.book.keywords.entity.Keyword;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.keywords.vo.*;
import com.pcloud.channelcenter.base.constants.ChannelEnum;
import com.pcloud.channelcenter.qrcode.service.QrcodeSceneService;
import com.pcloud.channelcenter.qrcode.vo.MessageBookVO;
import com.pcloud.channelcenter.qrcode.vo.QrWeixinParamVO;
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.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.bean.ResponesUtils;
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.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductTypeDto;
import com.pcloud.wechatgroup.group.dto.RobotReplyDTO;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lily
 * @date 2019/4/25 10:47
 */
@Slf4j
@Component("bookKeywordBiz")
public class BookKeywordBizImpl implements BookKeywordBiz {
    @Autowired
    private KeywordDao keywordDao;
    @Autowired
    private BookGroupDao bookGroupDao;
    @Autowired
    private BookKeywordDao bookKeywordDao;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private BookKeywordRecordDao bookKeywordRecordDao;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private AppTouchRecordDao appTouchRecordDao;
    @Autowired
    private GroupQrcodeDao groupQrcodeDao;
    @Resource
    private BookKeywordWarehouseBiz bookKeywordWarehouseBiz;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private QrcodeSceneService qrcodeSceneService;

    @Override
    @ParamLog("新增关键词")
    @Transactional(rollbackFor = Exception.class)
    public void insertKeyword(SetKeywordVO setKeywordVO) {
        if(null == setKeywordVO || setKeywordVO.check()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "应用/作品信息为空");
        }
        if (setKeywordVO.getClassifyId() == null) {
            setKeywordVO.setClassifyId(0L);
        }
        //获取图书相关信息
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(setKeywordVO.getBookGroupId());
        if (bookGroupDTO == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "该社群码不存在！");
        }
        //校验关键词
        checkKeyword(setKeywordVO.getKeywords(), setKeywordVO.getClassifyId(), setKeywordVO.getBookGroupId(), null);
        Integer count = bookKeywordDao.getKeywordCount(setKeywordVO.getBookGroupId(), setKeywordVO.getClassifyId());
        if (count >= 200) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "超出关键词数量限制");
        }
        //新增关键词
        Keyword keyword = new Keyword();
        BeanUtils.copyProperties(setKeywordVO, keyword);
        keyword.setCreateUser(setKeywordVO.getUserId());
        keywordDao.insert(keyword);
        //上架商品
        List<Long> productIds = new ArrayList<>();
        if (ReplyTypeEnum.APP.value.equals(keyword.getReplyType()) && "PRODUCT".equalsIgnoreCase(keyword.getServeType())) {
            productIds.add(keyword.getServeId());
        }
        productConsr.productAutoOnShelves(bookGroupDTO.getChannelId(), productIds);
        //新增关键词与分类或者图书的关系
        //按群创建
        if (setKeywordVO.getSetType() == 1){
            BookKeyword bookKeyword = new BookKeyword();
            BeanUtils.copyProperties(setKeywordVO, bookKeyword);
            bookKeyword.setKeywordId(keyword.getId());
            bookKeyword.setBookId(bookGroupDTO.getBookId());
            bookKeyword.setChannelId(bookGroupDTO.getChannelId());
            //获取最大排序值
            Integer rank = bookKeywordDao.getMaxRank(setKeywordVO.getBookGroupId(), bookKeyword.getClassifyId());
            bookKeyword.setRank(rank + 1);
            bookKeyword.setCreateUser(setKeywordVO.getUserId());
            if (null != setKeywordVO.getAddWarehouse() && 1 == setKeywordVO.getAddWarehouse()) {
                setKeywordVO.setChannelId(bookGroupDTO.getChannelId());
                final Long warehouseId = bookKeywordWarehouseBiz.addBookKeyword(setKeywordVO);
                bookKeyword.setWarehouseId(warehouseId);
                bookKeyword.setIsWarehouse(1);
            }
            if(null == bookKeyword.getIsWarehouse()){
                bookKeyword.setIsWarehouse(0);
            }
            if(null == bookKeyword.getWarehouseId()){
                bookKeyword.setWarehouseId(0L);
            }
            bookKeyword.setIsEdit(1);
            bookKeywordDao.insert(bookKeyword);
        }
        //按书创建
        else {
            List<ClassifyNameVO> classifyNameVOS = bookGroupClassifyDao.listClassifyByRank(setKeywordVO.getBookGroupId());
            List<BookKeyword> bookKeywords = new ArrayList<>();
            //创建群的记录
            if (!ListUtils.isEmpty(classifyNameVOS)) {
                classifyNameVOS.forEach(e -> {
                    BookKeyword bookKeyword = new BookKeyword();
                    BeanUtils.copyProperties(setKeywordVO, bookKeyword);
                    bookKeyword.setKeywordId(keyword.getId());
                    bookKeyword.setBookId(bookGroupDTO.getBookId());
                    bookKeyword.setChannelId(bookGroupDTO.getChannelId());
                    bookKeyword.setClassifyId(e.getId());
                    //获取最大排序值
                    Integer rank = bookKeywordDao.getMaxRank(setKeywordVO.getBookGroupId(), bookKeyword.getClassifyId());
                    bookKeyword.setRank(rank + 1);
                    bookKeyword.setCreateUser(setKeywordVO.getUserId());
                    if (null != setKeywordVO.getAddWarehouse() && 1 == setKeywordVO.getAddWarehouse()) {
                        setKeywordVO.setChannelId(bookGroupDTO.getChannelId());
                        final Long warehouseId = bookKeywordWarehouseBiz.addBookKeyword(setKeywordVO);
                        bookKeyword.setWarehouseId(warehouseId);
                        bookKeyword.setIsWarehouse(1);
                    }
                    if (null == bookKeyword.getIsWarehouse()) {
                        bookKeyword.setIsWarehouse(0);
                    }
                    if (null == bookKeyword.getWarehouseId()) {
                        bookKeyword.setWarehouseId(0L);
                    }
                    if (0 == bookKeyword.getClassifyId()) {
                        bookKeyword.setIsEdit(1);
                    }else {
                        bookKeyword.setIsEdit(0);
                    }
                    bookKeywords.add(bookKeyword);
                });
            }
            //创建书的记录
            BookKeyword bookKeyword = new BookKeyword();
            BeanUtils.copyProperties(setKeywordVO, bookKeyword);
            bookKeyword.setKeywordId(keyword.getId());
            bookKeyword.setBookId(bookGroupDTO.getBookId());
            bookKeyword.setChannelId(bookGroupDTO.getChannelId());
            //获取最大排序值
            Integer rank = bookKeywordDao.getMaxRank(setKeywordVO.getBookGroupId(), bookKeyword.getClassifyId());
            bookKeyword.setRank(rank + 1);
            bookKeyword.setCreateUser(setKeywordVO.getUserId());
            if (null != setKeywordVO.getAddWarehouse() && 1 == setKeywordVO.getAddWarehouse()) {
                setKeywordVO.setChannelId(bookGroupDTO.getChannelId());
                final Long warehouseId = bookKeywordWarehouseBiz.addBookKeyword(setKeywordVO);
                bookKeyword.setWarehouseId(warehouseId);
                bookKeyword.setIsWarehouse(1);
            }
            if (null == bookKeyword.getIsWarehouse()) {
                bookKeyword.setIsWarehouse(0);
            }
            if (null == bookKeyword.getWarehouseId()) {
                bookKeyword.setWarehouseId(0L);
            }
            if (0 == bookKeyword.getClassifyId()) {
                bookKeyword.setIsEdit(1);
            }else {
                bookKeyword.setIsEdit(0);
            }
            bookKeywords.add(bookKeyword);
            bookKeywordDao.insert(bookKeywords);
        }

    }

    @Override
    @ParamLog("批量新增关键词")
    @Transactional(rollbackFor = {Exception.class})
    public void insertKeywords(List<SetKeywordVO> setKeywordVOs, Long partyId) {
        if (CollectionUtils.isEmpty(setKeywordVOs) || null == partyId) {
            log.info("[insertKeywords] : setKeywordVOs:{}, partyId:{}", setKeywordVOs, partyId);
            return;
        }
        for (SetKeywordVO vo : setKeywordVOs) {
            vo.setUserId(partyId);
            this.insertKeyword(vo);
        }
    }

    @ParamLog("校验关键词是否重复")
    private void checkKeyword(String keywords, Long classifyId, Long bookGroupId, Long keywordId) {
        Boolean isHaveKeyword = bookKeywordDao.checkKeyword(keywords, classifyId, bookGroupId, keywordId);
        if (isHaveKeyword) {
            throw new BookBizException(BookBizException.ERROR, "该关键词已存在！");
        }
    }

    @Override
    @ParamLog("更新关键词")
    @Transactional(rollbackFor = Exception.class)
    public void updateKeyword(UpdateKeywordVO updateKeywordVO, Long partyId) {
        checkKeyword(updateKeywordVO.getKeywords(), updateKeywordVO.getClassifyId(), updateKeywordVO.getBookGroupId(), updateKeywordVO.getKeywordId());
        //获取图书相关信息
        BookGroupDTO bookGroupDTO = bookGroupDao.getDTOById(updateKeywordVO.getBookGroupId());
        if (bookGroupDTO == null) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "该社群码不存在！");
        }
        if (null != updateKeywordVO.getAddWarehouse() && 1 == updateKeywordVO.getAddWarehouse()) {
            SetKeywordVO v = new SetKeywordVO();
            BeanUtils.copyProperties(updateKeywordVO, v);
            if (ChannelEnum.APP.value.equals(updateKeywordVO.getServeType())) {
                final AppDto baseById = appConsr.getBaseById(updateKeywordVO.getServeId());
                if(null == baseById) {
                    throw new BookBizException(BookBizException.ID_NOT_EXIST, "应用不存在");
                }
                v.setTypeCode(baseById.getTypeCode());
            }
            if (ChannelEnum.PRODUCT.value.equals(updateKeywordVO.getServeType())) {
                final ProductDto proBaseById = productConsr.getProBaseById(updateKeywordVO.getServeId());
                if(null == proBaseById) {
                    throw new BookBizException(BookBizException.ID_NOT_EXIST, "作品不存在");
                }
                v.setTypeCode(proBaseById.getProductTypeCode());
            }
            v.setUserId(partyId);
            v.setChannelId(bookGroupDTO.getChannelId());
            final Long warehouseId = this.bookKeywordWarehouseBiz.addBookKeyword(v);
            this.bookKeywordDao.updateIsWarehouse(updateKeywordVO.getBookKeywordId(), warehouseId);
        }
        Keyword keyword = new Keyword();
        BeanUtils.copyProperties(updateKeywordVO, keyword);
        keyword.setId(updateKeywordVO.getKeywordId());
        keyword.setUpdateUser(partyId);
        keywordDao.update(keyword);
        //上架商品
        List<Long> productIds = new ArrayList<>();
        if (ReplyTypeEnum.APP.value.equals(keyword.getReplyType()) && ChannelEnum.PRODUCT.value.equalsIgnoreCase(keyword.getServeType())) {
            productIds.add(keyword.getServeId());
        }
        productConsr.productAutoOnShelves(bookGroupDTO.getChannelId(), productIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ParamLog("删除关键词")
    public void deleteKeyword(DeleteKeywordVO deleteKeywordVO, Long partyId) {
        if (deleteKeywordVO == null || deleteKeywordVO.getIsEdit() == null || deleteKeywordVO.getKeywordId() == null){
            throw new BookBizException(BookBizException.ERROR,"缺少必要参数");
        }
        if (deleteKeywordVO.getClassifyId() == null){
            deleteKeywordVO.setClassifyId(0L);
        }
        if (deleteKeywordVO.getIsEdit() == 1){
            keywordDao.deleteById(deleteKeywordVO.getKeywordId(), partyId);
            bookKeywordDao.deleteById(deleteKeywordVO.getKeywordId(), partyId);
        }else {
            bookKeywordDao.deleteKeywords(deleteKeywordVO.getKeywordId(),deleteKeywordVO.getBookGroupId(),deleteKeywordVO.getClassifyId(),partyId);
        }

    }

    @Override
    @ParamLog("设置排序值")
    public void setRank(SetRankVO setRankVO, Long partyId) {
        BookKeyword bookKeyword = new BookKeyword();
        bookKeyword.setId(setRankVO.getBookKeywordId());
        bookKeyword.setRank(setRankVO.getRank());
        bookKeyword.setUpdateUser(partyId);
        bookKeywordDao.setRank(bookKeyword);
    }

    @Override
    @ParamLog("获取关键词列表")
    public PageBeanNew<ListKeywordVO> listKeywordsByClassify(ListKeywordParam listKeywordParam) {
        PageParam pageParam = new PageParam(listKeywordParam.getCurrentPage(), listKeywordParam.getNumPerPage());
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("keywords", listKeywordParam.getKeywords());
        paramMap.put("classifyId", listKeywordParam.getClassifyId());
        paramMap.put("bookGroupId", listKeywordParam.getBookGroupId());
        PageBeanNew<ListKeywordVO> keywords = bookKeywordDao.listPageNew(pageParam, paramMap, "listKeywordsByClassify");
        if (keywords == null) {
            return new PageBeanNew<>(listKeywordParam.getCurrentPage(), listKeywordParam.getNumPerPage(), new ArrayList<>());
        }
        final List<Long> appIds = Lists.newArrayList();
        final List<Long> productIds = Lists.newArrayList();
        for (ListKeywordVO vo : keywords.getRecordList()) {
            if ("APP".equalsIgnoreCase(vo.getServeType())) {
                appIds.add(vo.getServeId());
            }
            if ("PRODUCT".equalsIgnoreCase(vo.getServeType())) {
                productIds.add(vo.getServeId());
            }
            if (vo.getIsEdit() == null){
                vo.setIsEdit(1);
            }
        }
        Map<Long, AppDto> app = Maps.newHashMap();
        if(!CollectionUtils.isEmpty(appIds)) {
            app = appConsr.mapBaseByIds(appIds);
        }
        Map<Long, ProductDto> proBasesByIds = Maps.newHashMap();
        if(!CollectionUtils.isEmpty(productIds)) {
            proBasesByIds = productConsr.getProBasesByIds(productIds);
        }
        final BookGroupDTO dtoById = bookGroupDao.getDTOById(listKeywordParam.getBookGroupId());
        for (ListKeywordVO vo : keywords.getRecordList()) {
            if ("APP".equalsIgnoreCase(vo.getServeType())) {
                final AppDto appDto = app.get(vo.getServeId());
                if (null == appDto) {
                    continue;
                }
                vo.setChannelId(appDto.getChannelId());
                vo.setTypeCode(appDto.getTypeCode());
            }
            if ("PRODUCT".equalsIgnoreCase(vo.getServeType())) {
                final ProductDto productDto = proBasesByIds.get(vo.getServeId());
                if (null == productDto || null == productDto.getProductTypeDto()) {
                    continue;
                }
                vo.setChannelId(dtoById.getChannelId());
                vo.setTypeCode(productDto.getProductTypeDto().getTypeCode());
            }
        }
        return keywords;
    }

    @Override
    @ParamLog("根据关键词标识获取关键词基本信息")
    public KeywordVO getByBookKeyword(Long bookKeywordId) {
        KeywordVO keywordVO = bookKeywordDao.getByBookKeyword(bookKeywordId);
        return keywordVO;
    }

    @Override
    @ParamLog("获取5个关键词（改成10个了）")
    public List<KeywordDTO> listFiveKeyword(Long classifyId, Long bookGroupId) {
        //获取是否单独设置关键词
        List<KeywordDTO> keywords = bookKeywordDao.listFiveKeyword(classifyId, bookGroupId);
        if (ListUtils.isEmpty(keywords)) {
            keywords = bookKeywordDao.listFiveKeyword(0L, bookGroupId);
        }
        return keywords;
    }

    @Override
    @ParamLog("关键词消息回复")
    public void sendKeywordMessage(String content, String weixinGroupId, String userWxId, String robotId, String ip) {
        //简单过滤非关键词的词
        if (StringUtil.isEmpty(content) || content.length() > 20) {
            return;
        }
        //通过群id获取对应基本信息
        GroupClassifyQrcodeDTO classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(weixinGroupId);
        if (classifyQrcodeInfo == null) {
            log.info("[关键词消息回复] classifyQrcodeInfo is null");
            return;
        }
        ReplyKeywordDTO replyKeywordDTO ;
        final boolean equals = "群主，来个抽奖".equals(content);
        if (equals){
            replyKeywordDTO = keywordDao.getByKeyword("群主，来个抽奖");
        } else {
            //获取匹配关键词
            replyKeywordDTO = bookKeywordDao.getKeywordId(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId(), content);
        }
        if (replyKeywordDTO == null) {
            log.info("[关键词消息回复] replyKeywordDTO is null");
            return;
        }
        log.info("[关键词回复原始数据] ： sendKeywordMessage replyKeywordDTO ：{}, robotId:{}, weixinGroupId:{}", replyKeywordDTO, robotId, weixinGroupId);
        // 处理链接地址
        if (ReplyTypeEnum.APP.value.equals(replyKeywordDTO.getReplyType()) || ReplyTypeEnum.LINK.value.equals(replyKeywordDTO.getReplyType())) {
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(classifyQrcodeInfo.getChannelId());
            String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, replyKeywordDTO.getLinkUrl(), classifyQrcodeInfo.getBookGroupId(), classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getGroupQrcodeId());
            replyKeywordDTO.setLinkUrl(linkUrl);
        }
        String redisContent = JedisClusterUtils.getJson("BOOK:KEYWORD:" + weixinGroupId + "-" + replyKeywordDTO.getKeywordId(), String.class);
        // 同一群10秒内不回复同一关键词
        if (redisContent != null) {
            insertBookKeywordRecord(classifyQrcodeInfo, replyKeywordDTO.getKeywordId(), userWxId, weixinGroupId, false);
            log.info("[关键词消息回复] redisContent:{} insertBookKeywordRecord return", redisContent);
            return;
        } else {
            JedisClusterUtils.setJson("BOOK:KEYWORD:" + weixinGroupId + "-" + replyKeywordDTO.getKeywordId(), replyKeywordDTO.getKeywordId(), 10);
            insertBookKeywordRecord(classifyQrcodeInfo, replyKeywordDTO.getKeywordId(), userWxId, weixinGroupId, true);
        }
        //获取推送消息机器人
        // 20190704改为收发一体
        if (StringUtil.isBlank(robotId)) {
            log.info("[关键词消息回复] robotId is null content:{}, robotId:{},weixinGroupId:{}", content, robotId, weixinGroupId);
            robotId = wechatGroupConsr.getRobotIdByGroupId(weixinGroupId);
        }
        log.info("[关键词回复发送数据] ： sendKeywordMessage replyKeywordDTO ：{}, robotId:{}, weixinGroupId:{}", replyKeywordDTO, robotId, weixinGroupId);
        SendWeixinRequestTools.sendKeywordMessage(replyKeywordDTO, robotId, weixinGroupId, ip);
        //新增关键词触发记录
        addKeywordAppTouchRecord(replyKeywordDTO, weixinGroupId, classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId());
        //第一推送关键词消息埋点
        String keywordsKey = "BOOK:FIRSTKEYWORD:" + DateUtils.getShortDateStr() + "-" + weixinGroupId;
        Boolean isSend = JedisClusterUtils.getJson(keywordsKey, Boolean.class);
        if (isSend != null && isSend) {
            return;
        }
        JedisClusterUtils.setJson(keywordsKey, true);
        JedisClusterUtils.expire(keywordsKey, 86400);
        RobotReplyDTO robotReplyDTO = new RobotReplyDTO();
        robotReplyDTO.setKeyWord(content);
        robotReplyDTO.setWxGroupId(weixinGroupId);
        robotReplyDTO.setWxUserId(userWxId);
        wechatGroupConsr.addFirstRobotReplyRecord(robotReplyDTO);
    }

    /**
     * 关键词应用触发记录
     */
    private void addKeywordAppTouchRecord(ReplyKeywordDTO replyKeywordDTO, String weixinGroupId, Long classifyId, Long bookGroupId) {
        if (ReplyTypeEnum.APP.value.equals(replyKeywordDTO.getReplyType())) {
            Keyword keyword = keywordDao.getById(replyKeywordDTO.getKeywordId());
            if (keyword != null) {
                AppTouchRecord appTouchRecord = new AppTouchRecord();
                appTouchRecord.setServeId(keyword.getServeId());
                appTouchRecord.setServeType(keyword.getServeType());
                appTouchRecord.setTouchType(TouchTypeEnum.KEYWORD.value);
                appTouchRecord.setBookGroupId(bookGroupId);
                appTouchRecord.setClassifyId(classifyId);
                GroupQrcode groupQrcode = groupQrcodeDao.getGroupQrcodeByGroupId(weixinGroupId);
                if (groupQrcode != null) {
                    appTouchRecord.setQrcodeId(groupQrcode.getId());
                }
                appTouchRecord.setWeixinGroupId(weixinGroupId);
                appTouchRecordDao.insert(appTouchRecord);
            }
        }
    }

    private void insertBookKeywordRecord(GroupClassifyQrcodeDTO classifyQrcodeInfo, Long keywordId, String userWxId, String weixinGroupId, Boolean isSend) {
        BookKeywordRecord bookKeywordRecord = new BookKeywordRecord();
        BeanUtils.copyProperties(classifyQrcodeInfo, bookKeywordRecord);
        bookKeywordRecord.setKeywordId(keywordId);
        bookKeywordRecord.setUserWxId(userWxId);
        bookKeywordRecord.setWeixinGroupId(weixinGroupId);
        bookKeywordRecord.setSend(isSend);
        bookKeywordRecordDao.insert(bookKeywordRecord);
    }

    @Override
    public PageBeanNew<KeywordStatisticsDTO> getKeywordStatistics(Integer currentPage, Integer numPerPage, Long bookGroupId, String weixinGroupId) {
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> map = new HashMap<>();
        map.put("bookGroupId", bookGroupId);
        if (!StringUtil.isEmpty(weixinGroupId)) {
            GroupQrcode groupQrcode = groupQrcodeDao.getGroupQrcodeByGroupId(weixinGroupId);
            if (groupQrcode != null) {
                map.put("classifyId", groupQrcode.getClassifyId());
            }
        }
        //分页获取关键词，创建时间，名称信息
        PageBeanNew<KeywordStatisticsDTO> pageBeanNew = bookKeywordDao.listPageNew(pageParam, map, "getKeywordInfoByBookGroupId");
        List<KeywordStatisticsDTO> keywordStatisticsDTOS = pageBeanNew.getRecordList();
        if (ListUtils.isEmpty(keywordStatisticsDTOS)) {
            return pageBeanNew;
        }
        List<Long> keywordIds = keywordStatisticsDTOS.stream().filter(s -> s.getKeywordId() != null).map(KeywordStatisticsDTO::getKeywordId).collect(Collectors.toList());
        //获取关键词累计触发次数，最近一次触发时间
        List<KeywordStatisticsDTO> keywordStatisticsDTOSForOther = bookKeywordRecordDao.getKeywordStatistics(bookGroupId, weixinGroupId, keywordIds);
        Map<Long, KeywordStatisticsDTO> otherMap = new HashMap<>();
        if (!ListUtils.isEmpty(keywordStatisticsDTOSForOther)) {
            for (KeywordStatisticsDTO in : keywordStatisticsDTOSForOther) {
                otherMap.put(in.getKeywordId(), in);
            }
        }
        //获取最近7天的触发次数
        Date startDate = DateUtils.addDay(new Date(), -7);
        List<KeywordStatisticsDTO> keywordStatisticsDTOSForTime = bookKeywordRecordDao.getKeywordStatisticsByTime(bookGroupId, weixinGroupId, keywordIds, startDate);
        Map<Long, Integer> weekTouchCountMap = new HashMap<>();
        if (!ListUtils.isEmpty(keywordStatisticsDTOSForOther)) {
            for (KeywordStatisticsDTO in : keywordStatisticsDTOSForTime) {
                weekTouchCountMap.put(in.getKeywordId(), in.getWeekTouchCount());
            }
        }
        for (KeywordStatisticsDTO keywordStatisticsDTO : keywordStatisticsDTOS) {
            Long keywordId = keywordStatisticsDTO.getKeywordId();
            KeywordStatisticsDTO other = otherMap.get(keywordId);
            if (other == null) {
                //如果记录表里面没有就填充0
                keywordStatisticsDTO.setTouchCount(0);
                keywordStatisticsDTO.setWeekTouchCount(0);
                keywordStatisticsDTO.setAvgDayTouchCount(0D);
            } else {
                //计算，填充
                keywordStatisticsDTO.setTouchCount(other.getTouchCount());
                keywordStatisticsDTO.setLastTouchTime(other.getLastTouchTime());
                keywordStatisticsDTO.setWeekTouchCount(weekTouchCountMap.get(keywordId));
                Date createDate = keywordStatisticsDTO.getKeywordCreateDate();
                int days = (int) (DateUtils.getDayEnd(new Date()).getTime() - DateUtils.getDayEnd(createDate).getTime()) / 1000 / 60 / 60 / 24;
                if (days <= 0) {
                    days = 1;
                }
                Double avgTouchCount = (double) keywordStatisticsDTO.getTouchCount() / (double) days;
                keywordStatisticsDTO.setAvgDayTouchCount(new BigDecimal(avgTouchCount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            }
        }
        return pageBeanNew;
    }

    @Override
    public Integer getKeywordCount(Long bookGroupId, Long classifyId) {
        if (bookGroupId == null){
            throw new BookBizException(BookBizException.ERROR, "缺少参数bookGroupId");
        }
        return bookKeywordDao.getKeywordCount(bookGroupId, classifyId);
    }
	

    @Override
    public List<ServiceResourceDTO> getServiceByWeixinGroup(QrWeixinParam qrWeixinParam,Long classifyId, Long qrcodeId) {
        Map<String, Object> map = new HashMap<>();
        map.put("bookGroupId", qrWeixinParam.getBookGroupId());
        List<ServiceResourceDTO> serviceResourceDTOS = ResponesUtils.list(bookKeywordDao.listBy(map, "getServiceByWeixinGroup"), ServiceResourceDTO.class);
        if (ListUtils.isEmpty(serviceResourceDTOS)) {
            return new ArrayList<>();
        }
        for (ServiceResourceDTO serviceResourceDTO : serviceResourceDTOS) {
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(serviceResourceDTO.getChannelId());
            String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, serviceResourceDTO.getUrl(), qrWeixinParam.getBookGroupId(), classifyId, qrcodeId);
            serviceResourceDTO.setUrl(linkUrl);
        }
        List<Long> appIds = serviceResourceDTOS.stream().filter(s -> ("APP").equals(s.getTypeCode())).map(ServiceResourceDTO::getFromId).collect(Collectors.toList());
        Map<Long, AppDto> appMap = appConsr.getBaseByIds(appIds);
        if (!MapUtils.isEmpty(appMap)) {
            for (ServiceResourceDTO serviceResourceDTO : serviceResourceDTOS) {
                AppDto appDto = appMap.get(serviceResourceDTO.getFromId());
                if (appDto != null && serviceResourceDTO.getTypeCode().equals("APP")) {
                    serviceResourceDTO.setFromType(appDto.getTypeCode());
                    serviceResourceDTO.setTitle(appDto.getTitle());
                    serviceResourceDTO.setShortName(appDto.getTypeName());
                }
            }
        }
        List<Long> productIds = serviceResourceDTOS.stream().filter(s -> ("PRODUCT").equals(s.getTypeCode())).map(ServiceResourceDTO::getFromId).collect(Collectors.toList());
        Map<Long, ProductDto> productMap = productConsr.getProBasesByIds(productIds);
        if (!MapUtils.isEmpty(productMap)) {
            for (ServiceResourceDTO serviceResourceDTO : serviceResourceDTOS) {
                ProductDto productDto = productMap.get(serviceResourceDTO.getFromId());
                if (productDto != null && serviceResourceDTO.getTypeCode().equals("PRODUCT")) {
                    ProductTypeDto productTypeDto = productDto.getProductTypeDto();
                    if (productTypeDto != null) {
                        serviceResourceDTO.setFromType(productTypeDto.getTypeCode());
                        serviceResourceDTO.setTitle(productDto.getProductName());
                        serviceResourceDTO.setShortName(productTypeDto.getTypeName());
                    }
                }
            }
        }
        if (serviceResourceDTOS != null && !StringUtil.isEmpty(qrWeixinParam.getTypeCode()) && qrWeixinParam.getServeId() != null) {
            serviceResourceDTOS.removeIf(vo -> (qrWeixinParam.getTypeCode().equals(vo.getTypeCode()) && qrWeixinParam.getServeId().equals(vo.getFromId())));
        }
        List<ServiceResourceDTO> uniqueResources = serviceResourceDTOS.stream().collect(
                Collectors. collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getFromId() + ";" + o.getTypeCode()))), ArrayList::new)
        );
        return uniqueResources;
    }

    @Override
    public List<ServiceResourceDTO> getServiceByChannel(QrWeixinParam qrWeixinParam, Long wechatUserId) {
        QrWeixinParamVO qrWeixinParamVO = new QrWeixinParamVO();
        BeanUtils.copyProperties(qrWeixinParam, qrWeixinParamVO);
        List<MessageBookVO> messageBookVOS = ResponseHandleUtil.parseListResponse(qrcodeSceneService.getQrMessage4Book(qrWeixinParamVO, wechatUserId), MessageBookVO.class);
        return ResponesUtils.list(messageBookVOS, ServiceResourceDTO.class);
    }

    @Override
    public ReplyKeywordDTO getReplyKeyword(String content, String weixinGroupId, String wexinGroupName) {
        ReplyKeywordDTO replyKeywordDTO = null;
        if (StringUtil.isEmpty(weixinGroupId) && StringUtil.isEmpty(wexinGroupName)) {
            return new ReplyKeywordDTO();
        }
        GroupClassifyQrcodeDTO classifyQrcodeInfo = null;
        if (!StringUtil.isEmpty(weixinGroupId)) {
            //通过群id获取对应基本信息
            classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(weixinGroupId);
        }
        if (classifyQrcodeInfo == null && !StringUtil.isEmpty(wexinGroupName)) {
            classifyQrcodeInfo = bookGroupClassifyDao.getClassifyQrcodeInfoByName((wexinGroupName));
        }
        if (classifyQrcodeInfo == null) {
            log.info("[关键词消息回复] classifyQrcodeInfo is null");
            return new ReplyKeywordDTO();
        }
        final boolean equals = "群主，来个抽奖".equals(content);
        if (equals) {
            replyKeywordDTO = keywordDao.getByKeyword("群主，来个抽奖");
        } else {
            //获取匹配关键词
            replyKeywordDTO = bookKeywordDao.getKeywordId(classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getBookGroupId(), content);
        }
        if (replyKeywordDTO == null) {
            return new ReplyKeywordDTO();
        }
        // 处理链接地址
        if (ReplyTypeEnum.APP.value.equals(replyKeywordDTO.getReplyType()) || ReplyTypeEnum.LINK.value.equals(replyKeywordDTO.getReplyType())) {
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(classifyQrcodeInfo.getChannelId());
            String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, replyKeywordDTO.getLinkUrl(), classifyQrcodeInfo.getBookGroupId(), classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getGroupQrcodeId());
            replyKeywordDTO.setLinkUrl(linkUrl);
            if (!StringUtil.isEmpty(linkUrl)) {
                replyKeywordDTO.setShortLinkUrl(UrlUtils.getShortUrl4Own(linkUrl));
            }
        }
        return replyKeywordDTO;
    }

}
