package com.gic.haoban.manage.service.service.out.impl.content.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.Week;
import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.haoban.manage.api.dto.content.log.TriggerCustomerDetailLogDTO;
import com.gic.haoban.manage.api.dto.content.report.MaterialReportDTO;
import com.gic.haoban.manage.api.enums.content.MaterialReportType;
import com.gic.haoban.manage.api.enums.content.TriggerCustomerChannelType;
import com.gic.haoban.manage.api.service.content.task.QywxGroupMsgTaskApiService;
import com.gic.haoban.manage.service.pojo.bo.content.GroupMessageInfoBo;
import com.gic.haoban.manage.service.pojo.bo.content.context.PotentialCustomerNotifyContext;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.content.GroupMessageService;
import com.gic.haoban.manage.service.service.content.MaterialReportService;
import com.gic.haoban.manage.service.service.content.PotentialCustomerService;
import com.gic.haoban.manage.service.service.content.adaptor.MaterialEnterpriseAdaptor;
import com.gic.haoban.manage.service.task.RouterConstant;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.Now;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author MUSI
 * @Date 2023/3/19 8:33 PM
 * @Description
 * @Version
 **/
@Component("qywxGroupMsgTaskApiServiceImpl")
public class QywxGroupMsgTaskApiServiceImpl implements QywxGroupMsgTaskApiService {

    private static final Logger log = LoggerFactory.getLogger(QywxGroupMsgTaskApiServiceImpl.class);
    @Autowired
    private GroupMessageService groupMessageService;
    @Autowired
    private MaterialReportService materialReportService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private PotentialCustomerService potentialCustomerService;

    @Override
    public ServiceResponse<Void> groupMsgTaskJob(String params) {
        log.info("执行触达客户定时任务 {}", DateUtil.datetimeToString(new Date()));
        // 获取开启【内容】权限的企业id
        List<String> enterpriseIds = groupMessageService.hasMaterialRightEnterprise(MaterialEnterpriseAdaptor.MaterialLevel.LOW.getCode());
        if (CollectionUtils.isEmpty(enterpriseIds)) {
            return ServiceResponse.success();
        }
        // 获取企业 (当前时间 - 30分钟, 当前时间)范围内的 导购分享记录。按创建时间排序
        Date currentTime = new Date();
        for (String enterpriseId : enterpriseIds) {
            GroupMessageInfoBo groupMessageInfoBo = new GroupMessageInfoBo();
            groupMessageInfoBo.setEnterpriseId(enterpriseId);
            groupMessageInfoBo.setStartTime(DateUtil.addNumForMinute(currentTime, -30));
            groupMessageInfoBo.setEndTime(currentTime);
            groupMessageService.handlerGroupMessage(groupMessageInfoBo);
        }
        return ServiceResponse.success();
    }

    /**
     * 处理客户触达日志明细
     *
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> handlerTriggerCustomerDetailLog(String params) {
        log.info("处理客户触达日志 {}", params);
        TriggerCustomerDetailLogDTO customerDetailLog = JSON.parseObject(params, TriggerCustomerDetailLogDTO.class);

        if (customerDetailLog == null) {
            log.info("处理客户触达日志 参数异常 {}", params);
            return ServiceResponse.success();
        }

        GroupMessageInfoBo groupMessageInfoBo = new GroupMessageInfoBo();
        groupMessageInfoBo.setEnterpriseId(customerDetailLog.getEnterpriseId());
        if (TriggerCustomerChannelType.PYQ.getCode().equals(customerDetailLog.getShareType())) {
            if (customerDetailLog.getSharePYQ() == null) {
                log.info("handlerTriggerCustomerDetailLog 分享朋友圈类型 参数异常 {}", params);
                return ServiceResponse.success();
            }
            groupMessageInfoBo.setShareLogId(customerDetailLog.getSharePYQ().getShareLogId());
        }
        groupMessageService.handlerGroupMessage(groupMessageInfoBo);
        return ServiceResponse.success();
    }

    /**
     * 素材周报
     *
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> handlerMaterialWeekReport(String params) {
        log.info("handlerMaterialWeekReport 执行素材周报任务开始 >>>>> {}", DateUtil.datetimeToString(new Date()));
//        Date now = new Date();
//        Week week = cn.hutool.core.date.DateUtil.dayOfWeekEnum(now);
//        if (!Week.MONDAY.equals(week)) {
//            log.info("handlerMaterialWeekReport 当前时间 不是周一 忽略 》》》 {}", DateUtil.datetimeToString(new Date()));
//            return ServiceResponse.success();
//        }
        return doHandlerReportInner(MaterialReportType.WEEK.getCode());
    }

    /**
     * 素材月报
     *
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> handlerMaterialMonthReport(String params) {
        log.info("handlerMaterialWeekReport 执行素材月报任务开始 >>>>> {}", DateUtil.datetimeToString(new Date()));
        return doHandlerReportInner(MaterialReportType.MONTH.getCode());
    }

    /**
     * 发送企业周报/月报素材
     *
     * @param reportType
     * @return
     */
    private ServiceResponse<Void> doHandlerReportInner(Integer reportType) {
        List<String> enterpriseIds = groupMessageService.hasMaterialRightEnterprise(MaterialEnterpriseAdaptor.MaterialLevel.LOW.getCode());
        if (CollectionUtils.isEmpty(enterpriseIds)) {
            return ServiceResponse.success();
        }

        for (String enterpriseId : enterpriseIds) {
            List<String> wxEnterpriseIds = wxEnterpriseService.queryWxEnterpriseWithEnterpriseId(enterpriseId);
            if (CollectionUtils.isEmpty(wxEnterpriseIds)) {
                log.info("企业 {}未关联企微", enterpriseId);
                continue;
            }
            List<String> staffIds = staffService.queryStaffIdsWithEnterpriseId(wxEnterpriseIds);
            if (CollectionUtils.isEmpty(staffIds)) {
                log.info("企业 {} 不存在成员", enterpriseId);
                continue;
            }
            for (String staffId : staffIds) {
                MaterialReportDTO temp = new MaterialReportDTO();
                temp.setStaffId(staffId);
                temp.setEnterpriseId(enterpriseId);
                temp.setReportType(reportType);
                boolean sendMQResult = this.sendMaterialReportMQ(temp);
                log.info("发送企业{}, 成员id: {}, 结果: {}", enterpriseId, staffId, sendMQResult);
            }
        }
        return ServiceResponse.success();
    }

    /**
     * 处理单成员素材使用周报/月报
     *
     * @param params
     * @return
     * @see RouterConstant#DEAL_ONE_STAFF_MATERIAL_REPORT
     */
    @Override
    public ServiceResponse<Void> doHandlerMaterialOneStaffReportMQ(String params) {
        log.info("doHandlerMaterialOneStaffReportMQ 参数: {}", params);
        MaterialReportDTO materialReportDTO = JSON.parseObject(params, MaterialReportDTO.class);
        if (materialReportDTO == null) {
            log.info("参数异常 {}", params);
            return ServiceResponse.success();
        }
        materialReportService.handlerMaterialReport(materialReportDTO.getEnterpriseId(), materialReportDTO.getStaffId(), materialReportDTO.getReportType());
        return ServiceResponse.success();
    }

    /**
     * 发送成员使用素材消息MQ
     *
     * @param materialReportDTO
     * @return
     */
    private boolean sendMaterialReportMQ(MaterialReportDTO materialReportDTO) {
        try {
            GICMQClientUtil.getClientInstance()
                    .sendMessage(RouterConstant.DEAL_ONE_STAFF_MATERIAL_REPORT, JSON.toJSONString(materialReportDTO));
            return true;
        } catch (Exception ex) {
            log.warn("发送成员使用素材周报/月报MQ异常, 参数: {}", JSON.toJSONString(materialReportDTO), ex);
        }
        return false;
    }

    /**
     * 销售线索 通知job
     *
     * @param params
     * @return 每半小时通知一次，提醒时间段：当天 8:00~23:00
     * 当天23:00~第二天8:00产生的线索动态，第二天 8:00 提醒
     * 区经不发应用、小程序消息
     * 导购、店长 应用只发主门店数据的应用消息
     */
    @Override
    public ServiceResponse<Void> potentialCustomerJob(String params) {
        Date now = new Date();
        log.info("potentialCustomerJob 执行销售线索通知 {}", cn.hutool.core.date.DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
        int currentHour = cn.hutool.core.date.DateUtil.hour(now, true);
        if (currentHour >= 23 || currentHour < 8) {
            log.info("当前时间处于消息禁发时间, 忽略{}", cn.hutool.core.date.DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
            return ServiceResponse.success();
        }
        List<String> enterpriseIds = groupMessageService.hasMaterialRightEnterprise(MaterialEnterpriseAdaptor.MaterialLevel.LOW.getCode());
        if (CollectionUtils.isEmpty(enterpriseIds)) {
            log.info("开通内容权限的企业为空");
            return ServiceResponse.success();
        }
        Date startTime = cn.hutool.core.date.DateUtil.offsetMinute(now, -30).toJdkDate();
        // 如果是8点那次的执行 需要获取 23 ～ 8点的数据
        if (checkIsTodayFirst(now)) {
            log.info("本次执行为当天第一次执行 {}", cn.hutool.core.date.DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"));
            Date yesterday = cn.hutool.core.date.DateUtil.yesterday().toJdkDate();
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.setTime(yesterday);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            startTime = calendar.getTime();
        }
        for (String enterpriseId : enterpriseIds) {
            PotentialCustomerNotifyContext context = PotentialCustomerNotifyContext.builder()
                    .enterpriseId(enterpriseId)
                    .startTime(startTime)
                    .endTime(now)
                    .build();
            potentialCustomerService.sendPotentialCustomerNotice(context);
        }
        return ServiceResponse.success();
    }

    /**
     * 判断是否是当天第一次
     * 执行时间处于 8:00 ~ 8:30
     *
     * @param now
     * @return
     */
    int hour_sec = 30 * 60;

    private boolean checkIsTodayFirst(Date now) {
        DateTime temp = cn.hutool.core.date.DateUtil.offsetSecond(now, -(hour_sec));
        return cn.hutool.core.date.DateUtil.hour(temp, true) < 8;
    }
}
