package cn.palmte.work.service;

import cn.palmte.work.bean.ApproveStatusEnum;
import cn.palmte.work.bean.StatusEnum;
import cn.palmte.work.config.activiti.ActConstant;
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 top.jfunc.common.utils.CollectionUtil;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @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;


    /**
     * 开启一个概算流程实例
     */
    public void startEstimateProcessInstance(Project project, Admin admin) throws Exception {
        startProcess(project, admin, ActConstant.PROCESS_DEFKEY_ESTIMATE);
    }

    /**
     * 返回概算的所有的实例id，没有则空集合
     */
    public List<String> getEstimateProcessInsIds(Project project){
        return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_ESTIMATE);
    }

    /**
     * 开启一个预算流程实例
     */
    public void startBudgetProcessInstance(Project project, Admin admin) throws Exception {
        startProcess(project, admin, ActConstant.PROCESS_DEFKEY_BUDGET);
    }
    /**
     * 返回预算的所有的实例id，没有则空集合
     */
    public List<String> getBudgetProcessInsIds(Project project){
        return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_BUDGET);
    }

    /**
     * 开启一个结算流程实例
     */
    public void startSettleProcessInstance(Project project, Admin admin) throws Exception {
        startProcess(project, admin, ActConstant.PROCESS_DEFKEY_SETTLE);
    }
    /**
     * 返回结算的所有的实例id，没有则空集合
     */
    public List<String> getSettleProcessInsIds(Project project){
        return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_SETTLE);
    }
    /**
     * 开启一个决算流程实例
     */
    public void startFinalProcessInstance(int projectId, Admin admin) throws Exception {
        Project project = projectRepository.findOne(projectId);
        startProcess(project, admin, ActConstant.PROCESS_DEFKEY_FINAL);
    }
    /**
     * 返回决算的所有的实例id，没有则空集合
     */
    public List<String> getFinalProcessInsIds(Project project){
        return getApproveInstanceIds(project, ActConstant.PROCESS_DEFKEY_FINAL);
    }
    private List<String> getApproveInstanceIds(Project project, String processDefkey) {
        List<ProjectInstanceRelation> all = projectInstanceRelationRepository.findAllByProjectIdEqualsAndProcessTypeEqualsOrderByCreateTimeDesc(project.getId(), processDefkey);
        if (CollectionUtil.isEmpty(all)) {
            return Collections.emptyList();
        }
        return all.stream().map(ProjectInstanceRelation::getProcessInsId).collect(Collectors.toList());
    }

    private void startProcess(Project project, Admin admin, String processDefkey) 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：{}", processDefkey, businessKey);
        String processInstanceId = actProcInsService.startProcessInstance(processDefkey, businessKey, variables);

        //保存流程实例id与项目的关联关系
        ProjectInstanceRelation relation = new ProjectInstanceRelation();
        relation.setProjectId(project.getId());
        relation.setProcessType(processDefkey);
        relation.setProcessInsId(processInstanceId);
        relation.setCreateTime(new Date());
        projectInstanceRelationRepository.saveAndFlush(relation);
    }

    /**
     * 更新审批人，用于在任务监听器中更新下个审批人
     * @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 ActConstant#PROCESS_DEFKEY_ESTIMATE
     * @see ActConstant#PROCESS_DEFKEY_BUDGET
     * @see ActConstant#PROCESS_DEFKEY_SETTLE
     * @see ActConstant#PROCESS_DEFKEY_FINAL
     */
    public void updateApproveStatus(int projectId, String processKey, ApproveStatusEnum approveStatusEnum){
        Project project = projectRepository.findOne(projectId);
        if(ActConstant.PROCESS_DEFKEY_ESTIMATE.equals(processKey)){
            project.setApproveStatusEstimate(approveStatusEnum.getApproveStatus());
        }else if(ActConstant.PROCESS_DEFKEY_BUDGET.equals(processKey)){
            project.setApproveStatusBudget(approveStatusEnum.getApproveStatus());
        }else if(ActConstant.PROCESS_DEFKEY_SETTLE.equals(processKey)){
            project.setApproveStatusSettle(approveStatusEnum.getApproveStatus());
        }else if(ActConstant.PROCESS_DEFKEY_FINAL.equals(processKey)){
            project.setApproveStatusFinal(approveStatusEnum.getApproveStatus());
        }

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

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


}
