package com.yeejoin.amos.boot.module.ugp.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl;
import com.yeejoin.amos.boot.module.ugp.api.Enum.OrgEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.ProblemProcessEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.SMSEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.TaskTypeEnum;
import com.yeejoin.amos.boot.module.ugp.api.entity.*;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.SmsRecordModel;
import com.yeejoin.amos.feign.workflow.Workflow;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO;
import com.yeejoin.amos.feign.workflow.model.AjaxResult;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.*;

/**
 * @author Dell
 */
@Service
public class ProblemInitiationServiceImpl {

    @Autowired
    TaskServiceImpl taskService;

    @Autowired
    ProjectServiceImpl projectServiceImpl;

    @Autowired
    SuperviseRuleServiceImpl superviseRuleServiceImpl;

    @Autowired
    RectifyMsgServiceImpl rectifyMsgServiceImpl;

    @Autowired
    OrgUsrServiceImpl orgUsrServiceImpl;

    @Autowired
    ProjectInitiationServiceImpl projectInitiationService;

    @Autowired
    QualityProblemServiceImpl qualityProblemService;

    @Autowired
    InstallNoticeMsgServiceImpl installNoticeMsgService;


    @Value("${params.work.flow.problemDefinitionKey}")
    private String problemDefinitionKey;

    @Value("${supervisionRoleId}")
    private String supervisionRoleId;

    @Value("${installationRoleId}")
    private String installationRoleId;

    @Value("${monitoringRoleId}")
    private String monitoringRoleId;

    @Value("${constructionRoleId}")
    private String constructionRoleId;

    public String start(QualityProblem qualityProblem) {
        String instanceId = null;
        //启动流程
        try {
            ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
            dto.setProcessDefinitionKey(problemDefinitionKey);
            dto.setBusinessKey("1");
            AjaxResult ajaxResult = Workflow.taskClient.startByVariable(dto);
            instanceId = ((Map)ajaxResult.get("data")).get("id").toString();
            ProjectInitiation projectInitiation = new ProjectInitiation();
            projectInitiation.setInstanceId(instanceId);
            projectInitiation.setTaskName("流程启动！");
            projectInitiationService.save(projectInitiation);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("流程启动失败："+e.getMessage());
        }
        qualityProblem.setInstanceId(instanceId);
        qualityProblem.setStatus(projectInitiationService.getFlowTaskName(instanceId));
        qualityProblem.setProcessProgress(ProblemProcessEnum.statusMap.get(qualityProblem.getStatus()));
        qualityProblemService.updateById(qualityProblem);
        sendSms(JSONObject.parseObject(JSONObject.toJSONString(qualityProblem)), SMSEnum.质量问题短信.getCode());
        return instanceId;
    }


    public void execute(String instanceId,QualityProblem objectd, String option){
        List<Long> unitIds = new ArrayList<>();
        String taskType = new String();

        JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(objectd));
        AjaxResult ajaxResult = Workflow.taskClient.getTask(instanceId);
        JSONObject dataObject = JSON.parseObject(JSON.toJSONString(ajaxResult.get("data")));
        ProjectInitiation projectInitiation = new ProjectInitiation();
        projectInitiation.setInstanceId(instanceId);
        projectInitiation.setContext(JSON.toJSONString(objectd));
        projectInitiation.setTaskId(dataObject.getString("id"));
        projectInitiation.setTaskName(dataObject.getString("name"));

        if (ProblemProcessEnum.重大问题发送短信.getName().equals(dataObject.getString("name"))) {
            if(!ValidationUtil.isEmpty(objectd)) {
                sendSms(object, SMSEnum.重大质量问题短信.getCode());
            }
        }

        if (ProblemProcessEnum.超期整改发送短信.getName().equals(dataObject.getString("name"))) {
            if(!ValidationUtil.isEmpty(objectd)) {
                sendSms(object, SMSEnum.超期整改短信.getCode());
            }
        }

        if (ProblemProcessEnum.重大问题整改完成发送短信.getName().equals(dataObject.getString("name"))) {
            if(!ValidationUtil.isEmpty(objectd)) {
                sendSms(object, SMSEnum.重大问题整改完成短信.getCode());
            }
        }


        try {
            //组装信息
            TaskResultDTO dto = new TaskResultDTO();
            dto.setResult(option);
            dto.setResultCode("select");
            dto.setTaskId(projectInitiation.getTaskId());
            HashMap<String, Object> var = new HashMap<>();
            var.put("select", option);
            dto.setVariable(var);
            //执行流程
            Workflow.taskClient.completeByTask(projectInitiation.getTaskId(),dto);
            //保存日志
            projectInitiationService.save(projectInitiation);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("任务完成失败："+e.getMessage());
        } finally {
            //更新任务表的状态 已办
            if(!ValidationUtil.isEmpty(unitIds)) {
                taskType = getUnitId(unitIds, objectd);
                taskService.saveOrUpdateTask(objectd.getStatus(), true, taskType, new Date(), object.getLong("sequenceNbr"), TaskTypeEnum.质量问题.getKey(), unitIds);
            }

            //更新problem中的status字段，表示当前流程下一个执行的任务
            qualityProblemService.updateById(objectd);
            updateProBlemFlowStatus(instanceId);
            QualityProblem quality = qualityProblemService.getById(objectd.getSequenceNbr());
            objectd.setStatus(quality.getStatus());

            if(!ValidationUtil.isEmpty(unitIds)) {
                taskType = getUnitId(unitIds, objectd);
                taskService.saveOrUpdateTask(objectd.getStatus(), false, taskType, new Date(), object.getLong("sequenceNbr"), TaskTypeEnum.质量问题.getKey(), unitIds);
            }
        }
    }

    /**
     * 获取任务的执行单位id 和 TaskType
     * @param unitIds
     */
    public String getUnitId(List<Long> unitIds, QualityProblem qualityProblem){
        Project project = projectServiceImpl.getById(qualityProblem.getProjectId());

        //获取问题所在的区域规则信息
        SuperviseRule superviseRule = superviseRuleServiceImpl.getOne(new LambdaQueryWrapper<SuperviseRule>().eq(SuperviseRule::getAdminRegionCode,project.getInstallRegionCode()));

        String taskType = "";
        if (ProblemProcessEnum.确定问题.getName().equals(qualityProblem.getStatus()) || ProblemProcessEnum.审查整改过程.getName().equals(qualityProblem.getStatus()) || ProblemProcessEnum.问题分类.getName().equals(qualityProblem.getStatus())) {
            unitIds.add(superviseRule.getInspectionUnitId());
            taskType = TaskTypeEnum.流程.getKey();
        }
        if (ProblemProcessEnum.编制处理方案.getName().equals(qualityProblem.getStatus()) || ProblemProcessEnum.提交整改书.getName().equals(qualityProblem.getStatus())) {
            unitIds.add(project.getInstallationUnitId());
            taskType = TaskTypeEnum.填报.getKey();
        }
        if (ProblemProcessEnum.审查处理方案.getName().equals(qualityProblem.getStatus())) {
            unitIds.add(project.getConstructionUnitId());
            taskType = TaskTypeEnum.流程.getKey();
        }

        return taskType;
    }

    /**
     * 项目立项及质量问题闭环处理 发送短信具体模板
     * @param object
     * @param smsCode
     */
    public void sendSms(JSONObject object, String smsCode){
        Long sequenceNbr = object.getLong("sequenceNbr");
        if(ValidationUtil.isEmpty(object.getString("projectName"))) {
            object.put("projectName", projectServiceImpl.getById(object.getLong("projectId")).getName());
        }
        //设置短信发送的基本参数
        HashMap<String, String> smsParams = new HashMap();
        smsParams.put("smsCode", smsCode);
        smsParams.put("projectName", object.getString("projectName"));
        smsParams.put("problemDescribe", object.getString("problemDescribe"));
        smsParams.put("CompanyName", object.getString("CompanyName"));
        if(SMSEnum.项目安装告知申请.getCode().equals(smsCode)){
            //给监察发短信
            sendTo(OrgEnum.监察部门.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
        }else if(SMSEnum.项目立项驳回短信.getCode().equals(smsCode)) {
            //给监察发短信
            sendTo(OrgEnum.监察部门.getKey(),object.getLong("sequenceNbr"),sequenceNbr,smsParams,smsCode,object);
            //给安装发短信
            sendTo(OrgEnum.安装单位.getKey(),object.getLong("sequenceNbr"),sequenceNbr,smsParams,smsCode,object);
        }else if(SMSEnum.重大质量问题短信.getCode().equals(smsCode)){
            //给监察发短信
            sendTo(OrgEnum.监察部门.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
        }else if(SMSEnum.超期整改短信.getCode().equals(smsCode)){
            //给安装发短信
            sendTo(OrgEnum.建设单位.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
            //给安装发短信
            sendTo(OrgEnum.监检机构.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
            //给安装发短信
            sendTo(OrgEnum.安装单位.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
            //给监察发短信
            sendTo(OrgEnum.监察部门.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
        }else if(SMSEnum.重大问题整改完成短信.getCode().equals(smsCode)){
            //给监察发短信
            sendTo(OrgEnum.监察部门.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
        }else if (SMSEnum.质量问题短信.getCode().equals(smsCode)) {
            //给安装发短信
            sendTo(OrgEnum.建设单位.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
            //给安装发短信
            sendTo(OrgEnum.监检机构.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
            //给安装发短信
            sendTo(OrgEnum.安装单位.getKey(),object.getLong("projectId"),sequenceNbr,smsParams,smsCode,object);
        }
    }

    /**
     * 发送短信给监检/安装/监察/建设
     * @param nameKey
     * @param projectId
     * @param sequenceNbr
     * @param smsParams
     * @param smsCode
     * @param object
     */
    public void sendTo(String nameKey,Long projectId,Long sequenceNbr,HashMap<String, String> smsParams,String smsCode,JSONObject object){
        if(OrgEnum.监检机构.getKey().equals(nameKey)){
            LambdaQueryWrapper<SuperviseRule> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SuperviseRule::getAdminRegionCode, projectServiceImpl.getById(projectId).getInstallRegionCode());
            String MonitoringUnitId = orgUsrServiceImpl.getById(superviseRuleServiceImpl.getOne(wrapper).getInspectionUnitId()).getAmosOrgId();
            sendMessage(sequenceNbr,MonitoringUnitId,smsParams,smsCode,monitoringRoleId,object);
        } else if (OrgEnum.安装单位.getKey().equals(nameKey)){
            //给安装发短信
            String installationUnitId = orgUsrServiceImpl.getById(projectServiceImpl.getById(projectId).getInstallationUnitId()).getAmosOrgId();
            sendMessage(sequenceNbr,installationUnitId,smsParams,smsCode,installationRoleId,object);
        } else if (OrgEnum.监察部门.getKey().equals(nameKey)){
            //给监察发短信
            LambdaQueryWrapper<SuperviseRule> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SuperviseRule::getAdminRegionCode, projectServiceImpl.getById(projectId).getInstallRegionCode());
            String supervisionUnitId = orgUsrServiceImpl.getById(superviseRuleServiceImpl.getOne(wrapper).getSuperviseDeptId()).getAmosOrgId();
            sendMessage(sequenceNbr,supervisionUnitId,smsParams,smsCode,supervisionRoleId,object);
        } else if (OrgEnum.建设单位.getKey().equals(nameKey)){
            //给建设发短信
            String installationUnitId = orgUsrServiceImpl.getById(projectServiceImpl.getById(projectId).getConstructionUnitId()).getAmosOrgId();
            sendMessage(sequenceNbr,installationUnitId,smsParams,smsCode,constructionRoleId,object);
        }

    }

    /**
     * 发送短信
     * @param sequenceNbr 任务id（项目/问题）
     * @param noticeUnitId 平台目标企业id
     * @param smsParams 短信参数
     * @param smsCode 短信模板
     * @param roleId 角色id
     */
    public void sendMessage(Long sequenceNbr,String noticeUnitId,HashMap<String, String> smsParams,String smsCode,String roleId,JSONObject object){
        //向noticeUnitId的部门发送短信
        List<AgencyUserModel> agencyUserModelList = Privilege.agencyUserClient.queryByRoleId(roleId,null).getResult();
        List<AgencyUserModel> companyUserModelList = Privilege.agencyUserClient.queryByCompanyId(Long.valueOf(noticeUnitId),null,null,null).getResult();
        Map<String,AgencyUserModel> map = new HashMap<>();
        for (AgencyUserModel agencyUserModel : companyUserModelList) {
            map.put(agencyUserModel.getUserId(), agencyUserModel);
        }

        //遍历用户List，拿到用户手机号、userId,来发短信、存短信日志。
        for (AgencyUserModel agencyUserModel : agencyUserModelList) {
            boolean bool = false;
            if(!ValidationUtil.isEmpty(map.get(agencyUserModel.getUserId()))){
                bool = true;
            }
            if (bool) {

                SmsRecordModel smsRecordModel = sendSmsMassage(smsCode, agencyUserModel.getMobile(), smsParams);
                if (ValidationUtil.isEmpty(smsRecordModel)) {
                    continue;
                }
                if(SMSEnum.项目安装告知申请.getCode().equals(smsCode) || SMSEnum.项目立项驳回短信.getCode().equals(smsCode)){
                    saveProjectSmsLog(smsRecordModel,sequenceNbr,noticeUnitId,agencyUserModel,object,smsCode);
                }else {
                    saveProblemSmsLog(smsRecordModel,sequenceNbr,noticeUnitId,agencyUserModel,object,smsCode);
                }

            }
        }
    }

    /**
     * 存 项目立项流程中 发送的短信信息
     * @param smsRecordModel
     * @param sequenceNbr
     * @param noticeUnitId
     * @param agencyUserModel
     * @param object
     * @param smsCode
     */
    public void saveProjectSmsLog(SmsRecordModel smsRecordModel,Long sequenceNbr,String noticeUnitId,AgencyUserModel agencyUserModel,JSONObject object,String smsCode){
        String content = Systemctl.smsTemplateClient.seleteOne(smsCode).getResult().getSmsContent();
        String projectName = object.getString("projectName");
        String companyName = object.getString("companyName");
        String reviewInfo = object.getString("reviewInfo");

        if(!ValidationUtil.isEmpty(projectName)){
            if(content.contains("${projectName}")) {
                content = content.replace("${projectName}", projectName);
            }
        }
        if(!ValidationUtil.isEmpty(companyName)){
            if(content.contains("${companyName}")){
                content = content.replace("${companyName}",companyName);
            }
        }
        if(!ValidationUtil.isEmpty(reviewInfo)){
            if(content.contains("${reviewInfo}")) {
                content = content.replace("${reviewInfo}", reviewInfo);
            }
        }

        LambdaQueryWrapper<OrgUsr> wrapperQueryWrapper = new LambdaQueryWrapper<>();
        wrapperQueryWrapper.eq(OrgUsr::getAmosOrgId,agencyUserModel.getSequenceNbr());
        InstallNoticeMsg installNoticeMsg = new InstallNoticeMsg();
        installNoticeMsg.setContent(content);
        installNoticeMsg.setInstallNoticeId(object.getLong("sequenceNbr"));
        installNoticeMsg.setTargetUnitId(Long.valueOf(noticeUnitId));
        installNoticeMsg.setTargetPersonId(orgUsrServiceImpl.getOne(wrapperQueryWrapper).getSequenceNbr());
        installNoticeMsg.setSendTime(smsRecordModel.getSendTime());
        installNoticeMsgService.save(installNoticeMsg);
    }

    /**
     * 存 质量问题闭环处理流程中 发送的短信信息
     * @param smsRecordModel
     * @param sequenceNbr
     * @param noticeUnitId
     * @param agencyUserModel
     * @param object
     * @param smsCode
     */
    public void saveProblemSmsLog(SmsRecordModel smsRecordModel,Long sequenceNbr,String noticeUnitId,AgencyUserModel agencyUserModel,JSONObject object,String smsCode){
        String content = Systemctl.smsTemplateClient.seleteOne(smsCode).getResult().getSmsContent();
        String projectName = object.getString("projectName");
        String problemDescribe = object.getString("problemDescribe");

        if(!ValidationUtil.isEmpty(projectName)){
            if(content.contains("${projectName}")) {
                content = content.replace("${projectName}", projectName);
            }
        }
        if(!ValidationUtil.isEmpty(problemDescribe)){
            if(content.contains("${problemDescribe}")){
                content = content.replace("${problemDescribe}",problemDescribe);
            }
        }

        LambdaQueryWrapper<OrgUsr> wrapperQueryWrapper = new LambdaQueryWrapper<>();
        wrapperQueryWrapper.eq(OrgUsr::getAmosOrgId,agencyUserModel.getSequenceNbr());
        RectifyMsg rectifyMsg = new RectifyMsg();
        rectifyMsg.setContent(content);
        rectifyMsg.setProblemId(sequenceNbr);
        rectifyMsg.setNoticeUnitId(Long.valueOf(noticeUnitId));
        rectifyMsg.setMsgReceiver(orgUsrServiceImpl.getOne(wrapperQueryWrapper).getSequenceNbr());
        rectifyMsg.setSendTime(smsRecordModel.getSendTime());
        rectifyMsgServiceImpl.save(rectifyMsg);
    }

    /**
     * 发送短信公用模板
     * @param smsCode
     * @param mobile
     * @param smsParams
     * @return
     */
    public SmsRecordModel sendSmsMassage(String smsCode, String mobile, HashMap<String, String> smsParams){
        SmsRecordModel smsRecordModel = new SmsRecordModel();

        if(!ValidationUtil.isEmpty(mobile)){
            smsParams.put("smsCode",smsCode);
            smsParams.put("mobile",mobile);
            smsRecordModel = Systemctl.smsClient.sendCommonSms(smsParams).getResult();
        }
        return smsRecordModel;
    }


    public void updateProBlemFlowStatus(String instanceId){
        LambdaQueryWrapper<QualityProblem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QualityProblem::getInstanceId,instanceId);
        QualityProblem qualityProblem = qualityProblemService.getOne(wrapper);
        qualityProblem.setStatus(projectInitiationService.getFlowTaskName(instanceId));
        qualityProblem.setProcessProgress(ProblemProcessEnum.statusMap.get(qualityProblem.getStatus()));
        qualityProblemService.updateById(qualityProblem);
    }

    public void updateProblemStatus(QualityProblem qualityProblem,Long sequenceNbr){
        QualityProblem quality = qualityProblemService.getById(sequenceNbr);
        qualityProblem.setStatus(quality.getStatus());
    }
}
