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

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupClassifyBiz;
import com.pcloud.book.group.biz.GroupQrcodeBiz;
import com.pcloud.book.group.dao.GroupQrcodeDao;
import com.pcloud.book.group.dto.GroupClassifyQrcodeDTO;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.reading.biz.ReadingActivityBiz;
import com.pcloud.book.reading.dto.ReadingActivityDTO;
import com.pcloud.book.riddle.biz.RiddleRecordBiz;
import com.pcloud.book.riddle.constants.RiddleConstant;
import com.pcloud.book.riddle.dao.RiddleClickRecordDao;
import com.pcloud.book.riddle.dao.RiddleCouponDao;
import com.pcloud.book.riddle.dao.RiddleDao;
import com.pcloud.book.riddle.dao.RiddleRecordDao;
import com.pcloud.book.riddle.dao.RiddleReplyDao;
import com.pcloud.book.riddle.dto.CouponClickDTO;
import com.pcloud.book.riddle.dto.GroupRedisDTO;
import com.pcloud.book.riddle.dto.GroupRiddleDTO;
import com.pcloud.book.riddle.dto.RiddleCouponDTO;
import com.pcloud.book.riddle.dto.UserRankingDTO;
import com.pcloud.book.riddle.entity.Riddle;
import com.pcloud.book.riddle.entity.RiddleClickRecord;
import com.pcloud.book.riddle.entity.RiddleCoupon;
import com.pcloud.book.riddle.entity.RiddleRecord;
import com.pcloud.book.riddle.enums.RiddleClickTypeEnum;
import com.pcloud.book.riddle.enums.RiddleRecordStatusEnum;
import com.pcloud.book.riddle.enums.RiddleReplyTypeEnum;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.quartz.entity.CallBackParam;
import com.pcloud.facade.quartz.entity.ScheduleJob;
import com.pcloud.facade.quartz.service.ScheduleService;
import com.pcloud.wechatgroup.group.dto.GroupUserDTO;
import com.pcloud.wechatgroup.message.dto.SendTextDTO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @描述：猜谜记录
 * @作者：zhuyajie
 * @创建时间：18:20 2019/7/24
 * @版本：1.0
 */
@Component("riddleRecordBiz")
public class RiddleRecordBizImpl implements RiddleRecordBiz {
    private static final Logger logger = LoggerFactory.getLogger(RiddleRecordBizImpl.class);

    @Value("${wechat.group.link.prefix}")
    private String wechatGroupLinkPrefix;
    @Autowired
    private RiddleDao riddleDao;
    @Autowired
    private RiddleRecordDao riddleRecordDao;
    @Autowired
    private RiddleReplyDao riddleReplyDao;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private GroupQrcodeBiz groupQrcodeBiz;
    @Autowired
    private GroupQrcodeDao groupQrcodeDao;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private RiddleClickRecordDao riddleClickRecordDao;
    @Autowired
    private RiddleCouponDao riddleCouponDao;
    @Autowired
    private BookGroupClassifyBiz bookGroupClassifyBiz;
    @Autowired
    private ReadingActivityBiz readingActivityBiz;

    @Override
    @ParamLog("猜谜语游戏过程")
    public void riddleProcess(SendTextDTO sendTextDTO) {
        if (null == sendTextDTO || StringUtil.isEmpty(sendTextDTO.getTextContent())) {
            return;
        }
        if (!SendMessageTypeEnum.GROUP.getCode().equals(sendTextDTO.getCode())) {//非群消息不处理
            return;
        }
        String textContent = sendTextDTO.getTextContent().trim();
        String wxGroupId = sendTextDTO.getWechatGroupId();
        String wxUserId = sendTextDTO.getWechatUserId();
        String wxId = sendTextDTO.getWxId();
        String ip = sendTextDTO.getIp();
        GroupQrcode groupQrcode = groupQrcodeDao.getGroupQrcodeByGroupId(wxGroupId);
        if (null != groupQrcode) {
            if (!groupQrcode.getRiddleOpen()) {
                ReadingActivityDTO readingActivityDTO = readingActivityBiz.getReadingActivityByWxGroupId(wxGroupId);
                if (null == readingActivityDTO){
                    logger.info("微信群=" + wxGroupId + "共读活动="+readingActivityDTO.getTheme()+"没有开启猜谜语游戏权限");
                    return;
                }else  if (null != readingActivityDTO && !readingActivityDTO.getRiddleOpen()){
                    logger.info("微信群=" + wxGroupId + "共读活动="+readingActivityDTO.getTheme()+"没有开启猜谜语游戏权限");
                    return;
                }
            }
        }else
        {
            throw new BizException(BizException.PARAM_IS_NULL.getCode(),"根据wxGroupId找不到群");
        }
        //历史记录
        RiddleRecord riddleRecord = riddleRecordDao.getLastRecordByWxGroupId(wxGroupId, null);
        //1该群猜谜语没有记录或已结束
        if (null == riddleRecord || (null != riddleRecord && ArrayUtils.contains(RiddleRecordStatusEnum.GAME_END, riddleRecord.getStatus()))) {
            //1.1关键词“猜谜语” ，游戏开启，计时
            if (textContent.equals("猜谜语")) {
                startGame(riddleRecord, wxGroupId, wxId, ip);
            }
        }
        //2猜谜语进行中
        else if (null != riddleRecord && !RiddleRecordStatusEnum.end.getCode().equals(riddleRecord.getStatus())) {
            Integer finishCount = riddleRecord.getFinishCount() == null ? 0 : riddleRecord.getFinishCount();
            Long riddleId = riddleRecord.getRiddleId();
            Riddle riddle = riddleDao.getById(riddleId);
            if (null == riddle) {
                logger.info("该条谜语不存在，riddleId+" + riddleId);
                return;
            }
            RiddleRecord insertRecord = new RiddleRecord();
            insertRecord.setRiddleId(riddleId);
            insertRecord.setWxGroupId(wxGroupId);
            insertRecord.setWxUserId(wxUserId);
            insertRecord.setFinishCount(finishCount);
            //2.1包含“结束”、“不想玩”，结束游戏
            if (textContent.contains("结束") || textContent.contains("不想玩") || textContent.contains("不玩了")) {
                endGame(insertRecord, wxGroupId, wxId, ip, riddle.getGrade(), finishCount);
                return;
            }
            //2.2中途参与,上一条答对了发送下一题,否则发送当前题目
            if (textContent.equals("猜谜语")) {
                midwayIn(riddle, riddleRecord.getCorrect(), wxGroupId, wxId, ip, wxUserId, finishCount);
                return;
            }
            //2.3不知道、提示、答案、正确答案,给提示语
            if (textContent.contains("不知道") || textContent.contains("提示") || textContent.contains("答案") || textContent.contains("正确答案")) {
                String before = "思考是件有趣的事哦，再想想吧。友情提示：可以问问其他人或者上网查询正确答案哦。";
                sendWeixinTextMessage(wxId, wxGroupId, before, ip, wxUserId);
                return;
            }
            //2.4判断答题对错
            judgeCorrcet(textContent, riddle, insertRecord, wxGroupId, wxId, ip, wxUserId, finishCount);
        }
    }

    @ParamLog("根据类型随机选取回复语")
    @Override
    public String getRandomReply(String type) {
        String reply = "";
        List<String> replyList = riddleReplyDao.getReplyByType(type);
        if (ListUtils.isEmpty(replyList)) {
            return reply;
        }
        int size = replyList.size();
        if (size == 1) {
            reply = replyList.get(0);
        } else if (size > 1) {
            Random random = new Random();
            reply = replyList.get(random.nextInt(size));
        }
        return reply;
    }

    @ParamLog("发送文本消息")
    public void sendWeixinTextMessage(String wxId, String wxGroupId, String content, String ip, String wxUserId) {
        SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
        sendTextMessageVO.setAltId(wxId);
        sendTextMessageVO.setWxGroupId(wxGroupId);
        if (!StringUtil.isEmpty(wxUserId)) {
            sendTextMessageVO.setAtId(wxUserId);
            GroupUserDTO groupUser = wechatGroupConsr.getWxUserInfoByWxUserId(wxUserId);
            if (null != groupUser && !StringUtil.isEmpty(groupUser.getNickName())) {
                content = "@" + groupUser.getNickName() + "，" + content;
            }
        }
        sendTextMessageVO.setContent(content);
        sendTextMessageVO.setIp(ip);
        logger.info("发送文本消息," + sendTextMessageVO);
        WxGroupSDK.sendTextMessage(sendTextMessageVO);
    }

    @ParamLog("发送下一题")
    public Boolean sendNextRiddle(Integer grade, Integer seq, String wxGroupId, String wxId, String ip,
                                  RiddleRecordStatusEnum statusEnum, String beforeContent, String wxUserId, Integer finishCount) {
        Riddle riddle = riddleDao.getRiddleByGradeAndSeq(grade, seq);
        if (null != riddle) {
            if (StringUtil.isEmpty(beforeContent)) {
                beforeContent = "接下来请听下一题：";
            }
            String sendText = beforeContent + riddle.getRiddleContent()+ "\n" + RiddleConstant.rule_notice;
            sendWeixinTextMessage(wxId, wxGroupId, sendText, ip, wxUserId);
            //添加记录
            RiddleRecord insertRecord = new RiddleRecord();
            insertRecord.setRiddleId(riddle.getId());
            insertRecord.setMessageContent(sendText);
            insertRecord.setWxGroupId(wxGroupId);
            insertRecord.setWxUserId(wxId);
            insertRecord.setCorrect(null);
            insertRecord.setStatus(statusEnum.getCode());
            insertRecord.setFinishCount(finishCount);
            riddleRecordDao.insert(insertRecord);
            return true;
        } else {
            logger.info("本关题目没有下一题");
            return false;
        }
    }

    @Override
    public PageBeanNew<GroupRiddleDTO> listPage(Long partyId, Integer currentPage, Integer numPerPage, String name) {
        PageBeanNew<GroupRiddleDTO> pageBeanNew = groupQrcodeBiz.listPageRiddle(partyId, currentPage, numPerPage, name);
        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        for (GroupRiddleDTO riddleDTO : pageBeanNew.getRecordList()) {
            GroupRiddleDTO participateCountDTO = riddleRecordDao.getParticipateCount(riddleDTO.getWxGroupId());
            if (null != participateCountDTO) {
                riddleDTO.setUserNum(participateCountDTO.getUserNum() == 0 ? 0 : participateCountDTO.getUserNum());
                riddleDTO.setParticipateCount(participateCountDTO.getParticipateCount() == 0 ? 0 : participateCountDTO.getParticipateCount());
            }
            RiddleRecord riddleRecord = riddleRecordDao.getLastRecordByWxGroupId(riddleDTO.getWxGroupId(), null);
            if (null != riddleRecord) {
                Riddle riddle = riddleDao.getById(riddleRecord.getRiddleId());
                riddleDTO.setGrade(riddle.getGrade());
                riddleDTO.setFinishCount(riddleRecord.getFinishCount());
                Integer correctCount = riddleRecordDao.getCorrectCountByGroup(riddleDTO.getWxGroupId(), riddleRecord.getFinishCount());
                riddleDTO.setCorrectCount(correctCount);
            }
            Integer couponUserCount = riddleClickRecordDao.getUserCountByType(riddleDTO.getWxGroupId(), RiddleClickTypeEnum.get_coupon.getCode());
            riddleDTO.setCouponUserCount(couponUserCount);
        }
        return pageBeanNew;
    }

    @Override
    public void updateRiddleOpenStatus(Long qrcodeId, Boolean status) {
        groupQrcodeDao.updateRiddleOpenStatus(qrcodeId, status);
    }

    /**
     * 开启游戏
     */
    public void startGame(RiddleRecord riddleRecord, String wxGroupId, String wxId, String ip) {
        Riddle currentRiddle = null;//要发送的题目
        Integer finishCount = 0;//通关次数
        Integer correctCount = 0;//答对题数
        if (null != riddleRecord) {
            finishCount = riddleRecord.getFinishCount() == null ? 0 : riddleRecord.getFinishCount();
            //结束取当前题
            currentRiddle = riddleDao.getById(riddleRecord.getRiddleId());
            if (RiddleRecordStatusEnum.over.getCode().equals(riddleRecord.getStatus())) {//通关结束取下一题
                Riddle nextRiddle = riddleDao.getRiddleByGradeAndSeq(currentRiddle.getGrade(), currentRiddle.getSeq());
                if (null == nextRiddle && currentRiddle.getGrade() < 3) {//从下一关第一题开始
                    nextRiddle = riddleDao.getRiddleByGradeAndSeq(currentRiddle.getGrade() + 1, 0);
                }
                currentRiddle = nextRiddle;
            }
            correctCount = riddleRecordDao.getCorrectCountByGroup(wxGroupId, finishCount);
            Integer total = riddleDao.getCount();
            if (correctCount.equals(total)) {//结束前答对所有题，通关次数+1
                currentRiddle = null;
                finishCount = finishCount + 1;
                correctCount = 0;
            }
        }
        //发送规则
        String reply = getRandomReply(RiddleReplyTypeEnum.rule.getCode());
        Integer ranking = riddleRecordDao.getGroupRanking(wxGroupId);
        reply = reply + "\n" + "目前本群总共猜对" + correctCount + "题，所有微信群中本群排名第" + ranking + "名，大家加油。";
        sendWeixinTextMessage(wxId, wxGroupId, reply, ip, null);
        //发送题目，保存该题目
        if (null != currentRiddle) {//发送上次题目
            String content = "请听题：" + currentRiddle.getRiddleContent() + "\n" + RiddleConstant.rule_notice;
            sendWeixinTextMessage(wxId, wxGroupId, content, ip, null);
            RiddleRecord insertRecord = new RiddleRecord();
            insertRecord.setRiddleId(currentRiddle.getId());
            insertRecord.setMessageContent(content);
            insertRecord.setWxGroupId(wxGroupId);
            insertRecord.setWxUserId(wxId);
            insertRecord.setCorrect(null);
            insertRecord.setStatus(RiddleRecordStatusEnum.begin.getCode());
            insertRecord.setFinishCount(finishCount);
            riddleRecordDao.insert(insertRecord);

        } else {//从第一题开始
            sendNextRiddle(1, 0, wxGroupId, wxId, ip, RiddleRecordStatusEnum.begin, "请听题：", null, finishCount);
        }
        //开始5分钟计时
        deleteJob(wxGroupId);
        addEndQuartzJob(wxGroupId, wxId, ip, wxId);
    }

    /**
     * 结束游戏
     */
    public void endGame(RiddleRecord insertRecord, String wxGroupId, String wxId, String ip, Integer grade, Integer finishCount) {
        Integer correctCount = riddleRecordDao.getCorrectCountByGroup(wxGroupId, finishCount);
        Integer ranking = riddleRecordDao.getGroupRanking(wxGroupId);
        String text = "好嘞，再见，爱你们哦。目前本群总共猜对" + correctCount + "题，所有微信群中本群排名第" + ranking + "名，大家加油。";
        //发送结束语
        sendWeixinTextMessage(wxId, wxGroupId, text, ip, null);
        //保存结束记录
        insertRecord.setMessageContent(text);
        insertRecord.setStatus(RiddleRecordStatusEnum.end.getCode());
        insertRecord.setCorrect(null);
        riddleRecordDao.insert(insertRecord);
        deleteJob(wxGroupId);
    }

    /**
     * 中途进入
     */
    public void midwayIn(Riddle riddle, Boolean correct, String wxGroupId, String wxId, String ip, String wxUserId, Integer finishCount) {
        String beforeContent = getRandomReply(RiddleReplyTypeEnum.midway_in.getCode());
        if (null != correct && correct) {
            Boolean sendNext = sendNextRiddle(riddle.getGrade(), riddle.getSeq(), wxGroupId, wxId, ip, RiddleRecordStatusEnum.underway, beforeContent, wxUserId, finishCount);
            if (!sendNext) {//本关没有下一题
                if (riddle.getGrade() < 3) {//从下一关第一题开始
                    sendNextRiddle(riddle.getGrade() + 1, 0, wxGroupId, wxId, ip, RiddleRecordStatusEnum.underway, beforeContent, wxUserId, finishCount);
                } else {//3关都答完，从头开始
                    sendNextRiddle(1, 0, wxGroupId, wxId, ip, RiddleRecordStatusEnum.underway, beforeContent, wxUserId, finishCount + 1);
                }
            }
        } else {//发送当前题
            String content = beforeContent + riddle.getRiddleContent() + "\n" + RiddleConstant.rule_notice;
            sendWeixinTextMessage(wxId, wxGroupId, content, ip, wxUserId);
        }
        deleteJob(wxGroupId);
        addEndQuartzJob(wxGroupId, wxId, ip, wxId);
    }

    /**
     * 判断答题对错
     */
    public void judgeCorrcet(String textContent, Riddle riddle, RiddleRecord insertRecord, String wxGroupId, String wxId, String ip, String wxUserId, Integer finishCount) {
        if (StringUtil.isEmpty(textContent)) {
            logger.error("回复内容为空" + wxGroupId + "wxUserId" + wxUserId);
            return;
        }
        if (textContent.equals(riddle.getAnswer()) || textContent.equals(riddle.getOtherAnswer())) {//答对

            //保存答题记录
            insertRecord.setMessageContent(textContent);
            insertRecord.setCorrect(true);
            insertRecord.setStatus(RiddleRecordStatusEnum.underway.getCode());
            riddleRecordDao.insert(insertRecord);
            //游戏开始的记录
            RiddleRecord riddleRecord = riddleRecordDao.getLastRecordByWxGroupId(wxGroupId, RiddleRecordStatusEnum.begin.getCode());
            Integer correctCount = riddleRecordDao.getCorrectCountByTime(wxGroupId, riddleRecord.getCreateTime());
            //连续答对5题发送成绩单及优惠券并结束游戏
            if (correctCount != 0 && correctCount % 5 == 0) {
                Integer count = riddleRecordDao.getCorrectCountByGroup(wxGroupId, finishCount);
                sendResult(wxId, wxGroupId, ip, count, insertRecord, riddleRecord.getCreateTime(), wxUserId);
                sendCouponLink(wxId, wxGroupId, ip);
            } else {
                //发送下一题
                String correctContent = getRandomReply(RiddleReplyTypeEnum.correct.getCode());
                Boolean sendNext = sendNextRiddle(riddle.getGrade(), riddle.getSeq(), wxGroupId, wxId, ip, RiddleRecordStatusEnum.underway, correctContent, wxUserId, finishCount);
                if (!sendNext) {//本关没有下一题
                    if (riddle.getGrade() < 3) {//从下一关第一题开始
                        sendNextRiddle(riddle.getGrade() + 1, 0, wxGroupId, wxId, ip, RiddleRecordStatusEnum.underway, correctContent, wxUserId, finishCount);
                    } else {//3关都答完
                        String content = getRandomReply(RiddleReplyTypeEnum.finish_end.getCode()) + "\n\n回复关键词“猜谜语”，可重新开始游戏。";
                        sendWeixinTextMessage(wxId, wxGroupId, content, ip, wxUserId);
                        sendCouponLink(wxId, wxGroupId, ip);
                        //结束游戏
                        RiddleRecord insert = new RiddleRecord();
                        BeanUtils.copyProperties(insertRecord, insert);
                        insert.setMessageContent(content);
                        insert.setStatus(RiddleRecordStatusEnum.over.getCode());
                        insert.setCorrect(null);
                        insert.setWxUserId(wxId);
                        riddleRecordDao.insert(insert);
                    }
                }
                deleteJob(wxGroupId);
                addEndQuartzJob(wxGroupId, wxId, ip, wxUserId);
            }

        } else if (riddle.getAnswer().contains(textContent) || textContent.contains(riddle.getAnswer())//部分答对
                || (!StringUtil.isEmpty(riddle.getOtherAnswer()) && textContent.contains(riddle.getOtherAnswer()))) {
            //保存答题记录
            insertRecord.setMessageContent(textContent);
            insertRecord.setCorrect(false);
            insertRecord.setStatus(RiddleRecordStatusEnum.underway.getCode());
            riddleRecordDao.insert(insertRecord);
            //发送部分答对文案
            String beforeContent = getRandomReply(RiddleReplyTypeEnum.partly_correct.getCode());
            beforeContent = beforeContent + "谜底是" + riddle.getAnswer().length() + "个字哦。";
            sendWeixinTextMessage(wxId, wxGroupId, beforeContent, ip, null);

        } else {//答错
            //保存答题记录
            insertRecord.setMessageContent(textContent);
            insertRecord.setCorrect(false);
            insertRecord.setStatus(RiddleRecordStatusEnum.underway.getCode());
            riddleRecordDao.insert(insertRecord);
          /*  GroupRedisDTO dto = new GroupRedisDTO();
            dto.setIp(ip);
            dto.setWxId(wxId);
            dto.setWxGroupId(wxGroupId);
            this.timeSchedule(dto);*/
        }
    }

    /**
     * 自动结束
     */
    public void autoEnd(String wxGroupId, String wxId, String ip, String wxUserId) {
        RiddleRecord riddleRecord = riddleRecordDao.getLastRecordByWxGroupId(wxGroupId, null);
        if (null == riddleRecord) {
            logger.info("微信群=" + wxGroupId + "没有猜谜语游戏记录");
            return;
        }
        Long riddleId = riddleRecord.getRiddleId();
        Riddle riddle = riddleDao.getById(riddleId);
        if (null == riddle) {
            logger.info("谜语=" + riddleId + "不存在");
            return;
        }
        Integer correctCount = riddleRecordDao.getCorrectCountByGroup(wxGroupId, riddleRecord.getFinishCount());
        Integer ranking = riddleRecordDao.getGroupRanking(wxGroupId);
        String reply = getRandomReply(RiddleReplyTypeEnum.no_reply_end.getCode());
        String text = reply + "目前本群总共猜对" + correctCount + "题，所有微信群中本群排名第" + ranking + "名，大家加油。";
        if (!text.contains("关键词")) {
            text = text + "想玩记得回复关键词“猜谜语”就可以召唤我啦。";
        }
        //发送结束语
        sendWeixinTextMessage(wxId, wxGroupId, text, ip, null);
        //保存结束记录
        RiddleRecord record = new RiddleRecord();
        record.setRiddleId(riddleId);
        record.setWxGroupId(wxGroupId);
        record.setWxUserId(wxUserId);
        record.setMessageContent(text);
        record.setStatus(RiddleRecordStatusEnum.end.getCode());
        record.setCorrect(null);
        record.setFinishCount(riddleRecord.getFinishCount());
        riddleRecordDao.insert(record);
    }


    /**
     * 添加定时任务-5分钟游戏自动结束
     */
    private void addEndQuartzJob(String wxGroupId, String wxId, String ip, String wxUserId) {
        ScheduleJob scheduleJob = new ScheduleJob();
        CallBackParam callBackParam = new CallBackParam();
        Map<String, Object> map = new HashMap<>();
        map.put("wxGroupId", wxGroupId);
        map.put("wxId", wxId);
        map.put("ip", ip);
        map.put("wxUserId", wxUserId);

        scheduleJob.setJobGroup(RiddleConstant.JOB_GROUP_RIDDLE);
        scheduleJob.setJobName(RiddleConstant.JOB_NAME_RIDDLE_EXPIRE + wxGroupId);
        scheduleJob.setStartTime(5);
        scheduleJob.setStartTimeFormat("mm");
        scheduleJob.setRepeatCount(0);
        scheduleJob.setIntervalTime(0);
        scheduleJob.setIntervalTimeFormat("mm");

        callBackParam.setBeanName("riddleService");
        callBackParam.setMethodName("riddleEndQuartz");
        callBackParam.setParamMap(map);
        Map<String, Object> scheduleMap = new HashMap<>();
        scheduleMap.put("scheduleJob", scheduleJob);
        scheduleMap.put("callBackParam", callBackParam);
        try {
            scheduleService.addSimpleJob(scheduleMap);
        } catch (Exception e) {
            logger.error("【猜谜语】添加定时任务失败" + e.getMessage(), e);
        }
    }

    /**
     * 删除定时任务-5分钟游戏自动结束
     */
    private void deleteJob(String wxGroupId) {
        try {
            scheduleService.deleteJob(RiddleConstant.JOB_NAME_RIDDLE_EXPIRE + wxGroupId, RiddleConstant.JOB_GROUP_RIDDLE);
        } catch (Exception e) {
            logger.error("【猜谜语】删除定时任务失败" + e.getMessage(), e);
        }
    }


    @Override
    @ParamLog("sendIncorrectMessage")
    public void sendIncorrectMessage(GroupRedisDTO groupRedisDTO) {
        if (null == groupRedisDTO) {
            return;
        }
        String wxGroupId = groupRedisDTO.getWxGroupId();
        RiddleRecord record = riddleRecordDao.getLastRecordByWxGroupId(wxGroupId, null);
        if (null == record) {
            return;
        }
        if (null != record.getCorrect() && record.getCorrect() == false) {
            logger.info("发送答错文案" + groupRedisDTO);
            //发送答错文案
            String beforeContent = this.getRandomReply(RiddleReplyTypeEnum.incorrect.getCode());
            this.sendWeixinTextMessage(groupRedisDTO.getWxId(), wxGroupId, beforeContent, groupRedisDTO.getIp(), null);
            //保存记录
            RiddleRecord insertRecord = new RiddleRecord();
            insertRecord.setRiddleId(record.getRiddleId());
            insertRecord.setWxGroupId(wxGroupId);
            insertRecord.setWxUserId(groupRedisDTO.getWxId());
            insertRecord.setMessageContent(beforeContent);
            insertRecord.setStatus(RiddleRecordStatusEnum.underway.getCode());
            insertRecord.setCorrect(null);
            insertRecord.setFinishCount(record.getFinishCount());
            riddleRecordDao.insert(insertRecord);
        }
    }

    @Override
    public void sendCouponLink(String wxId, String wxGroupId, String ip) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            logger.error("线程休眠失败");
        }
        logger.info("wechatGroupLinkPrefix="+wechatGroupLinkPrefix);
        String link = wechatGroupLinkPrefix + "/groupGuessing/guessing?wxGroupId=" + wxGroupId;
        link = UrlUtils.getShortUrl4Own(wechatGroupLinkPrefix + "/link?url=" + URLEncoder.encode(link));
        String content = "优惠券领取链接（@所有人均可领取哦）:\n" + link;
        sendWeixinTextMessage(wxId, wxGroupId, content, ip, null);
    }

    /**
     * 发送成绩单并结束游戏
     * @param wxId
     * @param wxGroupId
     * @param ip
     * @param correctCount
     */
    @ParamLog("发送用户成绩单")
    private void sendResult(String wxId, String wxGroupId, String ip, Integer correctCount, RiddleRecord record, Date startTime, String wxUserId) {
        Integer total = riddleDao.getCount();
        String reply;
        if (correctCount.equals(total)) {//答对所有题
            reply = getRandomReply(RiddleReplyTypeEnum.finish_end.getCode()) + "\n\n回复关键词“猜谜语”，可重新开始游戏。";
            sendWeixinTextMessage(wxId, wxGroupId, reply, ip, wxUserId);
        } else {
            String correctContent = "给你点赞，答对本轮游戏最后一题，现在发成绩单咯，下一轮游戏我们不见不散哦。";
            sendWeixinTextMessage(wxId, wxGroupId, correctContent, ip, wxUserId);
            Integer ranking = riddleRecordDao.getGroupRanking(wxGroupId);
            String before = "目前本群总共猜对" + correctCount + "题，所有微信群中本群排名第" + ranking + "名，大家加油。\n" +
                    "--------------------------------\n本轮成绩如下：\n";
            List<UserRankingDTO> rankingDTOS = riddleRecordDao.getUserRanking(wxGroupId, startTime);
            if (ListUtils.isEmpty(rankingDTOS)) {
                logger.error("查询用户排名失败");
                return;
            }
            String content = "";
            for (int i = 0; i < rankingDTOS.size(); i++) {
                UserRankingDTO rankingDTO = rankingDTOS.get(i);
                GroupUserDTO groupUser = wechatGroupConsr.getWxUserInfoByWxUserId(rankingDTO.getWxUserId());
                int rank = i + 1;
                if (rank == 1) {
                    content = "第1名：" + rankingDTO.getCount() + "分，@" + groupUser.getNickName() + "，恭喜成为本轮的谜语达人。【鼓掌】【鼓掌】【鼓掌】";
                } else {
                    content = content + "\n第" + rank + "名，" + rankingDTO.getCount() + "分，@" + groupUser.getNickName();
                }
            }
            reply = before + content + "\n\n回复关键词“猜谜语”可继续游戏哦。";
            sendWeixinTextMessage(wxId, wxGroupId, reply, ip, null);
        }
        //结束游戏
        RiddleRecord insertRecord = new RiddleRecord();
        BeanUtils.copyProperties(record, insertRecord);
        insertRecord.setMessageContent(reply);
        insertRecord.setStatus(RiddleRecordStatusEnum.over.getCode());
        insertRecord.setCorrect(null);
        insertRecord.setWxUserId(wxId);
        riddleRecordDao.insert(insertRecord);
        deleteJob(wxGroupId);
    }

    /**
     * 10s后发送答错文案
     * @param dto
     */
    public void timeSchedule(GroupRedisDTO dto) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                sendIncorrectMessage(dto);
            }
        }, 10000);
        try {
            //如果主线程不休眠一段时间，就执行了cancel方法，那么定时器还没来得及执行就会被关闭
            Thread.sleep(60*1000);
            timer.cancel();
        } catch (InterruptedException e) {
            logger.error("关闭线程定时器失败" + e.getMessage(), e);
        }
    }

    @Override
    public void addClickTrack(RiddleClickRecord riddleClickRecord) {
        if (RiddleClickTypeEnum.wish.getCode().equals(riddleClickRecord.getClickType())) {
            Integer totalCount = riddleRecordDao.getOverTime(riddleClickRecord.getWxGroupId());
            Integer useCount = riddleClickRecordDao.getCountByType(riddleClickRecord.getWxGroupId(), riddleClickRecord.getWechatUserId(), RiddleClickTypeEnum.wish.getCode());
            if (useCount >= totalCount) {
                throw new BookBizException(BookBizException.ERROR, "抽奖次数已使用完");
            }
        }
        riddleClickRecordDao.insert(riddleClickRecord);
    }

    @Override
    public CouponClickDTO getGroupWishCount(String wxGroupId, Long wechatUserId) {
        Integer totalCount = riddleRecordDao.getOverTime(wxGroupId);
        Integer useCount = riddleClickRecordDao.getCountByType(wxGroupId, wechatUserId, RiddleClickTypeEnum.wish.getCode());
        Integer remainCount = 0;
        if (useCount < totalCount) {
            remainCount = totalCount - useCount;
        }
        CouponClickDTO dto = new CouponClickDTO();
        dto.setTotalCount(totalCount);
        dto.setRemainCount(remainCount);
        return dto;
    }

    @Override
    public void addCoupon(RiddleCoupon riddleCoupon, Long adviserId) {
        if (!riddleCoupon.getStatus()){//关闭
            riddleCouponDao.deleteByAdviser(adviserId);

        }else {//开启
            if (riddleCoupon.getZkFinalPrice().compareTo(riddleCoupon.getCouponPrice()) < 0) {
                throw new BookBizException(BookBizException.ERROR, "原价小于优惠金额");
            }
            riddleCoupon.setAfterCouponPrice(riddleCoupon.getZkFinalPrice().subtract(riddleCoupon.getCouponPrice()).setScale(2));
            RiddleCouponDTO couponDTO = riddleCouponDao.getByAdviser(adviserId);
            if (null == couponDTO) {
                riddleCoupon.setCreateUser(adviserId);
                riddleCouponDao.insert(riddleCoupon);
            } else {
                riddleCoupon.setId(couponDTO.getId());
                riddleCouponDao.update(riddleCoupon);
            }
        }
    }

    @Override
    public RiddleCouponDTO getByAdviser(Long adviserId) {
        RiddleCouponDTO couponDTO = riddleCouponDao.getByAdviser(adviserId);
        if (null == couponDTO) {
            couponDTO = new RiddleCouponDTO();
            couponDTO.setStatus(false);
        }
        return couponDTO;
    }

    @Override
    public RiddleCouponDTO getCouponByGroup(String wxGroupId) {
        GroupClassifyQrcodeDTO groupClassifyQrcodeDTO = bookGroupClassifyBiz.getClassifyQrcodeInfo(wxGroupId);
        if (null == groupClassifyQrcodeDTO) {
            throw new BookBizException(BookBizException.ERROR, "该群不存在");
        }
        Long adviserId = groupClassifyQrcodeDTO.getAdviserId();
        return getByAdviser(adviserId);
    }

}
