package cn.palmte.work.service;


import cn.palmte.work.config.activiti.ActApproveTypeEnum;
import cn.palmte.work.config.activiti.ActConstant;
import cn.palmte.work.config.activiti.ActProcessKeyEnum;
import cn.palmte.work.config.activiti.ActProjectTypeEnum;
import cn.palmte.work.exception.ResponseException;
import cn.palmte.work.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xiongshiyan at 2021/10/29 , contact me with email yanshixiong@126.com or phone 15208384257
 */
@Service
public class ProjectInstanceService {
    private static final Logger logger = LoggerFactory.getLogger(ActProcInsService.class);
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private AdminService adminService;
    @Autowired
    private ActProcInsService actProcInsService;
    @Autowired
    private ProjectInstanceRelationRepository projectInstanceRelationRepository;
    @Autowired
    private ActTaskDefService actTaskDefService;


    /**
     * 通过项目id发起流程实例
     *
     * @param projectId
     * @param projectEnum
     * @param map
     * @throws Exception
     */
    public void startProcessByProjectId(int projectId, ActProjectTypeEnum projectEnum, Map<String, Object> map) throws Exception {
        ActProcessKeyEnum keyEnum;
        if (projectEnum == ActProjectTypeEnum.SALE_CONTRACT) {
            keyEnum = ActProcessKeyEnum.SALE_CONTRACT;
        } else if (projectEnum == ActProjectTypeEnum.BUSINESS_PURCHASE) {
            keyEnum = ActProcessKeyEnum.BUSINESS_PURCHASE;
        }else{
            throw new ResponseException("不支持的项目类型");
        }
        String processDefkey = keyEnum.getKey();
        String businessKey = String.valueOf(projectId);
        logger.info("startSaleContractProcess processDefkey:{}, businessKey：{}", processDefkey, businessKey);
        String processInstanceId = actProcInsService.startProcessInstance(processDefkey, businessKey, map);
        saveProjectInstance(projectId, processInstanceId, keyEnum, projectEnum);
    }


    /**
     * 通过项目id和项目类型完成审批任务
     *
     * @param projectId 项目唯一id
     * @param projectEnum 项目类型
     * @param approveEnum 审批状态
     * @param message 审批意见
     * @return
     */
    public boolean completeTaskByProjectId(int projectId, ActProjectTypeEnum projectEnum,
                                           ActApproveTypeEnum approveEnum, String message) {
        ProjectInstanceRelation projectInstance = projectInstanceRelationRepository.findByProjectIdAndProjectType(
                projectId, projectEnum.getType());
        if (projectInstance == null) {
            return false;
        }

        actTaskDefService.completeTaskByProcInsId(projectInstance.getProcessInsId(), approveEnum, message);
        return true;
    }


    private void saveProjectInstance(int projectId, String processInstanceId,
                                     ActProcessKeyEnum keyEnum, ActProjectTypeEnum projectTypeEnum) {
        //保存流程实例id与项目的关联关系
        ProjectInstanceRelation relation = new ProjectInstanceRelation();
        relation.setProjectId(projectId);
        relation.setProjectType(projectTypeEnum.getType());
        relation.setProcessType(keyEnum.getKey());
        relation.setProcessInsId(processInstanceId);
        relation.setCreateTime(new Date());
        projectInstanceRelationRepository.saveAndFlush(relation);
    }

    /**
     *  发起四算项目流程
     *
     * @param project
     * @param keyEnum
     * @throws Exception
     */
    public void startFourcalProcess(Project project, ActProcessKeyEnum keyEnum) throws Exception {
        HashMap<String, Object> variables = new HashMap<>();
        variables.put(ActConstant.KEY_PROJECT_TYPE, project.getType());
        String businessKey = String.valueOf(project.getId());
        logger.info("startProcess processDefkey:{}, businessKey：{}", keyEnum.getKey(), businessKey);
        String processInstanceId = actProcInsService.startProcessInstance(keyEnum.getKey(), businessKey, variables);

        saveProjectInstance(project.getId(), processInstanceId, keyEnum, ActProjectTypeEnum.FOURCAL);
    }


    public String startProcessBySystem(Project project, ActProcessKeyEnum keyEnum, ProjectTaskRecord taskRecord) throws Exception {
        HashMap<String, Object> variables = new HashMap<>();
        variables.put(ActConstant.KEY_PROJECT_TYPE, project.getType());
        String businessKey = String.valueOf(project.getId());
        logger.info("startProcessBySystem processDefkey:{}, businessKey：{}", keyEnum.getKey(), businessKey);

        String processInstanceId = actProcInsService.startProcessInstanceBySystem(
                keyEnum.getKey(), businessKey, variables, taskRecord);

        saveProjectInstance(project.getId(), processInstanceId, keyEnum, ActProjectTypeEnum.FOURCAL);
        return processInstanceId;
    }

    /**
     * 更新审批人，用于在任务监听器中更新下个审批人
     *
     * @param projectId 项目id
     * @param adminId 审批人id
     */
    public void updateApprover(int projectId, int adminId){
        Project project = projectRepository.findOne(projectId);
        if (project == null) {
            return;
        }
        if (adminId == 0) {
            project.setApproveName("");
        }else {
            Admin admin = adminService.getAdminById(adminId);
            project.setApproveName(admin.getRealName());
        }
        project.setApproveId(adminId);
        project.setLastUpdateTime(new Date());
        projectRepository.saveAndFlush(project);
    }

    /**
     * 更新审批状态
     * @param processKey 审批类型
     * @see ActProcessKeyEnum
     */
    public void updateApproveStatus(int projectId, String processKey, ActApproveTypeEnum approveTypeEnum){
        Project project = projectRepository.findOne(projectId);
        if(ActProcessKeyEnum.ESTIMATE.getKey().equals(processKey)){
            project.setApproveStatusEstimate(approveTypeEnum.getType());
        }else if(ActProcessKeyEnum.BUDGET.getKey().equals(processKey)){
            project.setApproveStatusBudget(approveTypeEnum.getType());
        }else if(ActProcessKeyEnum.SETTLE.getKey().equals(processKey)){
            project.setApproveStatusSettle(approveTypeEnum.getType());
        }else if(ActProcessKeyEnum.FINAL.getKey().equals(processKey)){
            project.setApproveStatusFinal(approveTypeEnum.getType());
        }

        if (approveTypeEnum == ActApproveTypeEnum.APPROVAL_PASSED) {
            //审批通过设置审批人为空
            project.setApproveId(0);
            project.setApproveName("");
        }

        project.setLastUpdateTime(new Date());
        projectRepository.saveAndFlush(project);
    }


}
