package com.dayou.workflow.handler;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dayou.common.BaseEntity;
import com.dayou.dto.HandlerPermissionDTO;
import com.dayou.dto.WorkNodeCommit;
import com.dayou.dto.WorkNodeDTO;
import com.dayou.entity.*;
import com.dayou.enums.MainBusinessEnum;
import com.dayou.enums.ProductionEnum;
import com.dayou.enums.workflow.CallbackEnum;
import com.dayou.enums.workflow.HandlerPermissionEnum;
import com.dayou.enums.workflow.WorkflowNodeEnum;
import com.dayou.mapper.*;
import com.dayou.service.IUserPostService;
import com.dayou.service.IUserService;
import com.dayou.service.workflow.IWorkFlowNodeInstanceService;
import com.dayou.service.workflow.IWorkNodeService;
import com.dayou.workflow.config.WorkNodeProcessable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static com.dayou.enums.workflow.NodeStateEnum.SKIP;
import static com.dayou.enums.workflow.WorkflowNodeEnum.*;

/**
 * 类说明：
 *
 * @author: wucl
 * @since: 2023/11/1
 * created with IntelliJ IDEA.
 */
@Component
public class MajorNodeHandler extends WorkNodeProcessable {

    @Autowired
    private IWorkFlowNodeInstanceService workFlowNodeInstanceService;
    @Autowired
    private WorkFlowNodeInstanceMapper workFlowNodeInstanceMapper;
    @Autowired
    private MajorProductionMapper majorProductionMapper;
    @Autowired
    private MajorTargetMapper majorTargetMapper;
    @Autowired
    private MajorMapper majorMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private IUserPostService userPostService;
    @Autowired
    private IWorkNodeService workNodeService;

    @Autowired
    private IUserService userService;


    @Override
    public boolean forward(WorkNodeCommit workNodeCommit) {
        WorkFlowNodeInstance currentInstanceNode = workFlowNodeInstanceMapper.getById(workNodeCommit.getInstanceNodeId());
        WorkNodeDTO nextWorkNode = beforeForward(workNodeCommit,currentInstanceNode);
        if (nextWorkNode!=null){
            String ifVerify = currentInstanceNode.getVerify();
            if (StrUtil.isNotEmpty(ifVerify)){
                CallbackEnum callback = CallbackEnum.valueOf(ifVerify);
                if (callback !=null){
                    //根据callback 确定具体的业务数据
                    //获取产品类型
                    List<ProductionEnum> production = workNodeCommit.getProduction();
                    switch (callback){
                        case CHECK_PRODUCTION_CHECK:
                            nextWorkNode = workNodeService.getNextWorkNodeByCheckState(currentInstanceNode.getFlowId(),currentInstanceNode.getNodeCode(),
                                    workNodeCommit.getDoSecondCheck(),workNodeCommit.getDoThirdCheck());
                            break;
                        case CHECK_PRODUCTION_TYPE:
                            //1. 获取业务上出具的产品类型。
                            //2.根据出具的产品类型 确定需要哪些节点
                            Map<String,List<WorkflowNodeEnum>> majorNecessaryNodes = CallbackEnum.NecessaryNode.getByProduction(MainBusinessEnum.MAJOR_BUSINESS.name(),
                                    production);
                            nextWorkNode = workNodeService.getNextWorkNodeByBusiness(currentInstanceNode.getFlowId(),MainBusinessEnum.MAJOR_BUSINESS,currentInstanceNode.getNodeCode(), majorNecessaryNodes);
                            break;
                        case CHECK_PRODUCTION_FUND:
                            //出库申请：已收款不用部门审核，直接到财务审核
                            if (workNodeCommit.getIfProductionFund()){
                                nextWorkNode = workNodeService.getNextWorkNode(nextWorkNode.getFlowId(), nextWorkNode.getId());
                            }
                            break;
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(workNodeCommit.getReportNos())){

                //主流程分支
                String code = workNodeService.getOne(new LambdaQueryWrapper<WorkNode>()
                        .select(WorkNode::getCode)
                        .eq(BaseEntity::getId, currentInstanceNode.getNodeId()).eq(BaseEntity::getDeleted, Boolean.FALSE)).getCode();
                WorkflowNodeEnum workflowNodeEnum = WorkflowNodeEnum.valueOf(code);

                if (workflowNodeEnum.equals(WorkflowNodeEnum.WRITE_STATEMENT)){
                    for (String businessSubId :workNodeCommit.getReportNos()){
                        addNextInstanceNode(currentInstanceNode,nextWorkNode, workNodeCommit.getNextHandlerId(),businessSubId,null);
                    }
                }
                else if(workflowNodeEnum.equals(WorkflowNodeEnum.WRITE_REPORT) || workflowNodeEnum.equals(WorkflowNodeEnum.WRITE_LETTER)){
                    for (String businessMinId :workNodeCommit.getReportNos()){
                        addNextInstanceNode(currentInstanceNode,nextWorkNode, workNodeCommit.getNextHandlerId(),workNodeCommit.getBusinessSubId(),businessMinId);
                    }
                }else {
                    addNextInstanceNode(currentInstanceNode,nextWorkNode, workNodeCommit.getNextHandlerId(),workNodeCommit.getBusinessSubId(),workNodeCommit.getBusinessMinId());
                }
            }
            else {
                addNextInstanceNode(currentInstanceNode,nextWorkNode, workNodeCommit.getNextHandlerId(),workNodeCommit.getBusinessSubId(),workNodeCommit.getBusinessMinId());
            }
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean skip(WorkNodeCommit workNodeCommit){
        WorkFlowNodeInstance instanceNode = workFlowNodeInstanceService.getById(workNodeCommit.getInstanceNodeId());
         workFlowNodeInstanceService.update(new LambdaUpdateWrapper<WorkFlowNodeInstance>().set(WorkFlowNodeInstance::getState,SKIP)
                .set(WorkFlowNodeInstance::getComment,workNodeCommit.getComments())
                .eq(WorkFlowNodeInstance::getId,workNodeCommit.getInstanceNodeId()));
        //添加日志
        return addWorkflowLog(workNodeCommit,instanceNode);
    }

    @Override
    public boolean goBack(WorkNodeCommit commit){
        Long instanceNodeId = commit.getInstanceNodeId();
        WorkFlowNodeInstance currentNode = workFlowNodeInstanceMapper.getInstanceNodeInfoById(instanceNodeId);
        //如果是撰写节点（意见书，报告，复评函）退回。需删除产品业务信息
        List<String> writeNodes = Arrays.asList(new String[]{WRITE_STATEMENT.name(), WRITE_REPORT.name(), WRITE_LETTER.name()});
        if (writeNodes.contains(currentNode.getNodeCode()) && commit.getCleanReportNo()!=null && commit.getCleanReportNo()){
            //是否取号？
            List<String> reportNos =  majorTargetMapper.getSubReportNo(currentNode.getBusinessId());
            if (CollectionUtil.isNotEmpty(reportNos)){
                //清除子号
                majorTargetMapper.cleanSubReportNo(currentNode.getBusinessId());
                //清除产品信息
                majorProductionMapper.delete(new LambdaQueryWrapper<MajorProduction>().eq(MajorProduction::getMajorId,currentNode.getBusinessId()));
            }
        }
        return super.goBack(commit);
    }

    @Override
    public Long searchHandlerId(WorkFlowNodeInstance instanceNode, HandlerPermissionDTO handlerPermissionDTO){
        HandlerPermissionEnum handlerPermissionEnum = handlerPermissionDTO.getName();
        Major major = majorMapper.selectOne(new LambdaQueryWrapper<Major>()
                        .select(Major::getDepartmentId,Major::getClientManagerId,Major::getPrincipalId).eq(Major::getId,instanceNode.getBusinessId()));
        switch (handlerPermissionEnum){
            case EMPLOYEE:
                return handlerPermissionDTO.getPowerId();
            case POST:
                Long handlerId = userPostService.getUniqueHandlerByPostForWorkNode(handlerPermissionDTO.getPowerId());
                return handlerId==null?
                        departmentMapper.selectOne(new LambdaQueryWrapper<Department>().select(Department::getLeaderId).eq(BaseEntity::getId, major.getDepartmentId())).getLeaderId()
                        :handlerId;
            case DEPARTMENT_LEADER:
                return departmentMapper.selectOne(new LambdaQueryWrapper<Department>().select(Department::getLeaderId).eq(BaseEntity::getId, major.getDepartmentId())).getLeaderId();
            case CLIENT_MANAGER:
            case INITIATOR:
                return major.getClientManagerId();
            case PRINCIPAL:
                return major.getPrincipalId();
            case PREVIOUS_HANDLER_LEADER:
                return userService.getLeaderByCurrentUser();
            case SYSTEM:
                //暂无程序处理逻辑
                return 0L;
            default:
                //实在找不到审批人 交由部门领导处理
                return departmentMapper.selectOne(new LambdaQueryWrapper<Department>().select(Department::getLeaderId).eq(BaseEntity::getId, major.getDepartmentId())).getLeaderId();
        }
    }
}
