package com.ruoyi.flowable.service.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sms.SmsSenderUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.flowable.common.constant.ProcessConstants;
import com.ruoyi.flowable.common.constant.UUIDGenerator;
import com.ruoyi.flowable.common.enums.FlowStatusEnum;
import com.ruoyi.flowable.factory.FlowServiceFactory;
import com.ruoyi.flowable.service.*;
import com.ruoyi.invest.domain.*;
import com.ruoyi.invest.domain.vo.ProjectTerminationVo;
import com.ruoyi.invest.mapper.TerminationMapper;
import com.ruoyi.invest.mapper.TProjectScoringMapper;
import com.ruoyi.invest.service.*;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.tool.service.ITUnifyFileService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
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.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * 项目池Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-02-21
 */
@Service
public class TerminationServiceImpl extends FlowServiceFactory implements ITerminationService
{
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Value("${spring.profiles.active}")
    private String active;
    @Autowired
    private TerminationMapper terminationMapper;
    @Autowired
    private ITProjectPoolService tProjectPoolService;
    @Autowired
    private ITProjectCirculationService tProjectCirculationService;
    @Autowired
    private IFlowBaseInfoService activitiBaseInfoService;
    @Autowired
    private IFlowInstanceService flowInstanceService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private IFlowService flowService;
    @Autowired
    private ITProjectMeetingService tProjectMeetingService;
    @Autowired
    private TProjectScoringMapper tProjectScoringMapper;
    @Autowired
    private ISysFormService sysFormService;
    @Override
    public List<ProjectTerminationVo> selectAllTerminationList(TProjectTermination tProjectTermination){
        return terminationMapper.selectAllTerminationList(tProjectTermination);
    }
    @Override
    public List<ProjectTerminationVo> getMyTaskList(String userId, TProjectTermination tProjectTermination){
        return terminationMapper.getMyTaskList(userId, tProjectTermination);
    }
    @Override
    public List<ProjectTerminationVo> getMyDoneTaskList(String userId, TProjectTermination tProjectTermination){
        return terminationMapper.getMyDoneTaskList(userId, tProjectTermination);
    }
    @Override
    public List<ProjectTerminationVo> getMyList(String userId,TProjectTermination tProjectTermination){
        return terminationMapper.getMyList(userId, tProjectTermination);
    }


    /**
     * 查询项目池
     * 
     * @param pInstId 流程实例Id
     * @return 项目池
     */
    @Override
    public TProjectTermination selectTProjectTerminationByProcInstId(String pInstId)
    {
        return terminationMapper.selectTProjectTerminationByProcInstId(pInstId);
    }

    @Override
    public AjaxResult start(TProjectTermination tProjectTermination) {

        // 根据key值获取最新的流程部署id
        String pDefId = null;
        ProcessInstance pInst = null;
        try {
            List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionKey("dgt-termination-workflow")
                    .orderByProcessDefinitionVersion().desc().list();
            if(list.size()==0){
                return AjaxResult.error("未找到该流程，无法开启流程！");
            }
            pDefId = list.get(0).getId();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(pDefId)
                    .latestVersion().singleResult();
            if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
                return AjaxResult.error("流程已被挂起,请先激活流程");
            }
            if(StringUtils.isNotBlank(pDefId)){

                //设置参数
                Map<String, Object> formProperties = new HashMap<String, Object>();
                // 设置流程发起人Id到流程中
                SysUser sysUser = SecurityUtils.getLoginUser().getUser();
                identityService.setAuthenticatedUserId(sysUser.getUserId().toString());
                formProperties.put("auditPass",tProjectTermination.isFlag()?true:false);
                //暂存
                formProperties.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId());
                //投资部负责人
                String leader=sysDeptMapper.selectDeptLeader("投资部");
                formProperties.put("MANAGER",sysUserService.selectUserByUserName(leader).getUserId());
                pInst = runtimeService.startProcessInstanceById(pDefId, formProperties);
               // ProcessInstance p = runtimeService.startProcessInstanceById(procDefId, variables);
                if(pInst!=null){
                    String nickName= SecurityUtils.getLoginUser().getUser().getNickName();
                    String userId=SecurityUtils.getLoginUser().getUserId().toString();
                    //保存信息
                    tProjectTermination.setId(IdUtils.fastSimpleUUID());
                    tProjectTermination.setProcInstId(pInst.getProcessInstanceId());
                    tProjectTermination.setCreateBy(userId);
                    if(tProjectTermination.isFlag()){
                        tProjectTermination.setStatus(1);//提交
                    }else{
                        tProjectTermination.setStatus(0);//暂存
                    }
                    // todo 更改终止状态
                    tProjectPoolService.updateTProjectPoolByApprovalFlag(tProjectTermination.getProjectPoolId(),"1");
                    // todo 短信提醒
                    /*if(StringUtils.isNotEmpty(tProjectTermination.getParticipantsId())){
                        StringUtils.str2List(tProjectTermination.getParticipantsId(),",",true,true).stream().forEach(str -> {
                            SysUser user = sysUserService.selectUserById(Long.valueOf(str));
                            String contents = "您好，"+user.getNickName()+"，" + tProjectTermination.getProjectName() + "已发起投决申请。";
                            try {
                                SmsSenderUtils.sendSms(user.getPhonenumber(),contents);
                            } catch (IOException e) {
                                logger.error("短信发送失败"+e.getMessage());
                            }
                        });
                    }*/

                    // todo 增加项目创建记录
                    tProjectCirculationService.insertTProjectCirculation(tProjectTermination.getProjectPoolId(),"终止申请",nickName);
                    // todo 更改终止状态
                    tProjectPoolService.updateTProjectPoolByTerminationFlag(tProjectTermination.getProjectPoolId(),"1");//1是代表已发起终止申请
                    // todo 新增终止数据
                    tProjectTermination.setCreateTime(DateUtils.getNowDate());
                    terminationMapper.insertTProjectTermination(tProjectTermination);



                    FlowBaseInfo flowBaseInfo = new FlowBaseInfo();
                    flowBaseInfo.setCreateBy(userId);
                    flowBaseInfo.setId(UUIDGenerator.uuid());
                    flowBaseInfo.setFormProperties(flowInstanceService.getFormProperties(pInst));
                    flowBaseInfo.setProcDefId(pDefId);
                    flowBaseInfo.setProcInsId(pInst.getId());
                    flowBaseInfo.setTaskName("申请人");
                    flowBaseInfo.setFlag(true);
                    flowBaseInfo.setComment(tProjectTermination.isFlag() ? "[提交]" : "[暂存]");
                    flowBaseInfo.setStatus(FlowStatusEnum.STARTED.getName());
                    flowBaseInfo.setFlag(tProjectTermination.isFlag());
                    activitiBaseInfoService.addActivitiBaseInfo(flowBaseInfo);

                    TProjectPool tProjectPool=new TProjectPool();
                    tProjectPool.setId(tProjectTermination.getProjectPoolId());
//                    tProjectPool.setProjectStage("8");//项目阶段-项目终止
//                    tProjectPool.setProjectState("o");//项目状态-项目终止
                    tProjectPoolService.updateTProjectPool(tProjectPool);
                    if(flowBaseInfo.isFlag()){
                        getAssignee(tProjectTermination,flowBaseInfo);
                    }
                    if (Objects.equals(active, "druid")) {
                        // todo 短信
                        sendMessage(flowBaseInfo);
                    }
                    //更新代办任务数量
                    sysFormService.updateToDoNumber();
                    return AjaxResult.success();
                }
                return AjaxResult.error();
            }
            return AjaxResult.error();
        } catch (Exception e) {
            /*res.put("status",false);
            res.put("msg", "流程定义id为空, 无法开启流程！");*/
            e.printStackTrace();
            return AjaxResult.error("msg", "流程定义id为空, 无法开启流程！");

        }


    }
    @Override
    public AjaxResult complete(TProjectTermination tProjectTermination, FlowBaseInfo flow,HttpServletRequest request) throws Exception {
        //Task task=taskService.createTaskQuery().processInstanceId(tProjectApproval.getProcInstId()).singleResult();
        Task task = taskService.createTaskQuery().taskId(flow.getTaskId()).singleResult();
        if (Objects.isNull(task)) {
            return AjaxResult.error("任务不存在");
        }
        //当前你登录人
        SysUser userInfo=SecurityUtils.getLoginUser().getUser();
        Map<String, Object> rs = new HashMap<String, Object>();
        rs.put("status",true);
        Map<String, Object> formProperties = new HashMap<>();
        formProperties.put("auditPass", tProjectTermination.isFlag());

        Map<String, Object> fpMap = flowService.getFormProperties(task.getProcessDefinitionId(), task.getId());
        try {
            rs = flowService.taskComplete( task.getId(), tProjectTermination.isFlag(), formProperties, userInfo.getUserId().toString());
        } catch (Exception e) {
            e.printStackTrace();
            rs.put("status", false);
            rs.put("msg", "流程审批失败");
        }
        boolean status = (boolean) rs.get("status");
        // 审核成功, 则记录审核信息
        if (status) {
            TProjectPool tProjectPool=new TProjectPool();
            tProjectPool.setId(tProjectTermination.getProjectPoolId());

            //FlowBaseInfo flow = new FlowBaseInfo();
            if(flow==null){
                flow = new FlowBaseInfo();
            }
            flow.setId(UUIDGenerator.uuid());
            flow.setFormProperties(flowService.getFormProperties(fpMap, request.getParameterMap()));
            flow.setStatus(FlowStatusEnum.RUNNING.getName());
            flow.setProcDefId(task.getProcessDefinitionId());
            flow.setProcInsId(task.getProcessInstanceId());
            flow.setTaskDefKey(task.getTaskDefinitionKey());
            String isOk = tProjectTermination.isFlag() ? "[同意]" : "[驳回]";
            if ("modifyApply".equals(task.getTaskDefinitionKey())) {
                tProjectTermination.setStatus(tProjectTermination.isFlag() ? 1 : 4);
                isOk = tProjectTermination.isFlag() ? "[提交]" : "[关闭]";
            } else {
                tProjectTermination.setStatus(tProjectTermination.isFlag() ? 2 : 0);
            }
            if (null != flow.getComment()) {
                flow.setComment(isOk + flow.getComment());
            } else {
                flow.setComment(isOk);
            }
            flow.setTaskName(task.getName());
            flow.setCreateBy(SecurityUtils.getLoginUser().getUserId().toString());
            flow.setFlag(tProjectTermination.isFlag());
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).active().singleResult();
            // 表示流程已经审批结束了
            if (processInstance == null) {
                flow.setStatus(FlowStatusEnum.ENDED.getName());
                if (!"modifyApply".equals(task.getTaskDefinitionKey())) {
                    //关闭该项目存在的流程（投资机会、项目立项、尽职背调、项目投决）
                    tProjectTermination.setStatus(3);
                    tProjectPool.setUpdateBy(userInfo.getNickName());
                    tProjectPool.setProjectStatus("1");//项目机会状态为终止
                    // todo 增加项目创建记录
                    tProjectCirculationService.insertTProjectCirculation(tProjectPool.getId(),"项目终止完成", userInfo.getNickName());
                }else{
                    tProjectPool.setTerminationFlag("0");
                }
            }
            tProjectPoolService.updateTProjectPool(tProjectPool);
            tProjectTermination.setUpdateTime(DateUtils.getNowDate());
            terminationMapper.updateTProjectTermination(tProjectTermination);
            activitiBaseInfoService.addActivitiBaseInfo(flow);
            if(flow.isFlag()){
                getAssignee(tProjectTermination,flow);
            }
            if (Objects.equals(active, "druid")) {
                //todo 短信
                sendMessage(flow);
            }
        }
        return AjaxResult.success();
    }
    public TProjectMeeting selectTProjectMeetingByProcInstId(String pInstId){
        TProjectTermination tProjectTermination=this.selectTProjectTerminationByProcInstId(pInstId);
        TProjectMeeting tProjectMeeting=null;
        if(tProjectTermination!=null){
            tProjectMeeting=tProjectMeetingService.selectTProjectMeetingByProjectPoolId(tProjectTermination.getProjectPoolId());
        }
        return tProjectMeeting;
    }
    /**
     * 根据流程Id查询汇总分数和平均分数
     * @param pInstId
     * @return
     */
    @Override
    public Map<String, String> selectSumScore(String pInstId) {
        TProjectTermination tProjectTermination=this.selectTProjectTerminationByProcInstId(pInstId);
        Map<String, String> sumScore=new HashMap<>();
        if(tProjectTermination!=null){
            TProjectMeeting tProjectMeeting=tProjectMeetingService.selectTProjectMeetingByProjectPoolId(tProjectTermination.getProjectPoolId());
            sumScore=tProjectScoringMapper.selectMeetingId(tProjectMeeting.getId());
        }
        return sumScore;
    }
    /**
     * 根据项目ID获取最新终止申请
     * @param projectPoolId
     * @return
     */
    @Override
    public TProjectTermination listProjectPoolIdNew(String projectPoolId) {
        return terminationMapper.listProjectPoolIdNew(projectPoolId);
    }
    // todo 短信
    public void sendMessage(FlowBaseInfo flowBaseInfo) {
        boolean flag = flowBaseInfo.isFlag();
        String procInsId = flowBaseInfo.getProcInsId();
        // 待办任务
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInsId).list();
        // 对应业务单据
        ProjectTerminationVo projectTermination =terminationMapper.selectProjectTerminationByProcInstId(procInsId);
        if (projectTermination == null) {
            return;
        }
        // 申请人
        SysUser applyUserInfo = sysUserService.selectUserById(Long.valueOf(projectTermination.getCreateBy()));
        // 当前登录人
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();

        if(tasks.size()>0) {
            for (int i = 0; i < tasks.size(); i++) {
                Task task = tasks.get(i);
                if (task != null) {
                    if (Objects.equals(applyUserInfo.getUserId(), loginUser.getUserId()) && !flag) {
                        // 如果是申请人暂存或者关闭或者自己驳回，不用给自己发审批短信
                        continue;
                    } else {
                        // 申请人提交，给下一个审批人发短信
                        // 审批人同意，给下一个审批人发短信
                        if (flag) { //给审批人发送短信
                            String assignee = task.getAssignee();
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(assignee)) { // 给审批人发送短信
                                SysUser auditUser = sysUserService.selectUserById(Long.valueOf(assignee));
                                String auditContents = auditUser.getNickName() + ",您好。投资系统中" + projectTermination.getProjectName() + "的项目终止流程待处理，请查看！";
                                if (auditUser != null && StringUtils.isNotBlank(auditUser.getPhonenumber())) {
                                    try{
                                        SmsSenderUtils.sendSms(auditUser.getPhonenumber(), auditContents);
                                    } catch (IOException e) {
                                        logger.error("短信发送失败"+e.getMessage());
                                    }
                                }
                            }
                        } else { // 审批人驳回，给申请人发短信
                            String rejectContents = applyUserInfo.getNickName()+"，您好。你在投资系统中提交" + projectTermination.getProjectName() + "的项目终止申请已审核，结果为【驳回】，请查看！";
                            if (applyUserInfo != null && StringUtils.isNotBlank(applyUserInfo.getPhonenumber())) {
                                try{
                                    SmsSenderUtils.sendSms(applyUserInfo.getPhonenumber(), rejectContents);
                                } catch (IOException e) {
                                    logger.error("短信发送失败"+e.getMessage());
                                }
                            }
                        }
                    }
                }
            }
        }else{
            String completeContents ="";
            if(flag) {
                // 审批完成，给申请人发短信
                //XXX，您好。你在投资系统中提交“XXX”的项目终止申请已审核，结果为【通过】/【驳回】/【观望】！
                completeContents = applyUserInfo.getNickName()+"，您好。你在投资系统中提交" + projectTermination.getProjectName() + "的项目终止申请已审核，结果为【同意】，请查看！";
                if (applyUserInfo != null && StringUtils.isNotBlank(applyUserInfo.getPhonenumber())) {
                    try{
                        SmsSenderUtils.sendSms(applyUserInfo.getPhonenumber(), completeContents);
                    } catch (IOException e) {
                        logger.error("短信发送失败"+e.getMessage());
                    }
                }

            }
        }
    }
    /**
     * 跳节点
     * @param projectTermination
     * @param flow
     * @throws Exception
     */
    public void getAssignee(TProjectTermination projectTermination, FlowBaseInfo flow) throws Exception {
        SysUser sysUser=SecurityUtils.getLoginUser().getUser();//当前登陆人
        if (sysUser == null) {
            sysUser=sysUserService.selectUserById(Long.parseLong(projectTermination.getCreateBy()));
        }
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(flow.getProcInsId()).list();
        Long userId=sysUser.getUserId();
        for(int i = 0; i < tasks.size(); i++) {
            Task task = tasks.get(i);
            if (task == null || StringUtils.isBlank(task.getAssignee())) {
                return;
            }
            Long assignee = Long.parseLong(task.getAssignee());
            if ("deptLeader".equals(task.getTaskDefinitionKey()) && (userId.equals(assignee) || projectTermination.getCreateBy().equals(assignee))) {
                JumpNode(projectTermination, flow);
            }
        }
    }
    public Map<String, Object> JumpNode(TProjectTermination projectTermination, FlowBaseInfo flow) throws Exception{
        List<Task> list = taskService.createTaskQuery().processInstanceId(flow.getProcInsId()).list();
        String taskId=null;
        Map<String, Object> rs = new HashMap<String, Object>();
        rs.put("status",true);
        if (list.size()>0) {
            taskId = list.get(0).getId();
            flow.setTaskId(taskId);
            boolean flag = flow.isFlag();
            //当前流程节点Id信息
//            ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(flow.getProcInsId()).singleResult();
//            String activitiId = execution.getActivityId();
            Map<String, Object> formProperties = new HashMap<>();
            formProperties.put("auditPass", flow.isFlag());
            //部门负责人
            String leader=sysDeptMapper.selectDeptLeader("投资部");
            SysUser sysUser=sysUserService.selectUserByUserName(leader);
            formProperties.put("MANAGER",sysUser.getUserId());
            //当前登陆人
            Long userId=SecurityUtils.getUserId();
            try {
                //表单审核
                rs = flowService.taskComplete(taskId, flag, formProperties, userId.toString());
            } catch (Exception e) {
                e.printStackTrace();
                rs.put("status", false);
                rs.put("msg", "流程审批失败");
            }
            if (flow.isFlag()){
                getAssignee(projectTermination,flow);
            }

        }
        return rs;
    }
}
