package com.hz.pm.api.sys.manage;

import com.hz.pm.api.common.enumeration.CommonEnum;
import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.meeting.helper.YxtCallOrSmsHelper;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.enumeration.InstTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningFlowTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningOperationTypeEnum;
import com.hz.pm.api.staging.enums.MsgTypeEnum;
import com.hz.pm.api.staging.service.INdWorkNoticeStagingService;
import com.hz.pm.api.sys.model.entity.Notify;
import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
import com.hz.pm.api.sys.service.IEarlyWarningRecordsService;
import com.hz.pm.api.sys.service.INotifyService;
import com.hz.pm.api.user.security.model.UserFullInfoDTO;
import com.ningdatech.yxt.model.cmd.SendSmsCmd.SendSmsContext;
import com.wflow.enums.WarningNoticeTypeEnum;
import com.wflow.enums.WarningRuleTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * @Classname EarlyWarningManage
 * @Description
 * @Date 2023/8/7 9:25
 * @Author PoffyZhang
 */
@Component
@AllArgsConstructor
@Slf4j
public class EarlyWarningManage {

    private final UserInfoHelper userInfoHelper;

    private final NoticeManage noticeManage;

    private final IEarlyWarningRecordsService earlyWarningRecordsService;

    private final YxtCallOrSmsHelper yxtCallOrSmsHelper;

    private final INdWorkNoticeStagingService workNoticeStagingService;

    private final INotifyService notifyService;

    /**
     * 预警通知
     *
     * @param noticeMethod
     * @param noticeContent
     * @param adventTimeout
     * @param userId
     * @param project
     */
    public void doEarlyWarning(String noticeMethod, String noticeContent, Integer adventTimeout, Integer overTimeout,
                               Integer biz, LocalDateTime startTime, Long userId,
                               Project project, Integer ruleType, Integer noticeType,
                               String path, String batchEmployees, String nodeId) {
        //1.存入 预警记录
        UserFullInfoDTO user = userInfoHelper.getUserFullInfo(userId);
        WflowEarlyWarningRecords records = new WflowEarlyWarningRecords();
        String content;

        switch (WarningRuleTypeEnum.checkByCode(ruleType)) {
            case PROCESS_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.PROCESS_WARNING.getCode());
                break;
            case DECLARED_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.DECLARED_WARNING.getCode());
                break;
            case OPERATION_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.OPERATION_WARNING.getCode());
                break;
            case RENEWAL_FUND:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(), overTimeout);
                }

                records.setRuleType(WarningRuleTypeEnum.RENEWAL_FUND.getCode());
                break;
            default:
                log.info("匹配不到 规则类型");
                return;
        }

        records.setAreaCode(project.getAreaCode());
        records.setBuildOrgCode(project.getBuildOrgCode());
        records.setBuildOrgName(project.getBuildOrgName());
        records.setCreateOn(LocalDateTime.now());
        records.setWarningTime(LocalDateTime.now());
        records.setInstStart(startTime);
        records.setInstType(biz);
        records.setNoticeMethod(noticeMethod);
        records.setNoticeContent(content);
        records.setProjectName(project.getProjectName());
        records.setWarningUsername(Objects.nonNull(user) ? user.getUsername() : StringUtils.EMPTY);
        records.setWarningUserId(String.valueOf(userId));
        records.setProjectId(project.getId());
        records.setProjectCode(project.getProjectCode());
        records.setProjectStatus(project.getStatus());
        records.setNoticeType(noticeType);
        records.setPath(path);
        records.setBatchUserIds(batchEmployees);
        records.setBiz(biz);
        records.setNodeId(nodeId);
        records.setOverTime(overTimeout);
        earlyWarningRecordsService.save(records);

        //2.消息提醒
        Notify notify = noticeManage.assemblyAuditNotify(user.getUserId(), project, content);
        notify.setType(MsgTypeEnum.PROJECT_REVIEW.name());
        notifyService.save(notify);

        //3.发短信
        if (noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode()))) {
            SendSmsContext context = new SendSmsContext();
            context.setReceiveNumber(user.getMobile());
            context.setContent(content);
            yxtCallOrSmsHelper.sendSms(context);
        }

        //4.浙政钉
        /*if (noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode()))) {
            // 获取发送浙政钉工作通知必要信息
            WorkNoticeInfo passWorkNoticeInfo = noticeManage.getSendWorkNoticeInfo(userId);
            passWorkNoticeInfo.setMsg(content);
            // 放入工作通知暂存表中，通过扫表异步发送
            workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW);
        }*/
    }

    /**
     * 催办
     *
     * @param noticeMethod
     * @param noticeContent
     * @param adventTimeout
     * @param userId
     * @param project
     */
    public void urging(String noticeMethod, String noticeContent, Integer adventTimeout, Integer overTimeout,
                       Integer biz, LocalDateTime startTime, Long userId,
                       Project project, Integer ruleType, Integer noticeType,
                       String path, String batchEmployees, String nodeId) {
        //1.存入 预警记录
        UserFullInfoDTO user = userInfoHelper.getUserFullInfo(userId);
        WflowEarlyWarningRecords records = new WflowEarlyWarningRecords();
        String content;

        switch (WarningRuleTypeEnum.checkByCode(ruleType)) {
            case PROCESS_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            InstTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.PROCESS_WARNING.getCode());
                break;
            case DECLARED_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningFlowTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.DECLARED_WARNING.getCode());
                break;
            case OPERATION_WARNING:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(),
                            WarningOperationTypeEnum.getByCode(biz), overTimeout);
                }
                records.setRuleType(WarningRuleTypeEnum.OPERATION_WARNING.getCode());
                break;
            case RENEWAL_FUND:
                if (Objects.isNull(noticeType)) {
                    content = convertContent(noticeContent, project.getProjectName(), overTimeout);
                } else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
                    content = convertAdventContent(noticeContent, project.getProjectName(), adventTimeout, overTimeout);
                } else {
                    content = convertContent(noticeContent, project.getProjectName(), overTimeout);
                }

                records.setRuleType(WarningRuleTypeEnum.RENEWAL_FUND.getCode());
                break;
            default:
                log.info("匹配不到 规则类型");
                return;
        }

        records.setAreaCode(project.getAreaCode());
        records.setBuildOrgCode(project.getBuildOrgCode());
        records.setBuildOrgName(project.getBuildOrgName());
        records.setCreateOn(LocalDateTime.now());
        records.setWarningTime(LocalDateTime.now());
        records.setInstStart(startTime);
        records.setInstType(biz);
        records.setNoticeMethod(noticeMethod);
        records.setNoticeContent(content);
        records.setProjectName(project.getProjectName());
        records.setWarningUsername(Objects.nonNull(user) ? user.getUsername() : StringUtils.EMPTY);
        records.setWarningUserId(String.valueOf(userId));
        records.setProjectId(project.getId());
        records.setProjectCode(project.getProjectCode());
        records.setProjectStatus(project.getStatus());
        records.setNoticeType(noticeType);
        records.setPath(path);
        records.setBatchUserIds(batchEmployees);
        records.setBiz(biz);
        records.setNodeId(nodeId);
        earlyWarningRecordsService.save(records);

        //2.消息提醒
        Notify notify = noticeManage.assemblyAuditNotify(user.getUserId(), project, content);
        notify.setType(MsgTypeEnum.PROJECT_REVIEW.name());
        notifyService.save(notify);

        //3.发短信
        if (noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode()))) {
            SendSmsContext context = new SendSmsContext();
            context.setReceiveNumber(user.getMobile());
            context.setContent(content);
            yxtCallOrSmsHelper.sendSms(context);
        }

        /*//4.浙政钉
        if (noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode()))) {
            // 获取发送浙政钉工作通知必要信息
            WorkNoticeInfo passWorkNoticeInfo = noticeManage.getSendWorkNoticeInfo(employeeCode);
            passWorkNoticeInfo.setMsg(content);
            // 放入工作通知暂存表中，通过扫表异步发送
            workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW);
        }*/
    }

    /**
     * 续建项目资金
     *
     * @param noticeContent
     * @param projectName
     * @param timeout
     * @return
     */
    private String convertContent(String noticeContent, String projectName, Integer timeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{time}", String.valueOf(timeout));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertAdventContent(String noticeContent, String projectName, Integer timeout, Integer overTimeOut) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{time}", String.valueOf(timeout))
                .replace("{time2}", String.valueOf((overTimeOut - timeout)));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    /**
     * 转换出 通知的内容
     *
     * @param noticeContent
     * @param projectName
     * @param instTypeEnum
     * @param timeout
     * @return
     */
    private String convertContent(String noticeContent, String projectName, InstTypeEnum instTypeEnum, Integer timeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(instTypeEnum) ? instTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(instTypeEnum) ? instTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertAdventContent(String noticeContent, String projectName, InstTypeEnum instTypeEnum, Integer timeout, Integer overTimeOut) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(instTypeEnum) ? instTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(instTypeEnum) ? instTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout))
                .replace("{time2}", String.valueOf((overTimeOut - timeout)));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertContent(String noticeContent, String projectName, WarningFlowTypeEnum warningFlowTypeEnum, Integer timeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(warningFlowTypeEnum) ? warningFlowTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(warningFlowTypeEnum) ? warningFlowTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertAdventContent(String noticeContent, String projectName, WarningFlowTypeEnum warningFlowTypeEnum, Integer timeout, Integer overTimeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(warningFlowTypeEnum) ? warningFlowTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(warningFlowTypeEnum) ? warningFlowTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout))
                .replace("{time2}", String.valueOf((overTimeout - timeout)));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertContent(String noticeContent, String projectName, WarningOperationTypeEnum operationTypeEnum, Integer timeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(operationTypeEnum) ? operationTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(operationTypeEnum) ? operationTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }

    private String convertAdventContent(String noticeContent, String projectName, WarningOperationTypeEnum operationTypeEnum, Integer timeout, Integer overTimeout) {
        noticeContent = noticeContent.replace("{projectName}", projectName)
                .replace("{flowType}", Objects.nonNull(operationTypeEnum) ? operationTypeEnum.getDesc() : "{flowType}")
                .replace("{stepName}", Objects.nonNull(operationTypeEnum) ? operationTypeEnum.getDesc() : "{stepName}")
                .replace("{time}", String.valueOf(timeout))
                .replace("{time2}", String.valueOf((overTimeout - timeout)));
        log.info("通知内容 :{}", noticeContent);
        return noticeContent;
    }
}
