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

import com.alibaba.fastjson.JSONObject;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.guide.biz.PcloudRobotWakeUpBiz;
import com.pcloud.book.guide.dto.WakeUpInfoDto;
import com.pcloud.book.guide.entity.PcloudRobotWakeup;
import com.pcloud.book.guide.entity.PcloudWakeupMessage;
import com.pcloud.book.guide.mapper.PcloudRobotWakeupMapper;
import com.pcloud.book.guide.mapper.PcloudWakeupMessageMapper;
import com.pcloud.book.guide.vo.ClassifyInfoVO;
import com.pcloud.book.guide.vo.RobotWakeUpConfigVO;
import com.pcloud.book.guide.vo.RobotWakeUpMsgVO;
import com.pcloud.book.guide.vo.RobotWakeUpShowVO;
import com.pcloud.book.pcloudkeyword.biz.PcloudRobotBiz;
import com.pcloud.book.pcloudkeyword.dao.PcloudRobotDao;
import com.pcloud.book.pcloudkeyword.entity.PcloudRobot;
import com.pcloud.book.pcloudkeyword.facade.response.PcloudRobotClassifyResponseVO;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.facade.quartz.entity.CallBackParam;
import com.pcloud.facade.quartz.entity.ScheduleJob;
import com.pcloud.facade.quartz.service.ScheduleService;
import com.sdk.wxgroup.SendFileVO;
import com.sdk.wxgroup.SendPicMessageVO;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.JsonParseException;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

import static com.pcloud.book.guide.constant.PcloudGuideRedisConstant.*;

@Component("pcloudRobotWakeUpBiz")
@Slf4j
public class PcloudRobotWakeUpBizImpl implements PcloudRobotWakeUpBiz {

    @Autowired
    private PcloudRobotWakeupMapper pcloudRobotWakeupMapper;

    @Autowired
    private PcloudRobotDao pcloudRobotDao;

    @Autowired
    private PcloudWakeupMessageMapper pcloudWakeupMessageMapper;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private PcloudRobotBiz pcloudRobotBiz;

    @Override
    public void robotWakeUpConfig(RobotWakeUpConfigVO robotWakeUpConfigVO) {
        Integer cycle = robotWakeUpConfigVO.getCycle();
        if (cycle == null || cycle < 1) {
            cycle = 1;
        }
        Integer lastDay = robotWakeUpConfigVO.getLastDay();
        if (lastDay == 1) {
            lastDay = 3;
        } else if (lastDay == 2) {
            lastDay = 7;
        } else if (lastDay == 3) {
            lastDay = DateUtils.getDayOfMonth(new Date());
        }
        PcloudRobotWakeup pcloudRobotWakeup = new PcloudRobotWakeup();
        pcloudRobotWakeup.setCreateTime(new Date());
        pcloudRobotWakeup.setCycle(cycle);
        pcloudRobotWakeup.setLast(lastDay);
        pcloudRobotWakeup.setStartTime(new Date());
        pcloudRobotWakeupMapper.insertSelective(pcloudRobotWakeup);

        List<Integer> classifyList = robotWakeUpConfigVO.getClassifyList();
        pcloudRobotDao.updateWakeUpByClassifyIds(classifyList);

        // 删除旧有消息配置
        pcloudWakeupMessageMapper.deleteAll();
        List<RobotWakeUpMsgVO> list = robotWakeUpConfigVO.getMsgVOList();
        if (list.size() > 3) {
            throw new BookBizException(BookBizException.PARAM_IS_ERROR, "最多配置三条消息");
        }

        for (RobotWakeUpMsgVO robotWakeUpMsgVO : list) {
            PcloudWakeupMessage pcloudWakeupMessage = new PcloudWakeupMessage();
            pcloudWakeupMessage.setCreateTime(new Date());
            if (robotWakeUpMsgVO.getReplyType() == 1) {
                pcloudWakeupMessage.setType("text");
                pcloudWakeupMessage.setTextContent(robotWakeUpMsgVO.getContent());
            } else if (robotWakeUpMsgVO.getReplyType() == 2) {
                pcloudWakeupMessage.setType("image");
                pcloudWakeupMessage.setImgUrl(robotWakeUpMsgVO.getPicUrl());
            } else if (robotWakeUpMsgVO.getReplyType() == 5) {
                String code = StringUtil.isEmpty(robotWakeUpMsgVO.getResourceTypeCode()) ? " " : robotWakeUpMsgVO.getResourceTypeCode();
                String size = StringUtil.isEmpty(robotWakeUpMsgVO.getSize()) ? " " : robotWakeUpMsgVO.getSize();
                List<String> infos = new ArrayList<>();
                infos.add(code);
                infos.add(size);
                pcloudWakeupMessage.setType("file");
                pcloudWakeupMessage.setTextContent(JSONObject.toJSONString(infos));
                pcloudWakeupMessage.setFileUrl(robotWakeUpMsgVO.getFileUrl());
                pcloudWakeupMessage.setFileName(robotWakeUpMsgVO.getContent());
            }
            pcloudWakeupMessage.setSeqNum(robotWakeUpMsgVO.getSeqNum());
            pcloudWakeupMessage.setId(null);
            pcloudWakeupMessageMapper.insertSelective(pcloudWakeupMessage);
        }

        String cron = "0 0 0/$ * * ? ";
        cron = cron.replace("$", String.valueOf(cycle));
        createCronJob(cron);

    }

    private void createCronJob(String cronStr) {
        try {
            scheduleService.deleteJob(PCLOUD_WAKE_UP_CRON_JOB, "book");
            ScheduleJob job = new ScheduleJob();
            //定时器任务
            job.setJobName(PCLOUD_WAKE_UP_CRON_JOB);
            //cron表达式
            job.setCronExpression(cronStr);
            //定时器分组
            job.setJobGroup("book");
            CallBackParam param = new CallBackParam();
            //service名称
            param.setBeanName("pcloudRobotWakeUpService");
            //回调内部接口方法名称
            param.setMethodName("doJob");

            //设置回调参数
            Map<String, Object> map = new HashMap<>();
            map.put("jobName", PCLOUD_WAKE_UP_CRON_JOB);
            param.setParamMap(map);
            Map<String, Object> scheduleMap = new HashMap<>();
            scheduleMap.put("scheduleJob", job);
            scheduleMap.put("callBackParam", param);
            scheduleService.addCronJob(scheduleMap);
        } catch (SchedulerException | JsonParseException e) {
            log.info("【PcloudRobotWakeUpBizImpl.createCronJob】创建定时任务失败", e);
        }
    }

    @Override
    public void robotWakeUpRemove() {
        pcloudRobotWakeupMapper.deleteAll();
        pcloudWakeupMessageMapper.deleteAll();
        pcloudRobotDao.clearWakeUp();
        try {
            scheduleService.deleteJob(PCLOUD_WAKE_UP_CRON_JOB, "book");
        } catch (SchedulerException | JsonParseException e) {
            log.info("【PcloudRobotWakeUpBizImpl.robotWakeUpRemove】删除定时任务失败", e);
        }
    }

    @Override
    public RobotWakeUpShowVO getRobotWakeUpConfig() {
        RobotWakeUpShowVO robotWakeUpShowVO = new RobotWakeUpShowVO();
        // 配置信息
        PcloudRobotWakeup pcloudRobotWakeup = pcloudRobotWakeupMapper.selectOne();
        if (pcloudRobotWakeup == null) {
            return robotWakeUpShowVO;
        }
        robotWakeUpShowVO.setCycle(pcloudRobotWakeup.getCycle());
        Integer last = pcloudRobotWakeup.getLast();
        if (last == 3) {
            last = 1;
        } else if (last == 7) {
            last = 2;
        } else {
            last = 3;
        }
        robotWakeUpShowVO.setLastDay(last);

        robotWakeUpShowVO.setStartTime(pcloudRobotWakeup.getStartTime());
        // 分类信息
        List<Integer> classifyInfoVOList = pcloudWakeupMessageMapper.getAllClassifyInfo();
        robotWakeUpShowVO.setClassifyList(classifyInfoVOList);
        // 消息列表
        List<PcloudWakeupMessage> list = pcloudWakeupMessageMapper.selectAll();
        List<RobotWakeUpMsgVO> robotWakeUpMsgVOList = new ArrayList<>();
        for (PcloudWakeupMessage pcloudWakeupMessage : list) {
            RobotWakeUpMsgVO robotWakeUpMsgVO = new RobotWakeUpMsgVO();
            robotWakeUpMsgVO.setSeqNum(pcloudWakeupMessage.getSeqNum());
            robotWakeUpMsgVO.setId(pcloudWakeupMessage.getId());
            if ("text".equals(pcloudWakeupMessage.getType())) {
                robotWakeUpMsgVO.setReplyType(1);
                robotWakeUpMsgVO.setContent(pcloudWakeupMessage.getTextContent());
            } else if ("image".equals(pcloudWakeupMessage.getType())) {
                robotWakeUpMsgVO.setReplyType(2);
                robotWakeUpMsgVO.setPicUrl(pcloudWakeupMessage.getImgUrl());
            } else if ("file".equals(pcloudWakeupMessage.getType())) {
                List<String> array = JSONObject.parseArray(pcloudWakeupMessage.getTextContent(), String.class);
                if (array.size() > 1) {
                    robotWakeUpMsgVO.setResourceTypeCode(array.get(0));
                    robotWakeUpMsgVO.setSize(array.get(1));
                }
                robotWakeUpMsgVO.setReplyType(5);
                robotWakeUpMsgVO.setContent(pcloudWakeupMessage.getFileName());
                robotWakeUpMsgVO.setFileUrl(pcloudWakeupMessage.getFileUrl());
            }
            robotWakeUpMsgVOList.add(robotWakeUpMsgVO);
        }


        robotWakeUpShowVO.setMsgList(robotWakeUpMsgVOList);
        return robotWakeUpShowVO;
    }

    @Override
    public void doJob() {
        // 1. 查询所有开启自动提醒的小号
        List<String> allRobot = pcloudRobotWakeupMapper.listAllRobot();
        // 2. 查询提醒时间
        PcloudRobotWakeup pcloudRobotWakeup = pcloudRobotWakeupMapper.selectOne();
        if (pcloudRobotWakeup == null || pcloudRobotWakeup.getLast() == null) {
            return;
        }
        List<PcloudWakeupMessage> list = pcloudWakeupMessageMapper.selectAll();
        if (ListUtils.isEmpty(list)) {
            return;
        }
        log.info("[开始自动唤醒 推送消息] msg: {}", JSONObject.toJSONString(list));

        for (String robot : allRobot) {
            Map<String, String> userInfo = JedisClusterUtils.hgetAll(robot + PCLOUD_ROBOT_WAKE_UP_SUFFIX);
            if (userInfo.isEmpty()) {
                return;
            }
            Set<String> wxids = userInfo.keySet();
            if (wxids.isEmpty()) {
                return;
            }
            for (String wxid : wxids) {
                WakeUpInfoDto dto = JSONObject.parseObject(userInfo.get(wxid), WakeUpInfoDto.class);
                Date date = dto.getTime();
                String ip = dto.getIp();
                if (DateUtils.getDateDiff(date, new Date()) > pcloudRobotWakeup.getLast()) {
                    //修改全局订阅状态
                    pcloudRobotBiz.updateUserTdState(robot, wxid, 0);
                    for (PcloudWakeupMessage msg : list) {
                        if ("text".equals(msg.getType())) {
                            SendTextMessageVO txt = new SendTextMessageVO();
                            txt.setAltId(robot);
                            txt.setContent(msg.getTextContent());
                            txt.setWxGroupId(wxid);
                            txt.setIp(ip);
                            WxGroupSDK.sendTextMessage(txt);
                        }
                        if ("image".equals(msg.getType())) {
                            SendPicMessageVO pic = new SendPicMessageVO();
                            pic.setAltId(robot);
                            pic.setPicUrl(msg.getImgUrl());
                            pic.setWxId(wxid);
                            pic.setWxGroupId(wxid);
                            pic.setIp(ip);
                            WxGroupSDK.sendPicMessage(pic);
                        }
                        if ("file".equals(msg.getType())) {
                            SendFileVO file = new SendFileVO();
                            file.setAltId(robot);
                            file.setFileUrl(msg.getFileUrl());
                            file.setFileName(msg.getFileName());
                            file.setWxId(wxid);
                            file.setWxGroupId(wxid);
                            file.setIp(ip);
                            WxGroupSDK.sendFile(file);
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<PcloudRobotClassifyResponseVO> listAllClassify() {
        return pcloudRobotWakeupMapper.listAllClassify();
    }

    @Override
    public void copyRobotWakeUp(String sourceWxId, String targetWxId) {
        PcloudRobot sourceRobot = pcloudRobotDao.getByWxId(sourceWxId);

        if (sourceRobot == null) {
            throw new BookBizException(BookBizException.ERROR, "源个人号未录入！");
        }

        if (sourceRobot.getRobotType() != null && sourceRobot.getWakeUp() == 1) {
            pcloudRobotDao.updateWakeUpByClassifyIds(Collections.singletonList(sourceRobot.getRobotType()));
        }
    }

}
