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

import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.content.ResourceConsr;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.WeixinQrcodeBiz;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.pcloudkeyword.set.PcloudRobotSet;
import com.pcloud.book.personal.dao.PcloudSkillRecordDao;
import com.pcloud.book.skill.biz.PcloudSubRemindBiz;
import com.pcloud.book.skill.dao.PcloudSkillDao;
import com.pcloud.book.skill.dao.PcloudSubReplyDao;
import com.pcloud.book.skill.dto.AppOrProductReplyDTO;
import com.pcloud.book.skill.entity.PcloudSkill;
import com.pcloud.book.skill.entity.PcloudSubReply;
import com.pcloud.book.skill.enums.SkillTypeEnum;
import com.pcloud.book.skill.enums.SubTypeEnum;
import com.pcloud.book.timecontrol.biz.TaskBiz;
import com.pcloud.book.timecontrol.biz.TaskSubscribeBiz;
import com.pcloud.book.timecontrol.dto.ReplyMessageBaseDto;
import com.pcloud.book.timecontrol.dto.TaskSendDto;
import com.pcloud.book.timecontrol.entity.TimeControlReplyMessage;
import com.pcloud.book.timecontrol.entity.TimeControlTask;
import com.pcloud.book.timecontrol.entity.TimeControlTaskItem;
import com.pcloud.book.timecontrol.entity.TimeControlTaskSend;
import com.pcloud.book.timecontrol.entity.TimeControlTaskSubscribe;
import com.pcloud.book.timecontrol.entity.TimeControlWeekDay;
import com.pcloud.book.timecontrol.enums.TimeControlPushTypeEnum;
import com.pcloud.book.timecontrol.enums.SendTypeEnum;
import com.pcloud.book.timecontrol.enums.TaskSendStateEnum;
import com.pcloud.book.timecontrol.enums.TaskSubscribeStateEnum;
import com.pcloud.book.timecontrol.mapper.TimeControlReplyMessageMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskItemMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskItemWeekMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskSendDetailMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskSendMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskSubscribeMapper;
import com.pcloud.book.util.common.YesOrNoEnums;
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.utils.BeanUtils;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.contentcenter.resource.dto.ResourceDTO;
import com.pcloud.wechatgroup.group.dto.GroupRobotDTO;
import com.sdk.wxgroup.RobotProcessTypeEnum;
import com.sdk.wxgroup.SendArticleMessageVO;
import com.sdk.wxgroup.SendFileVO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendPicMessageVO;
import com.sdk.wxgroup.SendTextMessageVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
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;

/**
 * @date: 2020年01月31日 20:12
 * @Author: Zcy
 * @Descprition
 */
@Component("taskSubscribeBiz")
public class TaskSubscribeBizImpl implements TaskSubscribeBiz {

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

    private static final ThreadFactory NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
            .setNameFormat("attendancetask-cashbak-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());

    @Autowired
    private TimeControlTaskSubscribeMapper taskSubscribeMapper;
    @Autowired
    private TimeControlTaskItemMapper taskItemMapper;
    @Autowired
    private TimeControlReplyMessageMapper replyMessageMapper;
    @Autowired
    private TimeControlTaskSendMapper timeControlTaskSendMapper;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private TimeControlTaskMapper taskMapper;
    @Autowired
    private ProductConsr productConsr;
    @Autowired
    private WeixinQrcodeBiz weixinQrcodeBiz;
    @Autowired
    private PcloudSkillDao pcloudSkillDao;
    @Autowired
    private PcloudSubReplyDao pcloudSubReplyDao;
    @Autowired
    private ResourceConsr resourceConsr;
    @Autowired
    private PcloudSubRemindBiz pcloudSubRemindBiz;
    @Value("${wechat.group.link.prefix}")
    private String wechatGroupLinkPrefix;
    @Autowired
    private PcloudRobotSet pcloudRobotSet;
    @Autowired
    private PcloudSkillRecordDao pcloudSkillRecordDao;
    @Autowired
    private TaskBiz taskBiz;
    @Autowired
    private TimeControlTaskItemWeekMapper timeControlTaskItemWeekMapper;
    @Autowired
    private TimeControlTaskSendDetailMapper timeControlTaskSendDetailMapper;

    @Override
    @ParamLog("任务订阅")
    public void subscribeTask(String wxUserId, Long bookId, Integer taskId, String robotWxId) {
        //更新技能记录列表状态
        List<Long> skillIds = pcloudSkillDao.getListByRelId(taskId);
        if (!ListUtils.isEmpty(skillIds)) {
            pcloudSkillRecordDao.batchUpdateState4ResourceAndActivity(wxUserId, skillIds, 1);
        }
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null == timeControlTask) {
            return;
        }
        TimeControlTaskSubscribe taskSubscribe = taskSubscribeMapper.getSubscribe(wxUserId, bookId, taskId);
        if (null != taskSubscribe) {
            if (TaskSubscribeStateEnum.FINISH.getState().equals(taskSubscribe.getState())) {
                LOGGER.info("任务已完成，直接返回");
                return;
            } else if (TaskSubscribeStateEnum.SUBSCRIBE.getState().equals(taskSubscribe.getState())) {
                LOGGER.info("任务已订阅，直接返回");
                return;
            } else {
                //1.改状态
                taskSubscribeMapper.subscribeTaskExist(taskSubscribe);
            }
        } else {
            taskSubscribe = new TimeControlTaskSubscribe();
            taskSubscribe.setWxUserId(wxUserId);
            taskSubscribe.setBookId(bookId);
            taskSubscribe.setTaskId(taskId);
            taskSubscribe.setState(TaskSubscribeStateEnum.SUBSCRIBE.getState());
            taskSubscribe.setRobotWxId(robotWxId);
            taskSubscribeMapper.subscribeTask(taskSubscribe);
        }
        insertTaskSend(wxUserId, bookId, taskId, timeControlTask, taskSubscribe);
        //订阅成功个人号回复消息
        EXECUTOR_SERVICE.execute(() -> {
            PcloudSkill pcloudSkill = pcloudSkillDao.getByRelId(taskId, SkillTypeEnum.TIME_MANAGE.value);
            if (null == pcloudSkill) {
                return;
            }
            List<PcloudSubReply> bySkillIdAndType = pcloudSubReplyDao.getBySkillIdAndType(pcloudSkill.getId(), SubTypeEnum.SUCCESS.value);
            GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
            String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
            if (!ListUtils.isEmpty(bySkillIdAndType)) {
                Integer count= bySkillIdAndType.size();
                String messageGroup =  UUID.randomUUID().toString();
                Integer index = 0;
                for (PcloudSubReply pcloudSubReply : bySkillIdAndType) {
                    sendReply(pcloudSubReply, wxUserId, robotWxId, ip, messageGroup, count, index);
                    index++;
                }
            }
        });
        //修改pcloud_sub_remind表状态
        pcloudSubRemindBiz.updateSubState(taskId,SkillTypeEnum.TIME_MANAGE.value,wxUserId,null);
        LOGGER.info("222");
    }

    private void insertTaskSend(String wxUserId, Long bookId, Integer taskId, TimeControlTask timeControlTask,
        TimeControlTaskSubscribe taskSubscribe) {
        List<ReplyMessageBaseDto> dayList = taskItemMapper.listTaskItemDay(taskId);
        List<TimeControlTaskSend> taskSendList = new ArrayList<>();
        if (!ListUtils.isEmpty(dayList)) {
            if (SendTypeEnum.SEND_DAY.state.equals(timeControlTask.getSendType())) {
                for (ReplyMessageBaseDto item : dayList) {
                    TimeControlTaskSend taskSend = new TimeControlTaskSend();
                    taskSend.setWxUserId(wxUserId);
                    taskSend.setBookId(bookId);
                    taskSend.setTaskId(taskId);
                    taskSend.setSubscribeId(taskSubscribe.getId());
                    taskSend.setSendState(TaskSendStateEnum.WAIT_SEND.state);
                    taskSend.setTaskItemId(item.getId());
                    taskSend.setSendDay(DateUtils.getShortDateStr(DateUtils.addDay(new Date(), item.getStartDay())));
                    taskSend.setSendHour(item.getSendHour());
                    taskSendList.add(taskSend);
                }
        } else if (SendTypeEnum.SEND_WEEK.state.equals(timeControlTask.getSendType())) {
                for (ReplyMessageBaseDto item : dayList) {
                    List<Integer> weekdays = item.getWeekdays();
                    if (!ListUtils.isEmpty(weekdays)) {
                        for (Integer weekDay : weekdays){
                        TimeControlTaskSend taskSend = new TimeControlTaskSend();
                        taskSend.setWxUserId(wxUserId);
                        taskSend.setBookId(bookId);
                        taskSend.setTaskId(taskId);
                        taskSend.setSubscribeId(taskSubscribe.getId());
                        taskSend.setSendState(TaskSendStateEnum.WAIT_SEND.state);
                        taskSend.setTaskItemId(item.getId());
                        taskSend.setSendWeek(weekDay);
                        taskSend.setSendCount(0);
                        taskSend.setSendHour(item.getSendHour());
                        taskSendList.add(taskSend);
                        }
                    }
                }
        }
            LOGGER.info("111");
            if (!ListUtils.isEmpty(taskSendList)){
                timeControlTaskSendMapper.batchInsert(taskSendList);
            }
    }
    }

    @ParamLog
    private void sendReply(PcloudSubReply pcloudSubReply, String userWxId, String robotWxId, String ip, String messageGroupId, Integer count, Integer index) {
        Integer type = pcloudSubReply.getType();
        if (ReplyTypeEnum.TEXT.value.equals(type)) {
            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
            sendTextMessageVO.setContent(pcloudSubReply.getContent());
            sendTextMessageVO.setAltId(robotWxId);
            sendTextMessageVO.setWxGroupId(userWxId);
            sendTextMessageVO.setIp(ip);
            sendTextMessageVO.setCode(1);
            sendTextMessageVO.setCounts(count);
            sendTextMessageVO.setMessageGroupId(messageGroupId);
            sendTextMessageVO.setIndex(index);
            sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.SKILL_REPLY);
            wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));;
        }
        if (ReplyTypeEnum.IMAGE.value.equals(type)) {
            SendPicMessageVO sendPicMessageVO = new SendPicMessageVO();
            sendPicMessageVO.setWxGroupId(userWxId);
            sendPicMessageVO.setAltId(robotWxId);
            sendPicMessageVO.setPicUrl(pcloudSubReply.getPicUrl());
            sendPicMessageVO.setIp(ip);
            sendPicMessageVO.setCode(1);
            sendPicMessageVO.setCounts(count);
            sendPicMessageVO.setMessageGroupId(messageGroupId);
            sendPicMessageVO.setIndex(index);
            sendPicMessageVO.setRobotProcessType(RobotProcessTypeEnum.SKILL_REPLY);
            wechatGroupConsr.sendMessage(JSON.toJSONString(sendPicMessageVO));
        }
        if (ReplyTypeEnum.APP.value.equals(type)) {
            AppOrProductReplyDTO appOrProductReplyDTO = new AppOrProductReplyDTO();
            appOrProductReplyDTO.setServeType(pcloudSubReply.getServeType());
            appOrProductReplyDTO.setServeId(pcloudSubReply.getServeId());
            appOrProductReplyDTO.setLinkUrl(pcloudSubReply.getLinkUrl());
            appOrProductReplyDTO.setRobotWxId(robotWxId);
            appOrProductReplyDTO.setRobotWxId(userWxId);
            appOrProductReplyDTO.setIp(ip);
            appOrProductReplyDTO.setSendMessageType(SendMessageTypeEnum.SELF.getCode());
            appOrProductReplyDTO.setCounts(count);
            appOrProductReplyDTO.setIndex(index);
            appOrProductReplyDTO.setMessageGroupId(messageGroupId);
            appOrProductReplyDTO.setRobotProcessTypeEnum(RobotProcessTypeEnum.SKILL_REPLY);
            pcloudRobotSet.sendAppOrProductReply(appOrProductReplyDTO);
        }
        if (ReplyTypeEnum.LINK.value.equals(type)) {
            SendArticleMessageVO sendArticleMessageVO = new SendArticleMessageVO();
            sendArticleMessageVO.setCode(1);
            sendArticleMessageVO.setAltId(robotWxId);
            sendArticleMessageVO.setDescription(pcloudSubReply.getDescription());
            sendArticleMessageVO.setWxGroupId(userWxId);
            sendArticleMessageVO.setLinkUrl(pcloudSubReply.getLinkUrl());
            sendArticleMessageVO.setPicUrl(pcloudSubReply.getPicUrl());
            sendArticleMessageVO.setTitle(pcloudSubReply.getContent());
            sendArticleMessageVO.setIp(ip);
            sendArticleMessageVO.setCounts(count);
            sendArticleMessageVO.setIndex(index);
            sendArticleMessageVO.setMessageGroupId(messageGroupId);
            sendArticleMessageVO.setRobotProcessType(RobotProcessTypeEnum.SKILL_REPLY);
            wechatGroupConsr.sendMessage(JSON.toJSONString(sendArticleMessageVO));
        }
        if (ReplyTypeEnum.RESOURCE.value.equals(type)) {
            SendFileVO sendFileVO = new SendFileVO();
            Map<Long, ResourceDTO> map = resourceConsr.mapByIds(Arrays.asList(pcloudSubReply.getResourceId()));
            ResourceDTO resourceDTO = map.get(pcloudSubReply.getResourceId());
            if (resourceDTO != null) {
                sendFileVO.setFileUrl(resourceDTO.getFileUrl());
                String fileName = resourceDTO.getResourceName();
                String fileType = resourceDTO.getFileType();
                if (fileName.contains(fileType)) {//去掉后缀
                    fileName = fileName.substring(0, fileName.indexOf(fileType) - 1);
                }
                sendFileVO.setFileName(fileName);
            }
            sendFileVO.setIp(ip);
            sendFileVO.setAltId(robotWxId);
            sendFileVO.setWxId(userWxId);
            sendFileVO.setCounts(count);
            sendFileVO.setIndex(index);
            sendFileVO.setMessageGroupId(messageGroupId);
            sendFileVO.setRobotProcessType(RobotProcessTypeEnum.SKILL_REPLY);
            wechatGroupConsr.sendMessage(JSON.toJSONString(sendFileVO));
        }
    }

    @Override
    @ParamLog("取消订阅")
    public void unSubscribeTask(String wxUserId, Long bookId, Integer taskId) {
        //更新技能记录列表状态
        List<Long> skillIds = pcloudSkillDao.getListByRelId(taskId);
        if (!ListUtils.isEmpty(skillIds)){
            pcloudSkillRecordDao.batchUpdateState4ResourceAndActivity(wxUserId,skillIds,2);
        }
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null == timeControlTask) {
            return;
        }
        TimeControlTaskSubscribe taskSubscribe = taskSubscribeMapper.getSubscribe(wxUserId, bookId, taskId);
        LOGGER.info("taskSubscribe = " + taskSubscribe);
        if (null != taskSubscribe && TaskSubscribeStateEnum.SUBSCRIBE.getState().equals(taskSubscribe.getState())) {
            taskSubscribe.setState(TaskSubscribeStateEnum.UNSUBSCRIBE.getState());
            taskSubscribeMapper.unSubscribeTask(taskSubscribe);
            //取消订阅的同时需要取消待发送的任务
            timeControlTaskSendMapper.cancelSend(taskSubscribe.getId(), TaskSendStateEnum.CANCEL.getState());
            //取消订阅个人号回复消息
            EXECUTOR_SERVICE.execute(() -> {
                PcloudSkill pcloudSkill = pcloudSkillDao.getByRelId(taskId, SkillTypeEnum.TIME_MANAGE.value);
                if (null == pcloudSkill) {
                    return;
                }
                List<PcloudSubReply> bySkillIdAndType = pcloudSubReplyDao.getBySkillIdAndType(pcloudSkill.getId(), SubTypeEnum.CANCEL.value);
                GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(taskSubscribe.getRobotWxId());
                String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
                if (!ListUtils.isEmpty(bySkillIdAndType)) {
                    Integer count= bySkillIdAndType.size();
                    String messageGroupId =  UUID.randomUUID().toString();
                    Integer index = 0;
                    for (PcloudSubReply pcloudSubReply : bySkillIdAndType) {
                        sendReply(pcloudSubReply, wxUserId, taskSubscribe.getRobotWxId(), ip, messageGroupId, count, index);
                        index++;
                    }
                }
            });
        }
    }

    @Override
    public void listTodayTask() {

    }

    @Override
    public void sendTimeTaskMessage() {
        List<TaskSendDto> taskSendList = timeControlTaskSendMapper.listTodayTask();
        if(ListUtils.isEmpty(taskSendList)){
            return;
        }
        addSendDetails(taskSendList);
        Map<String, List<TaskSendDto>> collect = taskSendList.stream().collect(Collectors.groupingBy(taskSendDto -> taskSendDto.getWxUserId() + "_" + taskSendDto.getTaskId()));
        for (String s : collect.keySet()) {
            sendTaskMsg(collect.get(s));
        }
    }

    private void sendTaskMsg(List<TaskSendDto> taskSendList) {
        // 判断是否处理过
        boolean success = false;
        int count = 0;
        for(TaskSendDto sendDto : taskSendList) {
            count++;
            Integer taskId = sendDto.getTaskId();
            Integer taskItemId = sendDto.getTaskItemId();
            TimeControlTaskItem timeControlTaskItem = taskItemMapper.selectByPrimaryKey(taskItemId);
            if (null == timeControlTaskItem) {
                continue;
            }
            List<TimeControlReplyMessage> replyMessages = replyMessageMapper.list4TaskItem(sendDto.getTaskItemId(), 0);
            String robotWxId = sendDto.getRobotWxId();
            String wxUserId = sendDto.getWxUserId();
            GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
            String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
            Integer taskSendId = sendDto.getId();
            TimeControlTaskSend timeControlTaskSend = timeControlTaskSendMapper.getById(taskSendId);
            taskBiz.sendReplyMessage(replyMessages, wxUserId, robotWxId, ip);
            if(YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getAddSendTime())){
                //封装退订提醒
                SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                sendTextMessageVO.setWxId(robotWxId);
                sendTextMessageVO.setAltId(robotWxId);
                sendTextMessageVO.setWxGroupId(wxUserId);
                sendTextMessageVO.setIp(ip);
                String content = "消息发送时间(" + DateUtils.formatDate(new Date())+")";
                sendTextMessageVO.setContent(content);
                sendTextMessageVO.setIndex(0);
                sendTextMessageVO.setCounts(1);
                sendTextMessageVO.setMessageGroupId(UUID.randomUUID().toString());
                sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));
            }
            if (YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getTdConfirm())){
                //封装退订提醒
                SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                sendTextMessageVO.setWxId(robotWxId);
                sendTextMessageVO.setAltId(robotWxId);
                sendTextMessageVO.setWxGroupId(wxUserId);
                sendTextMessageVO.setIp(ip);
                String content = "";
                if (YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getTdConfirm())) {
                    if (StringUtil.isEmpty(content)) {
                        content = content + "如需退订，请回复 TD" + sendDto.getTaskId();
                    }else {
                        content = content + "\n如需退订，请回复 TD" + sendDto.getTaskId();
                    }
                }
                sendTextMessageVO.setContent(content);
                sendTextMessageVO.setIndex(0);
                sendTextMessageVO.setCounts(1);
                sendTextMessageVO.setMessageGroupId(UUID.randomUUID().toString());
                sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));;
            }

            if (YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getProgressGuidance())) {
                //封装任务进度
                SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                sendTextMessageVO.setWxId(robotWxId);
                sendTextMessageVO.setAltId(robotWxId);
                sendTextMessageVO.setWxGroupId(wxUserId);
                sendTextMessageVO.setIp(ip);
                String link = wechatGroupLinkPrefix + "/time/task?taskId=" + timeControlTaskItem.getTaskId()
                        + "&taskItemId=" + taskItemId + "&wxUserId=" + wxUserId;
                String content = "当前任务进度→\n" + UrlUtils.getShortUrl4Own(link) + "";
                sendTextMessageVO.setContent(content);
                sendTextMessageVO.setIndex(0);
                sendTextMessageVO.setCounts(1);
                sendTextMessageVO.setMessageGroupId(UUID.randomUUID().toString());
                sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));;
            }
            TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
            //更新发送状态
            Integer completeState = null;
            Integer weekDay = DateUtils.getWeek();
            if(weekDay == 1){
                weekDay = 7;
            }else{
                weekDay = --weekDay;
            }
            Integer maxWeekDay = timeControlTaskItemWeekMapper.getMaxWeekDay(taskItemId);
            if (!YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getFinishConfirm())) {
                //根据日期来判断完成状态
                if (SendTypeEnum.SEND_DAY.state.equals(timeControlTask.getSendType())){
                    completeState = 1;
                }else if (SendTypeEnum.SEND_WEEK.state.equals(timeControlTask.getSendType())){
                    Date nextSendDate = DateUtils.addDay(new Date(),7);
                    Date shortNextSendDate = DateUtils.dateFormat(nextSendDate);
                    if (TimeControlPushTypeEnum.SEND_EVERY_DAY.state.equals(timeControlTask.getSendType())){
                        //如果每天发送今天等于结束时间则结束
                        if (DateUtils.dateFormat(new Date()).equals(timeControlTaskItem.getEndTime())){
                            completeState = 1;
                        }
                    }else if(maxWeekDay != null && maxWeekDay.equals(weekDay) && TimeControlPushTypeEnum.SEND_4_WEEK.state.equals(timeControlTask.getSendType())){
                        //如果下一次执行的时候大于最大时间则算完成了
                        if (shortNextSendDate.after(timeControlTaskItem.getEndTime())){
                            completeState = 1;
                        }
                    }

                }
            } else if (YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getFinishConfirm())){
                //根据日期来判断完成状态
                if (SendTypeEnum.SEND_DAY.state.equals(timeControlTask.getSendType())){
                    send4Finish(timeControlTaskItem, robotWxId, wxUserId, ip, taskSendId);
                }else if (SendTypeEnum.SEND_WEEK.state.equals(timeControlTask.getSendType())) {
                    Date nextSendDate = DateUtils.addDay(new Date(), 7);
                    Date shortNextSendDate = DateUtils.dateFormat(nextSendDate);
                    if (TimeControlPushTypeEnum.SEND_EVERY_DAY.state.equals(timeControlTask.getSendType())) {
                        //如果每天发送今天等于结束时间则结束
                        if (DateUtils.dateFormat(new Date()).equals(timeControlTaskItem.getEndTime())) {
                            send4Finish(timeControlTaskItem, robotWxId, wxUserId, ip, taskSendId);
                            completeState = 1;
                        }
                    } else if (maxWeekDay != null && maxWeekDay.equals(weekDay) && TimeControlPushTypeEnum.SEND_4_WEEK.state
                            .equals(timeControlTask.getSendType())) {
                        //如果下一次执行的时候大于最大时间则算完成了
                        if (shortNextSendDate.after(timeControlTaskItem.getEndTime())) {
                            send4Finish(timeControlTaskItem, robotWxId, wxUserId, ip, taskSendId);
                            completeState = 1;
                        }
                    }
                }
            }
            timeControlTaskSendMapper.updateSendState(sendDto.getId(), TaskSendStateEnum.FINISH_SEND.getState(), completeState);
            //如果是按周发送则增加发送次数
            if (SendTypeEnum.SEND_WEEK.state.equals(timeControlTask.getSendType())){
                timeControlTaskSendMapper.addSendCount(sendDto.getId());
            }
            //每次都要判断一下是否所有单项任务都完成。完成之后需要同步修改关注表里面完成状态
            if (SendTypeEnum.SEND_DAY.state.equals(timeControlTask.getSendType())){
                if(count==taskSendList.size()) {
                    Integer noCompletedItem = timeControlTaskSendMapper.getNoCompletedCount(timeControlTaskSend.getSubscribeId());
                    if (noCompletedItem == 0) {
                        taskSubscribeMapper.completedTaskById(timeControlTaskSend.getSubscribeId());
                    }
                }
            }else if (SendTypeEnum.SEND_WEEK.state.equals(timeControlTask.getSendType())){
                Date nextSendDate = DateUtils.addDay(new Date(),7);
                Date shortNextSendDate = DateUtils.dateFormat(nextSendDate);
                Date maxEndTime = taskItemMapper.getMaxEndTime(taskId);
                if (TimeControlPushTypeEnum.SEND_EVERY_DAY.state.equals(timeControlTask.getSendType())){
                    //如果每天发送今天等于结束时间则结束
                    if (DateUtils.dateFormat(new Date()).equals(maxEndTime)){
                        taskSubscribeMapper.completedTaskById(timeControlTaskSend.getSubscribeId());
                    }
                }else if(maxWeekDay != null && maxWeekDay.equals(weekDay) && TimeControlPushTypeEnum.SEND_4_WEEK.state.equals(timeControlTask.getSendType())){
                    //如果下一次执行的时候大于最大时间则算完成了
                    if (shortNextSendDate.after(maxEndTime)){
                        taskSubscribeMapper.completedTaskById(timeControlTaskSend.getSubscribeId());
                    }
                }

            }
        }
    }

    private void send4Finish(TimeControlTaskItem timeControlTaskItem, String robotWxId, String wxUserId, String ip, Integer taskSendId) {
        //封装退订提醒
        SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
        sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
        sendTextMessageVO.setWxId(robotWxId);
        sendTextMessageVO.setAltId(robotWxId);
        sendTextMessageVO.setWxGroupId(wxUserId);
        sendTextMessageVO.setIp(ip);
        String content = "";
        if (YesOrNoEnums.YES.getValue().equals(timeControlTaskItem.getFinishConfirm())) {
            String finishLinkUrl = timeControlTaskItem.getFinishLinkUrl();
            if (finishLinkUrl != null) {
                String baseUrl = wechatGroupLinkPrefix + "/link?";
                finishLinkUrl = baseUrl + "wxId=" +wxUserId+"&taskSendId=" +taskSendId+"&url=" + URLEncoder.encode(finishLinkUrl);
                String resultUrl = UrlUtils.getShortUrl4Own(finishLinkUrl);
                content = content + timeControlTaskItem.getFinishLinkIntroduce() + "\n" + resultUrl;
            }
        }
        sendTextMessageVO.setContent(content);
        sendTextMessageVO.setIndex(0);
        sendTextMessageVO.setCounts(1);
        sendTextMessageVO.setMessageGroupId(UUID.randomUUID().toString());
        sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
        wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));
        ;
    }

    @Override
    public TimeControlTaskSubscribe getSubscribeState(String wxUserId, Integer taskId) {
        TimeControlTaskSubscribe timeControlTaskSubscribe = taskSubscribeMapper.getSubscribe(wxUserId, null, taskId);
        if (null == timeControlTaskSubscribe) {
            timeControlTaskSubscribe = new TimeControlTaskSubscribe();
            timeControlTaskSubscribe.setTaskId(taskId);
            timeControlTaskSubscribe.setState(TaskSubscribeStateEnum.UNSUBSCRIBE.getState());
            timeControlTaskSubscribe.setWxUserId(wxUserId);
        }
        return timeControlTaskSubscribe;
    }

    @ParamLog("时间管理订阅")
    @Override
    public void subscribeTimeControlTask(String wxUserId, Long bookId, Integer taskId, String robotWxId) {
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null == timeControlTask) {
            return;
        }
        TimeControlTaskSubscribe taskSubscribe = taskSubscribeMapper.getSubscribe(wxUserId, bookId, taskId);
        if (null != taskSubscribe) {
            if (TaskSubscribeStateEnum.FINISH.getState().equals(taskSubscribe.getState())) {
                LOGGER.info("任务已完成，直接返回");
                return;
            } else if (TaskSubscribeStateEnum.SUBSCRIBE.getState().equals(taskSubscribe.getState())) {
                LOGGER.info("任务已订阅，直接返回");
                return;
            } else {
                //1.改状态
                taskSubscribeMapper.subscribeTaskExist(taskSubscribe);
            }
        } else {
            taskSubscribe = new TimeControlTaskSubscribe();
            taskSubscribe.setWxUserId(wxUserId);
            taskSubscribe.setBookId(bookId);
            taskSubscribe.setTaskId(taskId);
            taskSubscribe.setState(TaskSubscribeStateEnum.SUBSCRIBE.getState());
            taskSubscribe.setRobotWxId(robotWxId);
            taskSubscribeMapper.subscribeTask(taskSubscribe);
        }
        //插入待发送记录
       insertTaskSend(wxUserId,bookId,taskId,timeControlTask,taskSubscribe);
    }

    @Override
    @ParamLog("按周定时发送任务消息")
    public void sendTimeTaskMessage4Week(Integer taskItemId) {
        TimeControlTaskItem timeControlTaskItem = taskItemMapper.selectByPrimaryKey(taskItemId);
        if (null ==  timeControlTaskItem){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,taskItemId+"此任务不存在");
        }
        Integer weekDay = DateUtils.getWeek();
        if(weekDay == 1){
            weekDay = 7;
        }else{
            weekDay = --weekDay;
        }
        List<TaskSendDto> taskSendList = timeControlTaskSendMapper.listTodayTask4Week(taskItemId,weekDay);
        if(ListUtils.isEmpty(taskSendList)){
            return;
        }
        addSendDetails(taskSendList);
        Map<String, List<TaskSendDto>> collect = taskSendList.stream().collect(Collectors.groupingBy(taskSendDto -> taskSendDto.getWxUserId() + "_" + taskSendDto.getTaskId()));
        for (String s : collect.keySet()) {
            sendTaskMsg(collect.get(s));
        }

    }

    private void addSendDetails(List<TaskSendDto> taskSendList) {
        List<TimeControlTaskSend> taskSendDetailList = new ArrayList<>();
        taskSendList.stream().forEach(e ->{
                TimeControlTaskSend timeControlTaskSend = new TimeControlTaskSend();
                BeanUtils.copyProperties(e,timeControlTaskSend);
                taskSendDetailList.add(timeControlTaskSend);
            });
        //新增发送记录表
        if (!ListUtils.isEmpty(taskSendDetailList)){
            timeControlTaskSendDetailMapper.batchInsert(taskSendDetailList);
        }
    }

    private String splitUrl(AccountSettingDto accountSettingDto, String url) {
        String protocol = accountSettingDto.getProtocol();
        if (StringUtils.isEmpty(protocol)) {
            protocol = ChannelConstants.HTTP;
        }
        String resultUrl = "";
        if (!StringUtils.isEmpty(url)) {
            if (url.startsWith("http")) {
                return url;
            }
            if (url.startsWith("*")) {
                String endUrl = url.substring(url.indexOf("/"));
                if (accountSettingDto.getRandom() == null) {
                    resultUrl = protocol + "app." + accountSettingDto.getFirstDomain() + "/" + url.substring(1, url.indexOf("/")) + "/W"
                            + accountSettingDto.getAccountSettingId() + endUrl;
                } else {
                    resultUrl = protocol + "app" + accountSettingDto.getRandom() + "." + accountSettingDto.getFirstDomain() + "/" + url.substring(1, url.indexOf("/")) + "/W"
                            + accountSettingDto.getAccountSettingId() + endUrl;
                }
            } else {
                resultUrl = protocol + accountSettingDto.getDomain() + "/W" + accountSettingDto.getAccountSettingId() + url;
            }
        }
        return resultUrl;
    }
}
