package com.dayou.workflow.handler;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
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.AssetsMapper;
import com.dayou.mapper.DepartmentMapper;
import com.dayou.mapper.WorkFlowNodeInstanceMapper;
import com.dayou.service.IAssetsProductionService;
import com.dayou.service.IUserPostService;
import com.dayou.service.workflow.IWorkFlowNodeInstanceService;
import com.dayou.service.workflow.IWorkNodeService;
import com.dayou.service.workflow.IWorkTaskRecordService;
import com.dayou.workflow.config.WorkNodeProcessable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
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.*;

@Component
public class AssetsNodeHandler extends WorkNodeProcessable {

    @Autowired
    private AssetsMapper assetsMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private IUserPostService userPostService;

    @Autowired
    private IWorkNodeService workNodeService;

    @Autowired
    private WorkFlowNodeInstanceMapper workFlowNodeInstanceMapper;

    @Autowired
    private IWorkFlowNodeInstanceService workFlowNodeInstanceService;

    @Autowired
    private IAssetsProductionService assetsProductionService;

    @Autowired
    private IWorkTaskRecordService workTaskRecordService;

    @Override
    public boolean forward(WorkNodeCommit workNodeCommit) {
        WorkFlowNodeInstance currentInstanceNode = workFlowNodeInstanceMapper.getById(workNodeCommit.getInstanceNodeId());
        WorkNodeDTO nextWorkNode = beforeForward(workNodeCommit, currentInstanceNode);
        if (ObjectUtil.isNotNull(nextWorkNode)) {
            String ifVerify = currentInstanceNode.getVerify();
            if (StrUtil.isNotEmpty(ifVerify)) {
                CallbackEnum callback = CallbackEnum.valueOf(ifVerify);
                //根据callback 确定具体的业务数据
                //获取产品类型
                List<ProductionEnum> production = workNodeCommit.getProduction();
                switch (callback) {
                    // 校验资产产品类型
                    case CHECK_ASSET_PRODUCTION_TYPE:
                        //1. 获取业务上出具的产品类型。
                        //2.根据出具的产品类型 确定需要哪些节点
                        Map<String, List<WorkflowNodeEnum>> assetsNecessaryNodes = CallbackEnum.NecessaryNode.getByProduction(MainBusinessEnum.ASSET_BUSINESS.name(),
                                production);
                        nextWorkNode = workNodeService.getNextWorkNodeByBusiness(currentInstanceNode.getFlowId(), MainBusinessEnum.ASSET_BUSINESS, currentInstanceNode.getNodeCode(), assetsNecessaryNodes);
                        break;
                    // 校验资产四审
                    case CHECK_ASSET_FOURTH_CHECK_REPORT:
                        // doFourthCheck为真则执行四审节点,为假则跳过四审节点
                        if (!workNodeCommit.getDoFourthCheck()) {
                            nextWorkNode = workNodeService.getNextWorkNodeByFourthCheckState(currentInstanceNode.getFlowId(), currentInstanceNode.getNodeCode());
                        }
                        break;
                    // 校验订单实收款
                    case CHECK_ASSET_ORDER_FUND:
                        // 产品已有实收款则跳过出库申请
                        if (workNodeCommit.getIfProductionFund()) {
                            nextWorkNode = workNodeService.getNextWorkNodeByFourthCheckState(currentInstanceNode.getFlowId(), currentInstanceNode.getNodeCode());
                        }
                        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.GENERATE_STATEMENT)) {
                    for (String businessSubId : workNodeCommit.getReportNos()) {
                        addNextInstanceNode(currentInstanceNode, nextWorkNode, workNodeCommit.getNextHandlerId(), businessSubId, null);
                    }
                } else if (workflowNodeEnum.equals(WorkflowNodeEnum.WRITE_REPORT)) {
                    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;
        }
        // 判断下一个节点为null,且当前节点为 归档 时, 返回TRUE
        if (ObjectUtil.isNull(nextWorkNode)){
            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.BUSINESS_ARCHIVING)){
                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);
    }

    /**
     * 选择节点处理人
     *
     * @param instanceNode         节点实列
     * @param handlerPermissionDTO
     * @return Long
     */
    @Override
    public Long searchHandlerId(WorkFlowNodeInstance instanceNode, HandlerPermissionDTO handlerPermissionDTO) {
        HandlerPermissionEnum handlerPermissionEnum = handlerPermissionDTO.getName();
        Assets assets = assetsMapper.selectOne(new LambdaQueryWrapper<Assets>().select(Assets::getClientManagerId, Assets::getPrincipalId)
                .eq(BaseEntity::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, assets.getDepartmentId())).getLeaderId()
                        : handlerId;
            case DEPARTMENT_LEADER:
                return departmentMapper.selectOne(new LambdaQueryWrapper<Department>().select(Department::getLeaderId).eq(BaseEntity::getId, assets.getDepartmentId())).getLeaderId();
            case CLIENT_MANAGER:
                return assets.getClientManagerId();
            case INITIATOR:
                return assets.getClientManagerId();
            case PRINCIPAL:
                return assets.getPrincipalId();
            case SYSTEM:
                //暂无程序处理逻辑
                return 0L;
            default:
                //实在找不到审批人 交由部门领导处理
                return departmentMapper.selectOne(new LambdaQueryWrapper<Department>().select(Department::getLeaderId).eq(BaseEntity::getId, assets.getDepartmentId())).getLeaderId();
        }
    }
}
