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

import com.alibaba.fastjson.JSON;
import com.pcloud.appcenter.app.dto.AppDto;
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.group.enums.AppAndProductTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.keywords.enums.ReplyTypeEnum;
import com.pcloud.book.skill.dao.PcloudSkillDao;
import com.pcloud.book.skill.entity.PcloudSkill;
import com.pcloud.book.skill.enums.SkillTypeEnum;
import com.pcloud.book.timecontrol.biz.TaskBiz;
import com.pcloud.book.timecontrol.biz.TaskSubscribeBiz;
import com.pcloud.book.timecontrol.dto.BookTaskBindingDto;
import com.pcloud.book.timecontrol.dto.CreateReplyMessageDto;
import com.pcloud.book.timecontrol.dto.CreateTaskDto;
import com.pcloud.book.timecontrol.dto.CreateTaskItemDto;
import com.pcloud.book.timecontrol.dto.LabelDto;
import com.pcloud.book.timecontrol.dto.ReplyMessageBaseDto;
import com.pcloud.book.timecontrol.dto.ReplyMessageDto;
import com.pcloud.book.timecontrol.dto.TaskDto;
import com.pcloud.book.timecontrol.dto.TaskItemDto;
import com.pcloud.book.timecontrol.dto.UpdateTaskDto;
import com.pcloud.book.timecontrol.dto.UpdateTaskItemDto;
import com.pcloud.book.timecontrol.entity.TimeControlPrizeItem;
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.TimeControlTaskPrize;
import com.pcloud.book.timecontrol.entity.TimeControlTaskSend;
import com.pcloud.book.timecontrol.entity.TimeControlTaskSubscribe;
import com.pcloud.book.timecontrol.enums.TaskPrizeTypeEnum;
import com.pcloud.book.timecontrol.enums.TaskSendStateEnum;
import com.pcloud.book.timecontrol.mapper.BookTaskBindingMapper;
import com.pcloud.book.timecontrol.mapper.TaskPrizeItemMapper;
import com.pcloud.book.timecontrol.mapper.TaskPrizeMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlReplyMessageMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskItemMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskSendMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskSubscribeMapper;
import com.pcloud.book.timecontrol.vo.KeyWordTaskVO;
import com.pcloud.book.util.common.YesOrNoEnums;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.ServeLinkUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.common.utils.string.StringUtilParent;
import com.pcloud.contentcenter.resource.dto.ResourceDTO;
import com.pcloud.labelcenter.label.service.LabelService;
import com.pcloud.wechatgroup.base.exception.WechatGroupBizException;
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 lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

/**
 * @date: 2020年01月30日 14:20
 * @Author: Zcy
 * @Descprition
 */
@Slf4j
@Component("taskBiz")
public class TaskBizImpl implements TaskBiz {

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

    @Autowired
    private PcloudSkillDao pcloudSkillDao;
    @Autowired
    private TimeControlTaskMapper taskMapper;
    @Autowired
    private TimeControlTaskItemMapper taskItemMapper;
    @Autowired
    private TimeControlReplyMessageMapper replyMessageMapper;
    @Autowired
    private BookTaskBindingMapper bookTaskBindingMapper;
    @Autowired
    private TimeControlTaskSubscribeMapper taskSubscribeMapper;
    @Autowired
    private TimeControlTaskSendMapper timeControlTaskSendMapper;
    @Autowired
    private LabelService labelService;
    @Autowired
    private TaskSubscribeBiz taskSubscribeBiz;
    //@Autowired
    //private PcloudKeywordService pcloudKeywordService;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private WeixinQrcodeBiz weixinQrcodeBiz;
    @Autowired
    private TaskPrizeMapper taskPrizeMapper;
    @Autowired
    private TaskPrizeItemMapper taskPrizeItemMapper;
    @Autowired
    private AppConsr appConsr;
    @Autowired
    private QrcodeSceneConsr qrcodeSceneConsr;
    @Autowired
    private TaskPrizeBizImpl taskPrizeBiz;
    @Autowired
    private ResourceConsr resourceConsr;
    @Autowired
    private ProductConsr productConsr;

    @Override
    public Integer createTask(CreateTaskDto createTaskDto) {
        TimeControlTask timeControlTask = new TimeControlTask();
        BeanUtils.copyProperties(createTaskDto, timeControlTask);
        taskMapper.insert(timeControlTask);
        return timeControlTask.getTaskId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTask(Integer taskId) {
        PcloudSkill byRelId = pcloudSkillDao.getByRelId(taskId, SkillTypeEnum.TIME_MANAGE.value);
        if (Objects.nonNull(byRelId)) {
            throw new BookBizException(BookBizException.PARAM_IS_EXIST, "该计划已经关联技能，无法删除！");
        }
        // 1删除任务模板
        taskMapper.deleteByPrimaryKey(taskId);

        // 2删除书与任务之间的关联关系
        bookTaskBindingMapper.deleteByTask(taskId);
        // 3删除用户对这个任务的订阅关系
        taskSubscribeMapper.unSubscribeTaskByTaskId(taskId);

        //4 取消待发送的任务
        timeControlTaskSendMapper.cancelSendByTaskId(taskId);
    }

    @Override
    public void updateTask(UpdateTaskDto updateTaskDto) {
        TimeControlTask timeControlTask = new TimeControlTask();
        BeanUtils.copyProperties(updateTaskDto, timeControlTask);
        taskMapper.updateTask(timeControlTask);
        //同步任务名称
        bookTaskBindingMapper.updateTaskName(updateTaskDto.getTaskId(), updateTaskDto.getTaskName());
    }

    @Override
    public TaskDto getTaskById(Integer taskId) {
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null != timeControlTask) {
            TaskDto taskDto = new TaskDto();
            BeanUtils.copyProperties(timeControlTask, taskDto);
            return taskDto;
        }
        return null;
    }

    @Override
    public PageBeanNew<TaskDto> listTask4Pcloud(Integer currentPage, Integer numPerPage, String search) {
        List<TaskDto> list = new ArrayList<>();
        Integer count = taskMapper.getTaskCount(search);
        if (count <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, list);
        }
        list = taskMapper.listTask4Pcloud(currentPage * numPerPage, numPerPage, search);

        // 封装标签 统计数据
        Set<Long> labelSet = new HashSet<>();
        // 获取所有标签 统一获取标签名称
        list.forEach(item -> {
            labelSet.add(item.getProLabelId());
            labelSet.add(item.getDepLabelId());
            labelSet.add(item.getPurLabelId());
        });

        labelSet.remove(null);
        if (labelSet.size() > 0) {
            try {
                // 批量获取标签名称
                ResponseEntity<ResponseDto<Map<Long, String>>> response = labelService.getLabelName(new ArrayList<>(labelSet));
                Map<Long, String> labelMap = ResponseHandleUtil.parseMap(response, Long.class, String.class);
                // 补充标签名称
                list.forEach(item -> {
                    item.setProLabelName(labelMap.get(item.getProLabelId()));
                    item.setDepLabelName(labelMap.get(item.getDepLabelId()));
                    item.setPurLabelName(labelMap.get(item.getPurLabelId()));
                    String filterStr = StringUtilParent.replaceHtml(item.getTaskIntroduce());
                    String subStr = filterStr.length() > 60 ? filterStr.substring(0, 60) + "..." : filterStr;
                    item.setCutTaskIntroduce(subStr);
                });
            } catch (Exception e) {
                log.error("labelService.getLabelName 批量获取标签名称失败" + e.getMessage());
            }
        }
        return new PageBeanNew<>(currentPage, numPerPage, count, list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createTaskItem(CreateTaskItemDto createTaskItemDto) {
        Integer taskId = createTaskItemDto.getTaskId();
        Integer startDay = createTaskItemDto.getStartDay();
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null == timeControlTask) {
            return null;
        }
        List<CreateReplyMessageDto> replyMessageList = createTaskItemDto.getReplyMessageList();
        if (ListUtils.isEmpty(replyMessageList)) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "请至少填写一条任务提醒");
        }
        if (replyMessageList.size() > 3) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "至多填写3条任务提醒");
        }
        //检验是否存在当天定时任务
        /*TimeControlTaskItem item = taskItemMapper.getByTaskIdAndDay(taskId, startDay);
        if (null != item) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "已配置过当天消息!");
        }*/
        List<CreateReplyMessageDto> completedReplyMessageList = createTaskItemDto.getCompletedReplyMessageList();
        if(null!=createTaskItemDto.getFinishConfirm() && createTaskItemDto.getFinishConfirm()==1){
            if (StringUtil.isEmpty(createTaskItemDto.getFinishLinkIntroduce())) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "任务完成资源封装链接介绍不能为空！");
            }
            if (StringUtil.isEmpty(createTaskItemDto.getFinishLinkUrl())) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "任务完成资源封装链接地址不能为空！");
            }
            if (ListUtils.isEmpty(completedReplyMessageList)) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "请至少填写一条完成任务提醒");
            }
            if (completedReplyMessageList.size() > 4) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "至多填写3条完成任务提醒");
            }
        }
        TimeControlTaskItem item = new TimeControlTaskItem();
        BeanUtils.copyProperties(createTaskItemDto, item);
        if (null == item.getFinishConfirm()) {
            item.setFinishConfirm(0);
        }
        if(null==item.getTdConfirm()){
            item.setTdConfirm(0);
        }
        if(null==item.getAddSendTime()){
            item.setAddSendTime(0);
        }
        if(null == item.getProgressGuidance()) {
            item.setProgressGuidance(0);
        }
        taskItemMapper.insert(item);
        Integer taskItemId = item.getId();
        List<TimeControlReplyMessage> list = new ArrayList<>();
        replyMessageList.forEach(message -> {
            TimeControlReplyMessage replyMessage = new TimeControlReplyMessage();
            BeanUtils.copyProperties(message, replyMessage);
            replyMessage.setTaskItemId(taskItemId);
            replyMessage.setTaskId(taskId);
            replyMessage.setType(0);
            list.add(replyMessage);
        });
        //任务完成回复消息list
        if(null!=createTaskItemDto.getFinishConfirm() && createTaskItemDto.getFinishConfirm()==1){
            List<TimeControlReplyMessage> messageList = new ArrayList<>();
            completedReplyMessageList.forEach(message -> {
                TimeControlReplyMessage replyMessage = new TimeControlReplyMessage();
                BeanUtils.copyProperties(message, replyMessage);
                replyMessage.setTaskItemId(taskItemId);
                replyMessage.setTaskId(taskId);
                replyMessage.setType(1);
                list.add(replyMessage);
            });
        }
        replyMessageMapper.batchInsert(list);
        return taskItemId;
    }

    @Override
    public void deleteTaskItem(Integer taskItemId) {
        taskItemMapper.deleteByPrimaryKey(taskItemId);

        replyMessageMapper.deleteByItemId(taskItemId);
        //删除待发送任务
        timeControlTaskSendMapper.cancelSendByItemId(taskItemId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTaskItem(UpdateTaskItemDto updateTaskItemDto) {
        Integer taskItemId = updateTaskItemDto.getId();
        TimeControlTaskItem timeControlTaskItem = taskItemMapper.selectByPrimaryKey(taskItemId);
        if (null == timeControlTaskItem) {
            return;
        }
        Integer taskId = timeControlTaskItem.getTaskId();
        Integer startDay = updateTaskItemDto.getStartDay();
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        if (null == timeControlTask) {
            return;
        }
        List<CreateReplyMessageDto> replyMessageList = updateTaskItemDto.getReplyMessageList();
        if (ListUtils.isEmpty(replyMessageList)) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "请至少填写一条任务提醒");
        }
        if (replyMessageList.size() > 3) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "至多填写3条任务提醒");
        }
        //检验是否存在当天定时任务
        /*TimeControlTaskItem item = taskItemMapper.getByTaskIdAndDay(taskId, startDay);
        if (null != item && !item.getId().equals(taskItemId)) {
            throw new WechatGroupBizException(WechatGroupBizException.ERROR, "已配置过当天消息!");
        }*/
        List<CreateReplyMessageDto> completedReplyMessageList = updateTaskItemDto.getCompletedReplyMessageList();
        if(null!=updateTaskItemDto.getFinishConfirm() && updateTaskItemDto.getFinishConfirm()==1){
            if (StringUtil.isEmpty(updateTaskItemDto.getFinishLinkIntroduce())) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "任务完成资源封装链接介绍不能为空！");
            }
            if (StringUtil.isEmpty(updateTaskItemDto.getFinishLinkUrl())) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "任务完成资源封装链接地址不能为空！");
            }
            if (ListUtils.isEmpty(completedReplyMessageList)) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "请至少填写一条完成任务提醒");
            }
            if (completedReplyMessageList.size() > 4) {
                throw new WechatGroupBizException(WechatGroupBizException.ERROR, "至多填写3条完成任务提醒");
            }
        }
        BeanUtils.copyProperties(updateTaskItemDto, timeControlTaskItem);
        if (null == timeControlTaskItem.getFinishConfirm()) {
            timeControlTaskItem.setFinishConfirm(0);
        }
        if(null == timeControlTaskItem.getTdConfirm()){
            timeControlTaskItem.setTdConfirm(0);
        }
        if(null == timeControlTaskItem.getAddSendTime()){
            timeControlTaskItem.setAddSendTime(0);
        }
        if (null == timeControlTaskItem.getProgressGuidance()) {
            timeControlTaskItem.setProgressGuidance(0);
        }
        taskItemMapper.updateTaskItem(timeControlTaskItem);
        //删除原item下的配置
        replyMessageMapper.deleteByItemId(taskItemId);
        //重新插入
        List<TimeControlReplyMessage> list = new ArrayList<>();
        replyMessageList.forEach(message -> {
            TimeControlReplyMessage replyMessage = new TimeControlReplyMessage();
            BeanUtils.copyProperties(message, replyMessage);
            replyMessage.setTaskItemId(taskItemId);
            replyMessage.setTaskId(taskId);
            replyMessage.setType(0);
            list.add(replyMessage);
        });
        //任务完成回复消息list
        if(null!=updateTaskItemDto.getFinishConfirm() && updateTaskItemDto.getFinishConfirm()==1){
            List<TimeControlReplyMessage> messageList = new ArrayList<>();
            completedReplyMessageList.forEach(message -> {
                TimeControlReplyMessage replyMessage = new TimeControlReplyMessage();
                BeanUtils.copyProperties(message, replyMessage);
                replyMessage.setTaskItemId(taskItemId);
                replyMessage.setTaskId(taskId);
                replyMessage.setType(1);
                list.add(replyMessage);
            });
        }
        replyMessageMapper.batchInsert(list);
    }

    @Override
    public TaskItemDto getTaskItem(Integer id) {
        TaskItemDto taskItemDto = new TaskItemDto();
        TimeControlTaskItem timeControlTaskItem = taskItemMapper.selectByPrimaryKey(id);
        if (null == timeControlTaskItem) {
            return taskItemDto;
        }
        BeanUtils.copyProperties(timeControlTaskItem, taskItemDto);
        List<TimeControlReplyMessage> list = replyMessageMapper.list4TaskItem(id, 0);
        List<TimeControlReplyMessage> completeReplyMessageList = replyMessageMapper.list4TaskItem(id, 1);
        List<ReplyMessageDto> messageDtos = new ArrayList<>();
        if (!ListUtils.isEmpty(list)) {
            list.forEach(message -> {
                ReplyMessageDto replyMessageDto = new ReplyMessageDto();
                BeanUtils.copyProperties(message, replyMessageDto);
                messageDtos.add(replyMessageDto);
                if (ReplyTypeEnum.RESOURCE.value.equals(message.getReplyType())) {
                    Long resourceId = message.getResourceId();
                    Map<Long, ResourceDTO> map = resourceConsr.mapByIds(Arrays.asList(resourceId));
                    ResourceDTO resourceDTO = map.get(resourceId);
                    if (resourceDTO != null) {
                        replyMessageDto.setResourceName(resourceDTO.getResourceName());
                        replyMessageDto.setResourceUrl(resourceDTO.getFileUrl());
                        replyMessageDto.setFileType(resourceDTO.getFileType());
                        replyMessageDto.setFileSize(resourceDTO.getFileSize());
                        replyMessageDto.setResourceTypeCode(resourceDTO.getTypeCode());
                    }
                }
            });
        }
        taskItemDto.setReplyMessageList(messageDtos);
        //完成任务回复消息List
        List<ReplyMessageDto> completedMessageDtos = new ArrayList<>();
        if(!ListUtils.isEmpty(completeReplyMessageList)){
            completeReplyMessageList.forEach(message -> {
                ReplyMessageDto replyMessageDto = new ReplyMessageDto();
                BeanUtils.copyProperties(message, replyMessageDto);
                completedMessageDtos.add(replyMessageDto);
                if (ReplyTypeEnum.RESOURCE.value.equals(message.getReplyType())) {
                    Long resourceId = message.getResourceId();
                    Map<Long, ResourceDTO> map = resourceConsr.mapByIds(Arrays.asList(resourceId));
                    ResourceDTO resourceDTO = map.get(resourceId);
                    if (resourceDTO != null) {
                        replyMessageDto.setResourceName(resourceDTO.getResourceName());
                        replyMessageDto.setResourceUrl(resourceDTO.getFileUrl());
                        replyMessageDto.setFileType(resourceDTO.getFileType());
                        replyMessageDto.setFileSize(resourceDTO.getFileSize());
                        replyMessageDto.setResourceTypeCode(resourceDTO.getTypeCode());
                    }
                }
            });
        }
        taskItemDto.setCompletedReplyMessageList(completedMessageDtos);
        return taskItemDto;
    }

    @Override
    public List<ReplyMessageBaseDto> listTaskItemDay(Integer taskId) {
        return taskItemMapper.listTaskItemDay(taskId);
    }

    @Override
    public List<BookTaskBindingDto> listTask(String search) {
        List<BookTaskBindingDto> list = taskMapper.listTask(search);
        if (!ListUtils.isEmpty(list)) {
            // 封装标签 统计数据
            Set<Long> labelSet = new HashSet<>();
            // 获取所有标签 统一获取标签名称
            list.forEach(item -> {
                labelSet.add(item.getProLabelId());
                labelSet.add(item.getDepLabelId());
                labelSet.add(item.getPurLabelId());
            });

            labelSet.remove(null);
            if (labelSet.size() > 0) {
                // 批量获取标签名称
                ResponseEntity<ResponseDto<Map<Long, String>>> response = labelService.getLabelName(new ArrayList<>(labelSet));
                Map<Long, String> labelMap = ResponseHandleUtil.parseMap(response, Long.class, String.class);
                // 补充标签名称
                list.forEach(item -> {
                    item.setProLabelName(labelMap.get(item.getProLabelId()));
                    item.setDepLabelName(labelMap.get(item.getDepLabelId()));
                    item.setPurLabelName(labelMap.get(item.getPurLabelId()));
                });
            }
        }
        return list;
    }

    @Override
    public List<KeyWordTaskVO> listKeyWordTask() {
        return taskMapper.listKeyWordTask();
    }

    @Override
    public TaskDto getTaskByKey(String search, String wxUserId) {
        TaskDto taskByKey = taskMapper.getTaskByKey(search);
        if (taskByKey != null) {
            taskByKey.setSubscribeState(taskSubscribeBiz.getSubscribeState(wxUserId, taskByKey.getTaskId()).getState());
        }
        return taskByKey;
    }

    @Override
    public List<LabelDto> listMaxDepLabel(Integer num) {
        if (null == num) {
            num = 10;
        }
        List<Long> depLabelIds = taskMapper.listMaxDepLabel(num);
        List<LabelDto> list = new ArrayList<>();
        if (!ListUtils.isEmpty(depLabelIds)) {
            depLabelIds.forEach(depLabelId -> {
                LabelDto labelDto = new LabelDto();
                labelDto.setDepLabelId(depLabelId);
                String labelName = ResponseHandleUtil.parseResponse(labelService.getLabelName(depLabelId), String.class);
                labelDto.setDepLabelName(labelName);
                list.add(labelDto);
            });
        }
        return list;
    }

    @Override
    public List<TaskDto> listTaskByKey4User(String wxUserId, String search) {
        //1根据关键词去查询关联任务ID集合
        //List<Long> taskIds = ResponseHandleUtil.parseList(pcloudKeywordService.getTimePlanByGuideKeyword(search),Long.class);
        List<Long> taskIds = new ArrayList<>();
        List<TaskDto> taskDtoList = taskMapper.listTaskByKey4User(search, taskIds);
        if (!ListUtils.isEmpty(taskDtoList)) {
            //封装用户订阅状态
            taskDtoList.forEach(taskDto -> {
                taskDto.setSubscribeState(taskSubscribeBiz.getSubscribeState(wxUserId, taskDto.getTaskId()).getState());
            });
        }
        return taskDtoList;
    }

    @Override
    public List<TaskDto> listTaskByIds4User(String wxUserId, List<Integer> taskIds) {
        List<TaskDto> taskDtoList = taskMapper.listTaskByIds(taskIds);
        if (!ListUtils.isEmpty(taskDtoList)) {
            //封装用户订阅状态
            taskDtoList.forEach(taskDto -> {
                taskDto.setSubscribeState(taskSubscribeBiz.getSubscribeState(wxUserId, taskDto.getTaskId()).getState());
            });
        }
        return taskDtoList;
    }

    @Override
    public List<TaskDto> listTaskByLabelIds4User(String wxUserId, Long labelId) {
        List<TaskDto> taskDtoList = taskMapper.listTaskByLabelId(labelId);
        if (!ListUtils.isEmpty(taskDtoList)) {
            //封装用户订阅状态
            taskDtoList.forEach(taskDto -> {
                taskDto.setSubscribeState(taskSubscribeBiz.getSubscribeState(wxUserId, taskDto.getTaskId()).getState());
            });
        }
        return taskDtoList;
    }

    @Override
    @ParamLog
    @Transactional(rollbackFor = Exception.class)
    public void finishTaskSend(Integer taskSendId) {
        TimeControlTaskSend timeControlTaskSend = timeControlTaskSendMapper.getById(taskSendId);
        if (null == timeControlTaskSend) {
            return;
        }
        if (!(YesOrNoEnums.YES.getValue().equals(timeControlTaskSend.getWorking()) && YesOrNoEnums.NO.getValue().equals(timeControlTaskSend.getCompleteState()))){
            LOGGER.info("状态不对，不能完成任务");
            return;
        }
        Integer taskItemId = timeControlTaskSend.getTaskItemId();
        String wxUserId = timeControlTaskSend.getWxUserId();
        TimeControlTaskSubscribe timeControlTaskSubscribe = taskSubscribeMapper.getById(timeControlTaskSend.getSubscribeId());
        String robotWxId = timeControlTaskSubscribe.getRobotWxId();
        GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
        String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
        List<TimeControlReplyMessage> replyMessages = replyMessageMapper.list4TaskItem(taskItemId, 1);
        sendReplyMessage(replyMessages, wxUserId, robotWxId, ip);
        timeControlTaskSendMapper.updateSendState(taskSendId, TaskSendStateEnum.FINISH_SEND.getState(), 1);

        //每次都要判断一下是否所有单项任务都完成。完成之后需要同步修改关注表里面完成状态
        Integer noCompletedItem = timeControlTaskSendMapper.getNoCompletedCount(timeControlTaskSend.getSubscribeId());
        if(noCompletedItem==0){
            taskSubscribeMapper.completedTaskById(timeControlTaskSend.getSubscribeId());
        }
        new Thread(() -> {
            //处理奖励信息
            handlePrize(timeControlTaskSubscribe, ip, timeControlTaskSend.getTaskItemId());
        }).start();
    }

    private void handlePrize(TimeControlTaskSubscribe timeControlTaskSubscribe, String ip, Integer taskItemId) {
        LOGGER.info("开始处理奖励信息");
        //先判断有无单次奖励
        TimeControlTaskPrize taskPrize = taskPrizeMapper.getByTaskItemId(taskItemId);
        if (null != taskPrize) {
            if (taskPrize.getHasApp().equals(YesOrNoEnums.YES.getValue()) ||  taskPrize.getHasCoupon().equals(YesOrNoEnums.YES.getValue()) ||
                    taskPrize.getHasCertificate().equals(YesOrNoEnums.YES.getValue())) {
                List<TimeControlPrizeItem> timeControlPrizeItems = taskPrizeItemMapper.listByPrizeId(taskPrize.getId());
                if (!ListUtils.isEmpty(timeControlPrizeItems)) {
                    LOGGER.info("开始发送单次奖励");
                    timeControlPrizeItems.forEach(timeControlPrizeItem -> {
                        sendMessage(timeControlPrizeItem, ip, timeControlTaskSubscribe.getWxUserId(), timeControlTaskSubscribe.getRobotWxId());
                    });
                }
            }
        }
        Integer taskId = timeControlTaskSubscribe.getTaskId();
        //判断是否到大累计奖励
        Integer completedCount = timeControlTaskSendMapper.getCompletedCount(timeControlTaskSubscribe.getId());
        TimeControlTaskPrize byTaskId = taskPrizeMapper.getByTaskId(taskId, TaskPrizeTypeEnum.GRAND_TOTAL.key);
        if (byTaskId != null && completedCount.equals(byTaskId.getTotalPrizeNum())) {
            List<TimeControlPrizeItem> timeControlPrizeItems = taskPrizeItemMapper.listByPrizeId(byTaskId.getId());
            if (!ListUtils.isEmpty(timeControlPrizeItems)) {
                LOGGER.info("开始发送累计奖励");
                timeControlPrizeItems.forEach(timeControlPrizeItem -> {
                    sendMessage(timeControlPrizeItem, ip, timeControlTaskSubscribe.getWxUserId(), timeControlTaskSubscribe.getRobotWxId());
                });
            }
        }
    }

    private void sendMessage(TimeControlPrizeItem timeControlPrizeItem, String ip, String wxUserId, String robotWxId) {
        String groupId = UUID.randomUUID().toString();
        if (timeControlPrizeItem.getPrizeType() == 1) {
            //优惠券
            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
            sendTextMessageVO.setContent(timeControlPrizeItem.getCouponTitle() + "\n" + timeControlPrizeItem.getCouponUrl());
            sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
            sendTextMessageVO.setWxId(robotWxId);
            sendTextMessageVO.setAltId(robotWxId);
            sendTextMessageVO.setWxGroupId(wxUserId);
            sendTextMessageVO.setIp(ip);
            sendTextMessageVO.setIndex(0);
            sendTextMessageVO.setCounts(1);
            sendTextMessageVO.setMessageGroupId(groupId);
            sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
            wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));;
        } else if (timeControlPrizeItem.getPrizeType() == 2) {
            //应用
            if (AppAndProductTypeEnum.APP.value.equals(timeControlPrizeItem.getServeType())) {
                AppDto appDto = appConsr.getBaseById(timeControlPrizeItem.getServeId());
                if (appDto != null) {
                    AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(appDto.getChannelId());
                    // 处理链接地址
                    String endUrl = timeControlPrizeItem.getLinkUrl() + "&wxId=" + wxUserId + "&robotWxId=" + robotWxId;
                    String linkUrl = SendWeixinRequestTools.splitUrl(accountSettingDto, endUrl);
                    String resultUrl = UrlUtils.getShortUrl4Own(linkUrl);
                    SendArticleMessageVO sendArticleMessageVO = new SendArticleMessageVO();
                    sendArticleMessageVO.setCode(1);
                    sendArticleMessageVO.setAltId(robotWxId);
                    sendArticleMessageVO.setDescription(appDto.getTypeName());
                    sendArticleMessageVO.setWxGroupId(wxUserId);
                    sendArticleMessageVO.setLinkUrl(resultUrl);
                    sendArticleMessageVO.setPicUrl(appDto.getSquareImg());
                    sendArticleMessageVO.setTitle(appDto.getTitle());
                    sendArticleMessageVO.setIp(ip);
                    sendArticleMessageVO.setIndex(0);
                    sendArticleMessageVO.setCounts(1);
                    sendArticleMessageVO.setMessageGroupId(groupId);
                    sendArticleMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                    wechatGroupConsr.sendMessage(JSON.toJSONString(sendArticleMessageVO));
                }
            }
        } else if (timeControlPrizeItem.getPrizeType() == 3) {
            String s = taskPrizeBiz.downloadUrl(timeControlPrizeItem, wxUserId);
            if (null != s) {
                SendFileVO sendFileVO = new SendFileVO();
                sendFileVO.setFileUrl(s);
                sendFileVO.setFileName(DateUtils.today() + "-任务奖状" + ".jpg");
                sendFileVO.setIp(ip);
                sendFileVO.setAltId(robotWxId);
                sendFileVO.setWxId(wxUserId);
                sendFileVO.setIndex(0);
                sendFileVO.setCounts(1);
                sendFileVO.setMessageGroupId(groupId);
                sendFileVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                wechatGroupConsr.sendMessage(JSON.toJSONString(sendFileVO));
            }
        }
    }

    @Override
    public TaskDto getTaskByIdAndWxUserId(Integer relSkillId, String wxUserId) {
        return taskMapper.getTaskByIdAndWxUserId(relSkillId,wxUserId);
    }

    @Override
    public void sendReplyMessage(List<TimeControlReplyMessage> replyMessages, String wxUserId, String robotWxId, String ip) {
        String groupId = UUID.randomUUID().toString();
        int counts = replyMessages.size();
        if (!ListUtils.isEmpty(replyMessages)) {
            LOGGER.info("开始发送完成信息");
            for (int i = 0; i < replyMessages.size(); i++) {
                TimeControlReplyMessage replyMessage = replyMessages.get(i);
                if (replyMessage != null) {
                    Integer replyType = replyMessage.getReplyType();
                    if (ReplyTypeEnum.TEXT.value.equals(replyType)) {
                        // 发送文本
                        SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                        sendTextMessageVO.setContent(replyMessage.getContent());
                        sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                        sendTextMessageVO.setWxId(robotWxId);
                        sendTextMessageVO.setAltId(robotWxId);
                        sendTextMessageVO.setWxGroupId(wxUserId);
                        sendTextMessageVO.setIp(ip);
                        sendTextMessageVO.setIndex(i);
                        sendTextMessageVO.setCounts(counts);
                        sendTextMessageVO.setMessageGroupId(groupId);
                        sendTextMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                        wechatGroupConsr.sendMessage(JSON.toJSONString(sendTextMessageVO));;
                    } else if (ReplyTypeEnum.IMAGE.value.equals(replyType)) {
                        // 发送图片
                        SendPicMessageVO sendPicMessageVO = new SendPicMessageVO();
                        sendPicMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                        sendPicMessageVO.setAltId(robotWxId);
                        sendPicMessageVO.setWxGroupId(wxUserId);
                        sendPicMessageVO.setPicUrl(replyMessage.getPicUrl());
                        sendPicMessageVO.setIp(ip);
                        sendPicMessageVO.setIndex(i);
                        sendPicMessageVO.setCounts(counts);
                        sendPicMessageVO.setMessageGroupId(groupId);
                        sendPicMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                        wechatGroupConsr.sendMessage(JSON.toJSONString(sendPicMessageVO));
                    } else if (ReplyTypeEnum.APP.value.equals(replyType)) {
                        Long serveId = replyMessage.getServeId();
                        String completeLink = null;
                        if (AppAndProductTypeEnum.APP.value.equals(replyMessage.getServeType())) {
                            AppDto appDto = appConsr.getBaseById(serveId);
                            if (appDto != null) {
                                Long channelId = appDto.getChannelId();
                                AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(channelId);
                                // 处理链接地址
                                completeLink = ServeLinkUtils.getCompleteLink(replyMessage.getLinkUrl(), String.valueOf(accountSettingDto.getAccountSettingId()), accountSettingDto.getProtocol(),
                                        accountSettingDto.getDomain(), accountSettingDto.getFirstDomain(), String.valueOf(accountSettingDto.getRandom()));
                            }
                        } else {
                            completeLink = replyMessage.getLinkUrl();
                        }
                        SendArticleMessageVO sendArticleMessageVO = new SendArticleMessageVO();
                        sendArticleMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                        sendArticleMessageVO.setAltId(robotWxId);
                        sendArticleMessageVO.setDescription(replyMessage.getDescription());
                        sendArticleMessageVO.setWxGroupId(wxUserId);
                        completeLink = completeLink + "&wxId=" +wxUserId +"&robotWxId=" +robotWxId;
                        sendArticleMessageVO.setLinkUrl(completeLink);
                        sendArticleMessageVO.setPicUrl(replyMessage.getPicUrl());
                        sendArticleMessageVO.setTitle(replyMessage.getContent());
                        sendArticleMessageVO.setIp(ip);
                        sendArticleMessageVO.setIndex(i);
                        sendArticleMessageVO.setCounts(counts);
                        sendArticleMessageVO.setMessageGroupId(groupId);
                        sendArticleMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                        wechatGroupConsr.sendMessage(JSON.toJSONString(sendArticleMessageVO));
                    } else if (ReplyTypeEnum.RESOURCE.value.equals(replyType)) {
                        SendFileVO sendFileVO = new SendFileVO();
                        Map<Long, ResourceDTO> map = resourceConsr.mapByIds(Arrays.asList(replyMessage.getResourceId()));
                        ResourceDTO resourceDTO = map.get(replyMessage.getResourceId());
                        if (resourceDTO != null) {
                            sendFileVO.setFileUrl(resourceDTO.getFileUrl());
                            String fileName = resourceDTO.getResourceName();
                            String fileType = resourceDTO.getFileType();
                            log.info("fileName=" + fileName + "+fileType+" + fileType);
                            if (fileName.contains(fileType)) {//去掉后缀
                                fileName = fileName.substring(0, fileName.indexOf(fileType) - 1);
                            }
                            log.info("fileName=" + fileName);
                            sendFileVO.setFileName(fileName);
                        }
                        sendFileVO.setIp(ip);
                        sendFileVO.setAltId(robotWxId);
                        sendFileVO.setWxId(wxUserId);
                        sendFileVO.setCode(SendMessageTypeEnum.SELF.getCode());
                        sendFileVO.setIndex(i);
                        sendFileVO.setCounts(counts);
                        sendFileVO.setMessageGroupId(groupId);
                        sendFileVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                        wechatGroupConsr.sendMessage(JSON.toJSONString(sendFileVO));
                    }else if (ReplyTypeEnum.LINK.value.equals(replyType)) {
                        SendArticleMessageVO sendArticleMessageVO = new SendArticleMessageVO();
                        sendArticleMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                        sendArticleMessageVO.setAltId(robotWxId);
                        sendArticleMessageVO.setDescription(replyMessage.getDescription());
                        sendArticleMessageVO.setWxGroupId(wxUserId);
                        sendArticleMessageVO.setLinkUrl(replyMessage.getLinkUrl());
                        sendArticleMessageVO.setPicUrl(replyMessage.getPicUrl());
                        sendArticleMessageVO.setTitle(replyMessage.getContent());
                        sendArticleMessageVO.setIp(ip);
                        sendArticleMessageVO.setIndex(i);
                        sendArticleMessageVO.setCounts(counts);
                        sendArticleMessageVO.setMessageGroupId(groupId);
                        sendArticleMessageVO.setRobotProcessType(RobotProcessTypeEnum.TIME_CONTROL);
                        wechatGroupConsr.sendMessage(JSON.toJSONString(sendArticleMessageVO));
                    }
                }
            }
        }
    }

    @Override
    public Integer copyTaskItem(Integer taskItemId) {
        TimeControlTaskItem timeControlTaskItem = taskItemMapper.selectByPrimaryKey(taskItemId);
        if (null != timeControlTaskItem) {
            timeControlTaskItem.setId(null);
            timeControlTaskItem.setStartDay(timeControlTaskItem.getStartDay() + 1);
            taskItemMapper.insert(timeControlTaskItem);
            Integer newItemId = timeControlTaskItem.getId();
            List<TimeControlReplyMessage> list = replyMessageMapper.list4TaskItem(taskItemId,null);
            if (!ListUtils.isEmpty(list)) {
                list.forEach(replyMessage -> {
                    replyMessage.setTaskItemId(newItemId);
                });
                replyMessageMapper.batchInsert(list);
            }
            return newItemId;
        }
        return null;
    }

}
