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

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.WeixinQrcodeBiz;
import com.pcloud.book.group.dto.UserSelectParamDTO;
import com.pcloud.book.group.set.GroupSet;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotBiz;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotClassifyBiz;
import com.pcloud.book.pcloudkeyword.entity.PcloudRobot;
import com.pcloud.book.pcloudkeyword.entity.PcloudRobotClassify;
import com.pcloud.book.timecontrol.biz.SelfPlanBiz;
import com.pcloud.book.timecontrol.dto.SelfPlanUserDto;
import com.pcloud.book.timecontrol.entity.TimeControlReplyMessage;
import com.pcloud.book.timecontrol.entity.TimeControlSelfPlan;
import com.pcloud.book.timecontrol.entity.TimeControlSelfPlanFeedback;
import com.pcloud.book.timecontrol.entity.TimeControlSelfPlanItem;
import com.pcloud.book.timecontrol.entity.TimeControlTask;
import com.pcloud.book.timecontrol.entity.TimeControlTaskItem;
import com.pcloud.book.timecontrol.enums.FeedbackTypeEnum;
import com.pcloud.book.timecontrol.enums.ServiceStateEnum;
import com.pcloud.book.timecontrol.mapper.TimeControlReplyMessageMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlSelfPlanFeedbackMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlSelfPlanItemMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlSelfPlanMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskItemMapper;
import com.pcloud.book.timecontrol.mapper.TimeControlTaskMapper;
import com.pcloud.book.timecontrol.vo.AddTask4SelfPlan;
import com.pcloud.book.timecontrol.vo.CreateSelfPlanVO;
import com.pcloud.book.timecontrol.vo.SelfPlanVO;
import com.pcloud.book.timecontrol.vo.UpdateSelfPlanVO;
import com.pcloud.book.util.common.ThreadPoolUtils;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.biz.MessageBiz;
import com.pcloud.common.core.dto.SendEmailDto;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.wechatgroup.group.dto.GroupRobotDTO;
import com.pcloud.wechatgroup.group.dto.GroupUserDTO;
import com.sdk.wxgroup.SendMessageTypeEnum;
import com.sdk.wxgroup.SendTextMessageVO;
import org.apache.commons.lang.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 org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Component
public class SelfPlanBizImpl implements SelfPlanBiz {

    @Autowired
    private TimeControlSelfPlanItemMapper selfPlanItemMapper;
    @Autowired
    private TimeControlSelfPlanFeedbackMapper selfPlanFeedbackMapper;
    @Autowired
    private TimeControlSelfPlanFeedbackMapper timeControlSelfPlanFeedbackMapper;

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

    @Autowired
    private TimeControlSelfPlanMapper timeControlSelfPlanMapper;
    @Autowired
    private TimeControlTaskMapper taskMapper;
    @Autowired
    private TimeControlTaskItemMapper taskItemMapper;
    @Autowired
    private TimeControlReplyMessageMapper replyMessageMapper;
    @Autowired
    private PcloudRobotBiz pcloudRobotBiz;
    @Autowired
    private WechatGroupConsr wechatGroupConsr;
    @Autowired
    private GroupSet groupSet;
    @Autowired
    private WeixinQrcodeBiz weixinQrcodeBiz;
    @Autowired
    private PcloudRobotClassifyBiz pcloudRobotClassifyBiz;
    @Autowired
    private MessageBiz messageBiz;
    @Value("${self.plan.feedback.email}")
    private String selfPlanFeedbackEmail;

    @Override
    @ParamLog
    public Integer createSelfPlan(CreateSelfPlanVO createSelfPlanVO) {
        TimeControlSelfPlan timeControlSelfPlan = new TimeControlSelfPlan();
        timeControlSelfPlan.setWxId(createSelfPlanVO.getWxId());
        timeControlSelfPlan.setRobotWxId(createSelfPlanVO.getRobotWxId());
        timeControlSelfPlanMapper.insert(timeControlSelfPlan);
        //更新单号
        String id = String.valueOf(timeControlSelfPlan.getId());
        String s = StringUtils.leftPad(id, 6, "0");
        String date = DateUtils.formatDate(new Date(), "yyyyMMdd");
        timeControlSelfPlanMapper.updatePlanOrder(timeControlSelfPlan.getId(), date + s);
        return timeControlSelfPlan.getId();
    }



    @Override
    public void addTask4SelfPlan(AddTask4SelfPlan addTask4SelfPlan) {
        Integer taskId = addTask4SelfPlan.getTaskId();
        Integer planId = addTask4SelfPlan.getPlanId();
        TimeControlSelfPlan timeControlSelfPlan = timeControlSelfPlanMapper.getById(planId);
        if (null == timeControlSelfPlan) {
            throw new BookBizException(BookBizException.ERROR, "服务不存在！");
        }
        TimeControlTask timeControlTask = taskMapper.selectByPrimaryKey(taskId);
        timeControlTask.setTaskId(null);
        //新增任务
        taskMapper.insert(timeControlTask);
        Integer newTaskId = timeControlTask.getTaskId();
        //新增任务item
        List<TimeControlTaskItem> list = taskItemMapper.listByTaskId(taskId);
        if (!ListUtils.isEmpty(list)) {
            list.forEach(item -> {
                Integer oldItemId = item.getId();
                List<TimeControlReplyMessage> timeControlReplyMessages = replyMessageMapper.list4TaskItem(oldItemId, null);
                item.setTaskId(newTaskId);
                taskItemMapper.insert(item);
                Integer newItemId = item.getId();
                if (!ListUtils.isEmpty(timeControlReplyMessages)) {
                    timeControlReplyMessages.forEach(replyMessage -> {
                        replyMessage.setTaskId(newTaskId);
                        replyMessage.setTaskItemId(newItemId);
                    });
                    replyMessageMapper.batchInsert(timeControlReplyMessages);
                }
            });
        }
        timeControlSelfPlanMapper.bindTask(planId, newTaskId);
    }

    @Override
    public PageBeanNew<SelfPlanVO> listSelfPlan(Integer currentPage, Integer numPerPage, Integer serviceState) {
        int count = timeControlSelfPlanMapper.getSelfPlanCount(serviceState);
        if (count <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        List<SelfPlanVO> list = timeControlSelfPlanMapper.listSelfPlan(currentPage * numPerPage, numPerPage, serviceState);
        if (!ListUtils.isEmpty(list)) {
            List<String> collect = list.stream().map(SelfPlanVO::getWxId).distinct().collect(Collectors.toList());
            Map<String, GroupUserDTO> stringGroupUserDTOMap = wechatGroupConsr.mapWxUserInfoByWxIdList(collect);
            list.forEach(selfPlanVO -> {
                //封装数据
                String robotWxId = selfPlanVO.getRobotWxId();
                PcloudRobot pcloudRobotByWxId = pcloudRobotBiz.getPcloudRobotByWxId(robotWxId);
                if (null != pcloudRobotByWxId) {
                    selfPlanVO.setRobotType(pcloudRobotByWxId.getRobotType());
                    selfPlanVO.setUniqueNumber(pcloudRobotByWxId.getUniqueNumber());
                    PcloudRobotClassify classifyById = pcloudRobotClassifyBiz.getClassifyById(Long.valueOf(pcloudRobotByWxId.getRobotType()));
                    selfPlanVO.setClassifyName(classifyById.getClassifyName());
                }
                String wxId = selfPlanVO.getWxId();
                if (stringGroupUserDTOMap != null) {
                    GroupUserDTO groupUserDTO = stringGroupUserDTOMap.get(wxId);
                    if (groupUserDTO != null){
                        selfPlanVO.setHeadUrl(groupUserDTO.getHeadPic());
                        selfPlanVO.setNickName(groupUserDTO.getNickName());
                    }
                }
                List<TimeControlSelfPlanFeedback> timeControlSelfPlanFeedbacks =timeControlSelfPlanFeedbackMapper.getFeedbackByPlan(selfPlanVO.getPlanId(),FeedbackTypeEnum.FEEDBACK.value);
                if (ListUtils.isEmpty(timeControlSelfPlanFeedbacks)){
                    selfPlanVO.setFeedbackState(0);
                }else {
                    selfPlanVO.setFeedbackState(1);
                }
                List<TimeControlSelfPlanFeedback> feedbacks4Evaluate = timeControlSelfPlanFeedbackMapper.getFeedbackByPlan(selfPlanVO.getPlanId(),FeedbackTypeEnum.SERVICE_EVALUATE.value);
                if (!ListUtils.isEmpty(feedbacks4Evaluate)){
                    selfPlanVO.setTimeControlSelfPlanFeedback4Evaluate(feedbacks4Evaluate.get(0));
                }
            });
        }
        return new PageBeanNew<>(currentPage, numPerPage, count, list);
    }

    @Override
    public void deleteSelfPlan(Integer planId) {
        TimeControlSelfPlan plan = timeControlSelfPlanMapper.getById(planId);
        if (null != plan){
            if (ServiceStateEnum.FINISH_BUY.getValue().equals(plan.getServiceState())) {
                throw new BookBizException(BookBizException.ERROR, "已购买无法删除！");
            }
            if (ServiceStateEnum.FINISH_SUBSCRIBE.getValue().equals(plan.getServiceState())) {
                throw new BookBizException(BookBizException.ERROR, "已订阅无法删除！");
            }
            timeControlSelfPlanMapper.deleteById(planId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editSelfPlanItems(List<TimeControlSelfPlanItem> selfPlanItemList) {
        Integer planId = selfPlanItemList.get(0).getSelfPlanId();
        selfPlanItemMapper.deleteByPlanId(planId);
        selfPlanItemMapper.batchInsert(selfPlanItemList);
        TimeControlSelfPlan plan = timeControlSelfPlanMapper.getById(planId);
        if(plan != null) {
            plan.setUpdateTime(new Date());
            timeControlSelfPlanMapper.update(plan);
            if(plan.getHasClickPlan() == 1) {
                ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
                    String robotWxId = plan.getRobotWxId();
                    String userWxId = plan.getWxId();
                    GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
                    String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
                    SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
                    sendTextMessageVO.setContent(plan.getChangeReply());
                    sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
                    sendTextMessageVO.setWxId(robotWxId);
                    sendTextMessageVO.setAltId(robotWxId);
                    sendTextMessageVO.setWxGroupId(userWxId);
                    sendTextMessageVO.setIp(ip);
                    //WxGroupSDK.sendTextMessage(sendTextMessageVO);
                });
            }
        }
    }

    @Override
    public List<TimeControlSelfPlanItem> getSelfPlanItems(Integer planId) {
        return selfPlanItemMapper.getByPlanId(planId);
    }

    @Override
    public List<TimeControlSelfPlanItem> getSelfPlanItems4Wechat(Integer planId) {
        List<TimeControlSelfPlanItem> list = selfPlanItemMapper.getByPlanId(planId);
        timeControlSelfPlanMapper.updateHasClickPlan(planId);
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commitFeedback(List<TimeControlSelfPlanFeedback> selfPlanFeedbackList) {
        if(CollectionUtils.isEmpty(selfPlanFeedbackList)) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数缺失！");
        }
        String feedbackContent = "<br/>";
        Integer planId = selfPlanFeedbackList.get(0).getSelfPlanId();
        if(planId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "方案ID缺失！");
        }
        TimeControlSelfPlan plan = timeControlSelfPlanMapper.getById(planId);
        if(plan == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "该服务不存在！");
        }
        int index = 1;
        for(TimeControlSelfPlanFeedback planFeedback : selfPlanFeedbackList) {
            planFeedback.setRobotWxId(plan.getRobotWxId());
            planFeedback.setWxId(plan.getWxId());
            planFeedback.setFeedbackType(FeedbackTypeEnum.FEEDBACK.value);
            feedbackContent = feedbackContent + index++ + "、" + planFeedback.getContent() + "<br/>";
        }
        selfPlanFeedbackMapper.batchInsert(selfPlanFeedbackList);
        //发邮件
        String finalFeedbackContent = feedbackContent;
        ThreadPoolUtils.OTHER_THREAD_POOL.execute(() -> {
            String robotWxId = plan.getRobotWxId();
            String userWxId = plan.getWxId();
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("robotWxId", robotWxId);
            paramMap.put("userWxId", userWxId);
            paramMap.put("content", finalFeedbackContent);
            paramMap.put("time", DateUtils.getLongDateStr());
            PcloudRobot pcloudRobot = pcloudRobotBiz.getPcloudRobotByWxId(robotWxId);
            if(pcloudRobot != null) {
                paramMap.put("number", StringUtil.isEmpty(pcloudRobot.getUniqueNumber()) ? "未知" : pcloudRobot.getUniqueNumber());
                PcloudRobotClassify classify = pcloudRobotClassifyBiz.getClassifyById(pcloudRobot.getRobotType().longValue());
                paramMap.put("classifyName", classify == null ? "未知" : classify.getClassifyName());
            }
            GroupUserDTO userDTO = wechatGroupConsr.getWxUserInfoByWxUserId(userWxId);
            paramMap.put("nickName", userDTO == null ? "未知" : userDTO.getNickName());
            SendEmailDto sendEmailDto = new SendEmailDto();
            sendEmailDto.setToEmail(selfPlanFeedbackEmail);
            sendEmailDto.setTypeCode("self_plan_feedback_email");
            sendEmailDto.setContent(paramMap);
            messageBiz.sendEmail(sendEmailDto);
        });
    }

    @Override
    public List<TimeControlSelfPlanFeedback> getFeedbackByPlan(Integer planId) {
        return selfPlanFeedbackMapper.getFeedbackByPlan(planId, FeedbackTypeEnum.FEEDBACK.value);
    }

    @Override
    public void commitEvaluate(TimeControlSelfPlanFeedback selfPlanFeedback) {
        Integer planId = selfPlanFeedback.getSelfPlanId();
        if(planId == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数缺失！");
        }
        TimeControlSelfPlan plan = timeControlSelfPlanMapper.getById(planId);
        if(plan == null) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "该服务不存在！");
        }
        selfPlanFeedback.setRobotWxId(plan.getRobotWxId());
        selfPlanFeedback.setWxId(plan.getWxId());
        selfPlanFeedback.setFeedbackType(FeedbackTypeEnum.SERVICE_EVALUATE.value);
        selfPlanFeedbackMapper.insert(selfPlanFeedback);
    }

    @Override
    @ParamLog(value = "个性化定制-用户列表查询",isAfterReturn = false)
    public PageBeanNew<SelfPlanUserDto> listUser4SelfPlan(UserSelectParamDTO userSelectParamDTO) {
        Integer currentPage = userSelectParamDTO.getCurrentPage();
        Integer numPerPage = userSelectParamDTO.getNumPerPage();
        Map<String, Object> map = new HashMap<>();
        //判断robotid是否是小睿
        String robotId = userSelectParamDTO.getRobotId();
        List<SelfPlanUserDto> list = new ArrayList<>();
        Integer totalCount = 0;
        if (StringUtil.isEmpty(robotId)) {
            throw new BizException(BizException.PARAM_IS_NULL.getCode(), "robotId为空");
        }
        PcloudRobot pcloudRobot = pcloudRobotBiz.getPcloudRobotByWxId(robotId);
        if (null != pcloudRobot) {
            PageBeanNew<String> wechatUserIdPage = wechatGroupConsr.listPageFriend(currentPage, numPerPage,
                    robotId, userSelectParamDTO.getUserQuery());
            if (!ListUtils.isEmpty(wechatUserIdPage.getRecordList())) {
                List<String> wechatUserIds = wechatUserIdPage.getRecordList();
                Map<String, SelfPlanUserDto> selfPlanUserDtoMap = timeControlSelfPlanMapper.getSelfPlanUserDtoMap(wechatUserIds);
                list = groupSet.setUserInfo4SelfPlan4XIAORUI(wechatUserIds, selfPlanUserDtoMap);
                totalCount = wechatUserIdPage.getTotalCount();
            }
        }
        return new PageBeanNew<>(currentPage, numPerPage, totalCount, list);
    }

    @Override
    @ParamLog
    public void payBack(Integer planId) {
        TimeControlSelfPlan timeControlSelfPlan = timeControlSelfPlanMapper.getById(planId);
        if (null == timeControlSelfPlan) {
            LOGGER.info("计划不存在，直接返回!");
            return;
        }
        if (ServiceStateEnum.FINISH_BUY.getValue().equals(timeControlSelfPlan.getServiceState())){
            LOGGER.info("以购买，直接返回");
            return;
        }
        timeControlSelfPlan.setServiceState(ServiceStateEnum.FINISH_BUY.getValue());
        timeControlSelfPlanMapper.updateServiceState(timeControlSelfPlan);
        if (null != timeControlSelfPlan.getBuyReply()) {
            //发送购买return
            String wxId = timeControlSelfPlan.getWxId();
            String robotWxId = timeControlSelfPlan.getRobotWxId();
            GroupRobotDTO groupRobotDTO = wechatGroupConsr.getGroupRobotByWxId(robotWxId);
            String ip = weixinQrcodeBiz.getRobotIpByGeneration(groupRobotDTO.getVersion());
            SendTextMessageVO sendTextMessageVO = new SendTextMessageVO();
            sendTextMessageVO.setContent(timeControlSelfPlan.getBuyReply());
            sendTextMessageVO.setCode(SendMessageTypeEnum.SELF.getCode());
            sendTextMessageVO.setWxId(robotWxId);
            sendTextMessageVO.setAltId(robotWxId);
            sendTextMessageVO.setWxGroupId(wxId);
            sendTextMessageVO.setIp(ip);
            //WxGroupSDK.sendTextMessage(sendTextMessageVO);
        }
    }

    @Override
    public void advancedSetting(TimeControlSelfPlan timeControlSelfPlan) {
        checkParam4AdvancedSetting(timeControlSelfPlan);
        timeControlSelfPlanMapper.advancedSetting(timeControlSelfPlan);
    }

    @Override
    public void updateSelfPlan(UpdateSelfPlanVO updateSelfPlanVO) {
        timeControlSelfPlanMapper.updateSelfPlan(updateSelfPlanVO);
    }

    @Override
    public TimeControlSelfPlan getSelfPlanById(Integer planId) {
        TimeControlSelfPlan timeControlSelfPlan = timeControlSelfPlanMapper.getById(planId);
        String robotId = timeControlSelfPlan.getRobotWxId();
        PcloudRobot pcloudRobot = pcloudRobotBiz.getPcloudRobotByWxId(robotId);
        if (null != pcloudRobot){
            timeControlSelfPlan.setClassifyId(pcloudRobot.getRobotType());
            PcloudRobotClassify pcloudRobotClassify =  pcloudRobotClassifyBiz.getClassifyById(Long.valueOf(pcloudRobot.getRobotType().toString()));
            if (null != pcloudRobotClassify){
                timeControlSelfPlan.setClassifyName(pcloudRobotClassify.getClassifyName());
            }
        }
        return timeControlSelfPlan;
    }

    @Override
    public PageBeanNew<TimeControlSelfPlanFeedback> getFeedbackPage(Integer planId, Integer currentPage, Integer numPerPage) {
        Integer totalCount  = timeControlSelfPlanFeedbackMapper.listFeedbackCount(planId);
        if (totalCount <= 0) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        List<TimeControlSelfPlanFeedback> timeControlSelfPlanFeedbacks = timeControlSelfPlanFeedbackMapper.listFeedback(planId,
                currentPage * numPerPage,numPerPage);
        return new PageBeanNew<>(currentPage, numPerPage, totalCount, timeControlSelfPlanFeedbacks);
    }

    @Override
    public TimeControlSelfPlan getLatestPlan(String wxId, Integer planId) {
        if (null != planId) {
            return timeControlSelfPlanMapper.getById(planId);
        }
        TimeControlSelfPlan timeControlSelfPlan = timeControlSelfPlanMapper.getLatestPlan(wxId);
        return timeControlSelfPlan;
    }

    private void checkParam4AdvancedSetting(TimeControlSelfPlan timeControlSelfPlan) {
        if (null == timeControlSelfPlan){
            throw new BizException(BizException.PARAM_IS_NULL.getCode(), "timeControlSelfPlan为空");
        }
        if (null == timeControlSelfPlan.getTotalPrice()){
            throw new BizException(BizException.PARAM_IS_NULL.getCode(), "总价不能为空");
        }
        if (StringUtil.isEmpty(timeControlSelfPlan.getBuyReply())){
            throw new BizException(BizException.PARAM_IS_NULL.getCode(), "购买后返回方案不能为空");
        }
        if (StringUtil.isEmpty(timeControlSelfPlan.getChangeReply())){
            throw new BizException(BizException.PARAM_IS_NULL.getCode(), "订阅后返回方案不能为空");
        }
    }

}
