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

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.clock.dto.PushBookClockKeywordDTO;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.reader.ReaderConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
import com.pcloud.book.group.dao.BookGroupClassifyDao;
import com.pcloud.book.group.dto.GroupClassifyQrcodeDTO;
import com.pcloud.book.group.vo.BookGroupClassifyVO;
import com.pcloud.book.group.vo.ListGroupClassifyParam;
import com.pcloud.book.weixinclock.biz.WeixinClockBiz;
import com.pcloud.book.weixinclock.check.WeixinClockCheck;
import com.pcloud.book.weixinclock.dao.WeixinClockDao;
import com.pcloud.book.weixinclock.dao.WeixinClockGroupClassifyDao;
import com.pcloud.book.weixinclock.dao.WeixinClockMemberDao;
import com.pcloud.book.weixinclock.dao.WeixinClockPrizeRecordDao;
import com.pcloud.book.weixinclock.dao.WeixinClockRewardDao;
import com.pcloud.book.weixinclock.dao.WeixinClockTopicDao;
import com.pcloud.book.weixinclock.dto.DrawRewardDto;
import com.pcloud.book.weixinclock.dto.RankDto;
import com.pcloud.book.weixinclock.dto.WeixinClockDto;
import com.pcloud.book.weixinclock.entity.WeixinClock;
import com.pcloud.book.weixinclock.entity.WeixinClockGroupClassify;
import com.pcloud.book.weixinclock.entity.WeixinClockMember;
import com.pcloud.book.weixinclock.entity.WeixinClockPrizeRecord;
import com.pcloud.book.weixinclock.entity.WeixinClockTopic;
import com.pcloud.channelcenter.base.constants.ChannelConstants;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.MQTopicProducer;
import com.pcloud.common.core.constant.ProductTypeConstant;
import com.pcloud.common.core.constant.WXKeywordOperationConstant;
import com.pcloud.common.core.dto.PromotionGiftDto;
import com.pcloud.common.core.dto.PromotionOrderDto;
import com.pcloud.common.core.enums.PromotionOrderEnum;
import com.pcloud.common.enums.AppTypeEnum;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.DateNewUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
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.labelcenter.label.service.LabelService;
import com.pcloud.readercenter.wechat.entity.WechatGroupUser;
import com.pcloud.wechatgroup.group.dto.GroupUserDTO;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 杨涛
 * @description TODO
 * @date 2019/8/14 19:12
 */
@Component("weixinClockBiz")
public class WeixinClockBizImpl implements WeixinClockBiz {

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

    @Autowired
    private WeixinClockDao weixinClockDao;
    @Autowired
    private BookGroupClassifyDao bookGroupClassifyDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private LabelService labelService;
    @Autowired
    private WeixinClockRewardDao weixinClockRewardDao;
    @Autowired
    private WeixinClockGroupClassifyDao weixinClockGroupClassifyDao;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private WeixinClockMemberDao weixinClockMemberDao;
    @Autowired
    private WeixinClockTopicDao weixinClockTopicDao;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private ReaderConsr readerConsr;
    @Autowired
    private WeixinClockCheck weixinClockCheck;
    @Autowired
    private WeixinClockPrizeRecordDao weixinClockPrizeRecordDao;
    @Autowired
    private AdviserConsr adviserConsr;

    private static final ThreadFactory NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
            .setNameFormat("weixinclock-pool-%d").build();

    private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(5, 10, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024), NAMED_THREAD_FACTORY, new ThreadPoolExecutor.CallerRunsPolicy());

    @Value("${wechat.group.link.prefix}")
    private String wechatGroupLinkPrefix;


    /**
     * 关创建微信群签到打卡
     * @param weixinClockDto
     */
    @Override
    @ParamLog("创建微信群签到打卡")
    @Transactional(rollbackFor = Exception.class)
    public Long createWeixinClock(WeixinClockDto weixinClockDto) throws BizException {
        if(null == weixinClockDto) {
            throw new BookBizException(BookBizException.ERROR,"缺少必要参数！");
        }
        weixinClockCheck.checkParam4CreateWeixinClock(weixinClockDto);
        WeixinClock weixinClock = new WeixinClock();
        BeanUtils.copyProperties(weixinClockDto, weixinClock);
        weixinClockDao.insert(weixinClock);
        Long weixinClockId = weixinClock.getWeixinClockId();
        if(!ListUtils.isEmpty(weixinClockDto.getGroupClassifyIds())) {
            List<WeixinClockGroupClassify> groupClassifyIds = Lists.newArrayList();
            weixinClockDto.getGroupClassifyIds().forEach(e -> {
                WeixinClockGroupClassify weixinClockGroupClassify = new WeixinClockGroupClassify();
                weixinClockGroupClassify.setBookGroupClassifyId(e);
                weixinClockGroupClassify.setWeixinClockId(weixinClockId);
                groupClassifyIds.add(weixinClockGroupClassify);
            });
            weixinClockGroupClassifyDao.batchInsert(groupClassifyIds);
        }
        if(!ListUtils.isEmpty(weixinClockDto.getWeixinClockRewards())) {
            weixinClockDto.getWeixinClockRewards().forEach(e -> e.setWeixinClockId(weixinClockId));
            weixinClockRewardDao.batchInsert(weixinClockDto.getWeixinClockRewards());
        }
        return weixinClockId;
    }

    @Override
    @ParamLog("获取编辑所有的分类")
    public PageBeanNew<BookGroupClassifyVO> listGroupClassify4Clock(ListGroupClassifyParam listGroupClassifyParam, Long adviserId) throws BizException {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("adviserId", adviserId);
        if (!StringUtil.isEmpty(listGroupClassifyParam.getName())) {
            paramMap.put("name", listGroupClassifyParam.getName());
        }
        paramMap.put("bookIds", listGroupClassifyParam.getBookIds());
        paramMap.put("proLabelId",listGroupClassifyParam.getProLabelId());
        paramMap.put("depLabelId",listGroupClassifyParam.getDepLabelId());
        paramMap.put("purLabelId",listGroupClassifyParam.getPurLabelId());
        PageParam pageParam = new PageParam(listGroupClassifyParam.getCurrentPage(), listGroupClassifyParam.getNumPerPage());
        PageBeanNew<BookGroupClassifyVO> pageBeanNew = bookGroupClassifyDao.listPageNew(pageParam, paramMap, "listGroupClassify4Clock");
        if (pageBeanNew == null) {
            return new PageBeanNew<>(listGroupClassifyParam.getCurrentPage(), listGroupClassifyParam.getNumPerPage(), new ArrayList<>());
        }
        //遍历填充标签
        List<BookGroupClassifyVO> bookGroupClassifyVOS = pageBeanNew.getRecordList();
        if (!ListUtils.isEmpty(bookGroupClassifyVOS)) {
            List<Long> labelIds = new ArrayList<>();
            List<Long> classifyIds = new ArrayList<>();
            for (BookGroupClassifyVO bookGroupClassifyVO : bookGroupClassifyVOS) {
                classifyIds.add(bookGroupClassifyVO.getClassifyId());
                if (bookGroupClassifyVO.getProLabelId() != null) {
                    labelIds.add(bookGroupClassifyVO.getProLabelId());
                }
                if (bookGroupClassifyVO.getPurLabelId() != null) {
                    labelIds.add(bookGroupClassifyVO.getPurLabelId());
                }
                if (bookGroupClassifyVO.getDepLabelId() != null) {
                    labelIds.add(bookGroupClassifyVO.getDepLabelId());
                }
            }
            Map<Long, Integer> activeCountMap = wechatGroupConsr.get7DayActiveUserCountByClassify(classifyIds);
            Map<Long, String> labelMap = new HashMap<>();
            if (!ListUtils.isEmpty(labelIds)) {
                labelMap = ResponseHandleUtil.parseMap(labelService.getLabelName(labelIds), Long.class, String.class);
            }
            for (BookGroupClassifyVO bookGroupClassifyVO : bookGroupClassifyVOS) {
                if (!MapUtils.isEmpty(labelMap)) {
                    Long proLabelId = bookGroupClassifyVO.getProLabelId();
                    Long purLabelId = bookGroupClassifyVO.getPurLabelId();
                    Long depLabelId = bookGroupClassifyVO.getDepLabelId();
                    if (proLabelId != null) {
                        bookGroupClassifyVO.setProLabelName(labelMap.get(proLabelId));
                    }
                    if (purLabelId != null) {
                        bookGroupClassifyVO.setPurLabelName(labelMap.get(purLabelId));
                    }
                    if (depLabelId != null) {
                        bookGroupClassifyVO.setDepLabelName(labelMap.get(depLabelId));
                    }
                }
                Integer count = activeCountMap.get(bookGroupClassifyVO.getClassifyId());
                if (count == null) {
                    bookGroupClassifyVO.setWeekActiveNumber(0);
                } else {
                    bookGroupClassifyVO.setWeekActiveNumber(count);
                }
            }
        }
        return pageBeanNew;
    }

    /**
     * 删除微信群签到打卡
     * @param weixinClockId
     * @param adviserId
     */
    @Override
    @ParamLog("删除微信群签到打卡")
    @Transactional(rollbackFor = Exception.class)
    public void deleteWeixinClock(Long weixinClockId, Long adviserId) throws BizException {
        if(null == weixinClockId){
            throw new BookBizException(BookBizException.ERROR,"缺少删除的必要参数");
        }
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("weixinClockId",weixinClockId);
        //删除对应的群分类
        weixinClockGroupClassifyDao.deleteById(weixinClockId);
        //删除对应的奖励信息
        weixinClockRewardDao.deleteById(weixinClockId);
        //删除主表的微信群签到打卡
        weixinClockDao.deleteWeixinClock(paramMap);
    }

    /**
     * 修改微信群签到打卡
     * @param weixinClockDto
     * @throws BizException
     */
    @Override
    @ParamLog("修改微信群签到打卡")
    @Transactional(rollbackFor = Exception.class)
    public void updateWeixinClock(WeixinClockDto weixinClockDto) throws BizException {
        if(null == weixinClockDto) {
            throw new BookBizException(BookBizException.ERROR,"缺少必要参数！");
        }
        if(null == weixinClockDto.getWeixinClockId()){
            throw new BookBizException(BookBizException.ERROR,"缺少修改的必要参数");
        }
        weixinClockCheck.checkParam4CreateWeixinClock(weixinClockDto);
        Long weixinClockId = weixinClockDto.getWeixinClockId();
        WeixinClock weixinClock = new WeixinClock();
        BeanUtils.copyProperties(weixinClockDto, weixinClock);
        weixinClockDao.update(weixinClock);
        //删除对应的群分类
        weixinClockGroupClassifyDao.deleteById(weixinClockId);
        //删除对应的基本信息
        weixinClockRewardDao.deleteById(weixinClockId);
        if(!ListUtils.isEmpty(weixinClockDto.getGroupClassifyIds())) {
            List<WeixinClockGroupClassify> groupClassifyIds = Lists.newArrayList();
            weixinClockDto.getGroupClassifyIds().forEach(e -> {
                WeixinClockGroupClassify weixinClockGroupClassify = new WeixinClockGroupClassify();
                weixinClockGroupClassify.setBookGroupClassifyId(e);
                weixinClockGroupClassify.setWeixinClockId(weixinClockId);
                groupClassifyIds.add(weixinClockGroupClassify);
            });
            weixinClockGroupClassifyDao.batchInsert(groupClassifyIds);
        }
        if(!ListUtils.isEmpty(weixinClockDto.getWeixinClockRewards())) {
            weixinClockDto.getWeixinClockRewards().forEach(e -> e.setWeixinClockId(weixinClockId));
            weixinClockRewardDao.batchInsert(weixinClockDto.getWeixinClockRewards());
        }
    }

    @Override
    public PageBeanNew<WeixinClockDto> listWeixinClock4Adviser(PageParam pageParam, Map<String, Object> paramMap) throws BizException {
        PageBeanNew<WeixinClockDto> clockDtoPage = weixinClockDao.listPageNew(pageParam, paramMap, "listWeixinClock4Adviser");
        if (clockDtoPage == null) {
            return new PageBeanNew<>(pageParam.getPageNum(), pageParam.getNumPerPage(), 0, new ArrayList<>());
        }
        List<Long> appIds = clockDtoPage.getRecordList().stream().map(WeixinClockDto::getClockPrizeId).collect(Collectors.toList());
        if(!ListUtils.isEmpty(appIds)) {
            Map<Long, AppDto> resultsMap = appConsr.getBaseByIds(appIds);
            for(WeixinClockDto weixinClockDto:clockDtoPage.getRecordList()){
                if(null != resultsMap && resultsMap.containsKey(weixinClockDto.getClockPrizeId())){
                    AppDto appDto = resultsMap.get(weixinClockDto.getClockPrizeId());
                    DrawRewardDto drawRewardDto = new DrawRewardDto();
                    drawRewardDto.setAppId(weixinClockDto.getClockPrizeId());
                    drawRewardDto.setChannelId(appDto.getChannelId());
                    drawRewardDto.setSquareImg(appDto.getSquareImg());
                    drawRewardDto.setTitle(appDto.getTitle());
                    drawRewardDto.setTypeCode(appDto.getTypeCode());
                    weixinClockDto.setDrawRewardDto(drawRewardDto);
                }
            }
        }
        return clockDtoPage == null ? new PageBeanNew() : clockDtoPage;
    }

    @Override
    public WeixinClockDto getWeixinClockBaseInfo(Long weixinClockId) throws BizException {
        WeixinClockDto weixinClockDto = weixinClockDao.getWeixinClockBaseInfo(weixinClockId);
        if(null != weixinClockDto && null != weixinClockDto.getClockPrizeId() && !weixinClockDto.getClockPrizeId().equals(0L)) {
            AppDto appDto = appConsr.getBaseById(weixinClockDto.getClockPrizeId());
            DrawRewardDto drawRewardDto = new DrawRewardDto();
            drawRewardDto.setAppId(weixinClockDto.getClockPrizeId());
            drawRewardDto.setChannelId(appDto.getChannelId());
            drawRewardDto.setSquareImg(appDto.getSquareImg());
            drawRewardDto.setTitle(appDto.getTitle());
            drawRewardDto.setTypeCode(appDto.getTypeCode());
            weixinClockDto.setDrawRewardDto(drawRewardDto);
        }
        return weixinClockDto == null ? new WeixinClockDto() : weixinClockDto;
    }

    @Override
    @ParamLog("获取某个微信群签到打卡的所有群分类详情")
    public PageBeanNew<BookGroupClassifyVO> listGroupClassifyDetail4Clock(Long weixinClockId, Integer currentPage, Integer numPerPage) throws BizException {
        if(null == weixinClockId) {
            throw new BookBizException(BookBizException.ERROR,"缺少微信打卡标识的必要参数！");
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("weixinClockId", weixinClockId);
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        PageBeanNew<BookGroupClassifyVO> pageBeanNew = weixinClockDao.listPageNew(pageParam, paramMap, "listGroupClassifyDetail4Clock");
        if (pageBeanNew == null) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        List<BookGroupClassifyVO> bookGroupClassifyVOS = pageBeanNew.getRecordList();
        if (!ListUtils.isEmpty(bookGroupClassifyVOS)) {
            List<Long> classifyIds = bookGroupClassifyVOS.stream().map(BookGroupClassifyVO::getClassifyId).collect(Collectors.toList());
            Map<Long, Integer> activeCountMap = wechatGroupConsr.get7DayActiveUserCountByClassify(classifyIds);
            for (BookGroupClassifyVO bookGroupClassifyVO : bookGroupClassifyVOS) {
                //最近7天活跃人数
                Integer count = activeCountMap.get(bookGroupClassifyVO.getClassifyId());
                if (count == null) {
                    bookGroupClassifyVO.setWeekActiveNumber(0);
                } else {
                    bookGroupClassifyVO.setWeekActiveNumber(count);
                }
            }
        }
        return pageBeanNew == null ? new PageBeanNew() : pageBeanNew;
    }

    @Override
    @ParamLog("校验是否为该群的打卡关键字")
    public Boolean checkWeixinClockKeyword(String content, String weixinGroupId) throws BizException {
        LOGGER.info("content----->"+content+"weixinGroupId----->"+weixinGroupId);
        //简单过滤非关键词的词
        if (StringUtil.isEmpty(content) || content.length() > 10) {
            return false;
        }
        //通过群id获取对应基本信息
        GroupClassifyQrcodeDTO classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(weixinGroupId);
        if(null == classifyQrcodeInfo){
            return false;
        }
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("bookGroupClassifyId",classifyQrcodeInfo.getClassifyId());
        String aimKeyword = weixinClockGroupClassifyDao.getKeywordByGroupClassify(paramMap);
        LOGGER.info("aimKeyword=" + aimKeyword + "content=" + content);
        return content.equalsIgnoreCase(aimKeyword);
    }

    private String getClockRankUrl(Long adviserId, Long clockPrizeId, String wxGroupId, String wxUserId){
        StringBuffer sbu=new StringBuffer();
        if(null != clockPrizeId  && !clockPrizeId.equals(0L)) {
            AppDto appDto = appConsr.getBaseById(clockPrizeId);
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
            if (null == accountSettingDto) {
                return "";
            }
            String protocol = accountSettingDto.getProtocol();
            if (StringUtils.isEmpty(protocol)) {
                protocol = ChannelConstants.HTTP;
            }
            sbu.append(protocol).append(accountSettingDto.getDomain()).append("/W")
                    .append(accountSettingDto.getAccountSettingId()).append("/clock").append("?wxGroupId=")
                    .append(wxGroupId).append("&wxUserId=").append(wxUserId);
            return UrlUtils.getShortUrl4Own(sbu.toString());
        }
        if(null != adviserId && !adviserId.equals(0L)){
            Long channelId = adviserConsr.getDefaultChannel(adviserId);
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
            if (null == accountSettingDto) {
                return "";
            }
            String protocol = accountSettingDto.getProtocol();
            if (StringUtils.isEmpty(protocol)) {
                protocol = ChannelConstants.HTTP;
            }
            sbu.append(protocol).append(accountSettingDto.getDomain()).append("/W")
                    .append(accountSettingDto.getAccountSettingId()).append("/clock").append("?wxGroupId=")
                    .append(wxGroupId).append("&wxUserId=").append(wxUserId);
            return UrlUtils.getShortUrl4Own(sbu.toString());
        }
        return "";
    }

    private String getClockRewardUrl(Long clockPrizeId){
        StringBuffer sbu=new StringBuffer();
        if(null != clockPrizeId  && !clockPrizeId.equals(0L)) {
            AppDto appDto = appConsr.getBaseById(clockPrizeId);
            AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
            if(null == accountSettingDto){
                return "";
            }
            String protocol = accountSettingDto.getProtocol();
            if (StringUtils.isEmpty(protocol)) {
                protocol = ChannelConstants.HTTP;
            }
            if(accountSettingDto.getRandom() != null) {
                sbu.append(protocol).append("app").append(accountSettingDto.getRandom()).append(".").append(accountSettingDto.getFirstDomain())
                        .append("/luck").append("/W").append(accountSettingDto.getAccountSettingId()).append("/C").append(appDto.getChannelId())
                        .append("/A").append(appDto.getAppId())
                        .append("/luckPage?isPreview=1&adviserId=").append(appDto.getCreatedUser()).append("&appType==").append(appDto.getTypeCode())
                        .append("&origin=wxGroup");
            }else{
                sbu.append(protocol).append("app.").append(accountSettingDto.getFirstDomain())
                        .append("/luck").append("/W").append(accountSettingDto.getAccountSettingId()).append("/C").append(appDto.getChannelId())
                        .append("/A").append(appDto.getAppId())
                        .append("/luckPage?isPreview=1&adviserId=").append(appDto.getCreatedUser()).append("&appType==").append(appDto.getTypeCode())
                        .append("&origin=wxGroup");
            }
            LOGGER.info("抽奖的跳转链接=====" + sbu.toString() + "================s");
            return UrlUtils.getShortUrl4Own(sbu.toString());
        }
        return "";
    }

    /**
     * 发送关键词信息
     * @param content
     * @param userWxId
     * @return
     */
    @Override
    @ParamLog("为微信群打卡关键词，发送关键词信息")
    @Transactional(rollbackFor = Exception.class)
    public Boolean sendKeywordMessage(String content, String userWxId,String wechatGroupId, String wxId, String ip) {
        LOGGER.info("接受到的关键词信息" + content);
        GroupClassifyQrcodeDTO classifyQrcodeInfo = bookGroupClassifyBiz.getClassifyQrcodeInfo(wechatGroupId);
        if(null == classifyQrcodeInfo){
            return false;
        }
        WeixinClockDto weixinClockDto = weixinClockGroupClassifyDao.getClockBaseInfoByClassify(classifyQrcodeInfo.getClassifyId());
        WeixinClockMember clockMember = weixinClockMemberDao.getByWxUserId(wechatGroupId, userWxId);
        AppDto appDto = appConsr.getBaseById(weixinClockDto.getClockPrizeId());
        Long channelId = null;
        if(null == appDto) {
            channelId = adviserConsr.getDefaultChannel(weixinClockDto.getCreateUser());
        }else {
            channelId = appDto.getChannelId();
        }
        Long wechatUserId = readerConsr.getWechatUserId(userWxId, channelId);
        GroupUserDTO groupUserDTO = wechatGroupConsr.getWxUserInfoByWxUserId(userWxId);
        groupUserDTO = null == groupUserDTO ? new GroupUserDTO() : groupUserDTO;
        Long weixinClockMemberId = clockMember == null ? null : clockMember.getWeixinClockMemberId();
        if(null == clockMember) {
            WeixinClockMember weixinClockMember = new WeixinClockMember();
            weixinClockMember.setWeixinClockId(weixinClockDto.getWeixinClockId());
            weixinClockMember.setAllClockDay(0);
            weixinClockMember.setBookGroupClassifyId(classifyQrcodeInfo.getClassifyId());
            weixinClockMember.setHeadPic(groupUserDTO.getHeadPic());
            weixinClockMember.setNickname(groupUserDTO.getNickName());
            weixinClockMember.setWxGroupId(wechatGroupId);
            weixinClockMember.setWxUserId(userWxId);
            weixinClockMember.setWechatUserId(wechatUserId);
            weixinClockMemberDao.insert(weixinClockMember);
            weixinClockMemberId = weixinClockMember.getWeixinClockMemberId();
        }
        SendTextMessageVO vo = new SendTextMessageVO();
        vo.setAltId(wxId);
        vo.setWxGroupId(wechatGroupId);
        vo.setIp(ip);
        String sendContent = "";
        String nickname = groupUserDTO.getNickName();
        if(StringUtil.isEmpty(nickname)){
            nickname = "神秘客";
        }
        WeixinClockTopic weixinTopic = weixinClockTopicDao.getTopicByIds4Today(wechatGroupId, userWxId);
        if(null == weixinTopic){
            WeixinClockTopic weixinClockTopic = new WeixinClockTopic();
            weixinClockTopic.setBookGroupClassifyId(classifyQrcodeInfo.getClassifyId());
            weixinClockTopic.setCreatedDay(new Date());
            weixinClockTopic.setWeixinClockId(weixinClockDto.getWeixinClockId());
            weixinClockTopic.setWxGroupId(wechatGroupId);
            weixinClockTopic.setWxUserId(userWxId);
            weixinClockTopic.setWeixinClockMemberId(weixinClockMemberId);
            weixinClockMemberDao.updateClockDays(wechatGroupId, userWxId, wechatUserId);
            weixinClockTopicDao.insert(weixinClockTopic);
            //发topic，增加抽奖次数
            //发送抽奖的TOPIC
            Long clockDays = weixinClockTopicDao.getClockCountByUser(wechatGroupId, userWxId);
            if(null != weixinClockDto.getClockPrizeId()) {
                if (null != wechatUserId && !wechatUserId.equals(0L)) {
                    EXECUTOR_SERVICE.execute(() -> {
                        LOGGER.info("异步校验是否满足抽奖要求,clockDays=" + clockDays);
                        PromotionOrderDto promotionOrderDto = new PromotionOrderDto();
                        List<PromotionGiftDto> promotionGiftDtoList = new ArrayList<>();
                        PromotionGiftDto promotionGiftDto = new PromotionGiftDto();
                        promotionGiftDto.setTargetClass(PromotionOrderEnum.TARGET_CLASS_APP.getCode());
                        promotionGiftDto.setTargetType(AppTypeEnum.DRAW.value);
                        promotionGiftDto.setTargetId(weixinClockDto.getClockPrizeId());
                        Integer grantNum = weixinClockRewardDao.getGrantNumFromReward(weixinClockDto.getWeixinClockId(), clockDays);
                        promotionGiftDto.setGrantNum(grantNum == null ? "0" : grantNum.toString());
                        promotionGiftDtoList.add(promotionGiftDto);
                        promotionOrderDto.setGifts(promotionGiftDtoList);
                        promotionOrderDto.setUserId(wechatUserId);
                        LOGGER.info("发送抽奖规则,参数：promotionOrderDto=" + promotionOrderDto);
                        amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MQTopicProducer.GIVE_GIFT, promotionOrderDto);
                    });
                } else {
                    WeixinClockPrizeRecord weixinClockPrizeRecord1 = weixinClockPrizeRecordDao.selectByWxUserIdAndAppId(userWxId, weixinClockDto.getClockPrizeId());
                    LOGGER.info("weixinClockPrizeRecord1=====" + weixinClockPrizeRecord1);
                    if (null == weixinClockPrizeRecord1) {
                        WeixinClockPrizeRecord weixinClockPrizeRecord2 = new WeixinClockPrizeRecord();
                        weixinClockPrizeRecord2.setClockPrizeId(weixinClockDto.getClockPrizeId());
                        weixinClockPrizeRecord2.setWxUserId(userWxId);
                        Integer grantNum = weixinClockRewardDao.getGrantNumFromReward(weixinClockDto.getWeixinClockId(), clockDays);
                        weixinClockPrizeRecord2.setPrizeTime(grantNum == null ? 0 : grantNum);
                        LOGGER.info("weixinClockPrizeRecord2------" + weixinClockPrizeRecord2);
                        weixinClockPrizeRecordDao.insert(weixinClockPrizeRecord2);
                    } else {
                        Integer grantNum = weixinClockRewardDao.getGrantNumFromReward(weixinClockDto.getWeixinClockId(), clockDays);
                        grantNum = grantNum == null ? 0 : grantNum;
                        weixinClockPrizeRecordDao.updatePrizeTime(userWxId, weixinClockDto.getClockPrizeId(), grantNum);
                    }
                }
            }
            //获取我的新排名
            Integer newOrder = weixinClockMemberDao.getMyNewOrder(wechatGroupId, userWxId);
            String clockRewardUrl = getClockRewardUrl(weixinClockDto.getClockPrizeId());
            String clockRankUrl = getClockRankUrl(weixinClockDto.getCreateUser(), weixinClockDto.getClockPrizeId(), wechatGroupId, userWxId);
            Calendar today = Calendar.getInstance();
            int month = today.get(Calendar.MONTH) + 1;
            int dayOfMonth = today.get(Calendar.DAY_OF_MONTH);
            Integer grantNum = weixinClockRewardDao.getGrantNumFromReward(weixinClockDto.getWeixinClockId(), clockDays);
            if(null == weixinClockDto.getClockPrizeId()){
                grantNum = 0;
            }
            if(null != grantNum && !grantNum.equals(0)){
                sendContent = "@" + nickname + "   "+ weixinClockDto.getClockIntroduction() + "\n" + month + "月" + dayOfMonth + "日打卡成功，你已累积打卡"
                        + clockDays + "天，排名第" +
                        newOrder + "，明天继续！" + "\n" + "\n" + "查看排行榜：" + clockRankUrl + "\n" + "点击抽奖，即可有机会获得精美礼品哦：" + clockRewardUrl;
            }else {
                sendContent = "@" + nickname + "   "+ weixinClockDto.getClockIntroduction() + "\n" + month + "月" + dayOfMonth + "日打卡成功，你已累积打卡"
                        + clockDays + "天，排名第" +
                        newOrder + "，明天继续！" + "\n" + "\n" + "查看排行榜：" + clockRankUrl;
            }
        } else {
            sendContent = "@" + nickname + " ，你今天已经打过卡了，明天再继续！";
        }
        vo.setContent(sendContent);
        LOGGER.info("微信群内加入并打卡：发送微信消息vo="+vo);
        WxGroupSDK.sendTextMessage(vo);
        return true;
    }

    /**
     * 获取某个群内的打卡排行榜
     * @param wxGroupId
     * @param wxUserId
     * @return
     */
    @Override
    @ParamLog("获取某个群内的打卡排行榜")
    public PageBeanNew<RankDto> listWeixinClockRank(String wxGroupId, String wxUserId, Integer currentPage, Integer numPerPage) {
        PageParam pageParam = new PageParam(currentPage, numPerPage);
        Map<String, Object> map = new HashMap<>();
        map.put("wxGroupId", wxGroupId);
        map.put("wxUserId", wxUserId);
        PageBeanNew<RankDto> rankDtos = weixinClockMemberDao.listPageNew(pageParam, map, "listWeixinClockRank");
        if (null == rankDtos || ListUtils.isEmpty(rankDtos.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        return rankDtos;
    }

    /**
     * 获取某个群内某个用户的信息
     * @param wxGroupId
     * @param wxUserId
     * @return
     */
    @Override
    @ParamLog("获取某个群内某个用户的信息")
    public RankDto getClockWechatUserRank(Long wechatUserId, String wxGroupId, String wxUserId) {
        RankDto rankDto = weixinClockMemberDao.getClockWechatUserRank(wechatUserId, wxGroupId);
        return null == rankDto ? new RankDto() : rankDto;
    }

    /**
     * 接收到微信用户绑定TOPIC
     * @param wechatGroupUser
     */
    @Override
    @ParamLog("微信用户绑定")
    public void receiveWxGroupUserBindTopic(WechatGroupUser wechatGroupUser) {
            List<WeixinClockPrizeRecord> weixinClockPrizeRecords = weixinClockPrizeRecordDao.getAllPrizeList(wechatGroupUser.getWxUserId());
            PromotionOrderDto promotionOrderDto = new PromotionOrderDto();
            List<PromotionGiftDto> promotionGiftDtoList = new ArrayList<>();
            for(WeixinClockPrizeRecord weixinClockPrizeRecord : weixinClockPrizeRecords){
                PromotionGiftDto promotionGiftDto = new PromotionGiftDto();
                promotionGiftDto.setTargetClass(PromotionOrderEnum.TARGET_CLASS_APP.getCode());
                promotionGiftDto.setTargetType(AppTypeEnum.DRAW.value);
                promotionGiftDto.setTargetId(weixinClockPrizeRecord.getClockPrizeId());
                Integer grantNum = weixinClockPrizeRecord.getPrizeTime();
                promotionGiftDto.setGrantNum(grantNum == null ? "0" : grantNum.toString());
                promotionGiftDtoList.add(promotionGiftDto);
            }
            promotionOrderDto.setGifts(promotionGiftDtoList);
            promotionOrderDto.setUserId(wechatGroupUser.getWechatUserId());
            LOGGER.info("发送抽奖规则,参数：promotionOrderDto=" + promotionOrderDto);
            amqpTemplate.convertAndSend(MQTopicProducer.EXCHAGE, MQTopicProducer.GIVE_GIFT, promotionOrderDto);
            weixinClockPrizeRecordDao.deleteByWxUserId(wechatGroupUser.getWxUserId());
            weixinClockMemberDao.updatMemberWechatUserId(wechatGroupUser.getWxUserId(), wechatGroupUser.getWechatUserId());
    }

}
