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

import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.WeixinQrcodeBiz;
import com.pcloud.book.timecontrol.biz.TaskBiz;
import com.pcloud.book.timecontrol.biz.TaskSubscribeBiz;
import com.pcloud.book.timecontrol.dto.*;
import com.pcloud.book.timecontrol.entity.*;
import com.pcloud.book.timecontrol.mapper.*;
import com.pcloud.book.timecontrol.enums.TaskSendStateEnum;
import com.pcloud.book.timecontrol.vo.KeyWordTaskVO;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.labelcenter.label.service.LabelService;
import com.pcloud.wechatgroup.base.exception.WechatGroupBizException;
import lombok.extern.slf4j.Slf4j;
import com.pcloud.wechatgroup.group.dto.GroupRobotDTO;
import com.sdk.wxgroup.SendFileVO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendPicMessageVO;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;
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.*;

/**
 * @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 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;

    @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) {
        // 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()));
                });
            } 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);
        }
        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.setReplyType(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.setReplyType(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);
        }
        taskItemMapper.updateTtaskItem(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.setReplyType(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.setReplyType(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);
            });
        }
        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);
            });
        }
        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
    public void finishTaskSend(Integer taskSendId) {
        TimeControlTaskSend timeControlTaskSend = timeControlTaskSendMapper.getById(taskSendId);
        if (null == timeControlTaskSend) {
            return;
        }
        if (!TaskSendStateEnum.FINISH_SEND.getState().equals(timeControlTaskSend.getSendState())) {
            LOGGER.info("任务未完成");
        }
        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);
        if (!ListUtils.isEmpty(replyMessages)) {
            LOGGER.info("發送消息開始");
            for(TimeControlReplyMessage replyMessage : replyMessages) {
                if(replyMessage != null) {
                    switch (replyMessage.getMessageType()) {
                        case "text" :
                            // 发送文本
                            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                            sendTextMessageVO.setContent(replyMessage.getText());
                            sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                            sendTextMessageVO.setWxId(robotWxId);
                            sendTextMessageVO.setAltId(robotWxId);
                            sendTextMessageVO.setWxGroupId(wxUserId);
                            sendTextMessageVO.setIp(ip);
                            WxGroupSDK.sendTextMessage(sendTextMessageVO);
                            break;
                        case "img" :
                            // 发送图片
                            SendPicMessageVO sendPicMessageVO = new SendPicMessageVO();
                            sendPicMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                            sendPicMessageVO.setAltId(timeControlTaskSubscribe.getRobotWxId());
                            sendPicMessageVO.setWxGroupId(wxUserId);
                            sendPicMessageVO.setPicUrl(replyMessage.getImgUrl());
                            sendPicMessageVO.setIp(ip);
                            WxGroupSDK.sendPicMessage(sendPicMessageVO);
                            break;
                        case "file" :
                            // 发送文件
                            SendFileVO sendFileVO = new SendFileVO();
                            sendFileVO.setFileUrl(replyMessage.getFileUrl());
                            sendFileVO.setFileName(replyMessage.getFileName());
                            sendFileVO.setIp(ip);
                            sendFileVO.setAltId(robotWxId);
                            sendFileVO.setWxId(wxUserId);
                            WxGroupSDK.sendFile(sendFileVO);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        timeControlTaskSendMapper.updateSendState(taskSendId, TaskSendStateEnum.FINISH_SEND.getState(), 1);

        //每次都要判断一下是否所有单项任务都完成。完成之后需要同步修改关注表里面完成状态
        Integer noCompletedItem = timeControlTaskSendMapper.getNoCompletedCount(timeControlTaskSend.getSubscribeId());
        if(noCompletedItem==0){
            taskSubscribeMapper.completedTaskById(timeControlTaskSend.getSubscribeId());
        }
    }

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