package cn.stylefeng.workflow.instance.modular.task.strategy;

import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.workflow.api.entity.design.Node;
import cn.stylefeng.workflow.api.entity.instance.RuntimeNode;
import cn.stylefeng.workflow.api.entity.task.RuTask;
import cn.stylefeng.workflow.api.enums.strategy.AdjacentApproverSkipPolicyEnum;
import cn.stylefeng.workflow.api.enums.strategy.EmptyApproverStrategyEnum;
import cn.stylefeng.workflow.api.enums.strategy.SamePersonApprovalPolicyEnum;
import cn.stylefeng.workflow.api.pojo.InstanceContext;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverConfig;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverJumpStrategy;
import cn.stylefeng.workflow.instance.modular.task.strategy.emptyprocess.base.EmptyApproverRule;
import cn.stylefeng.workflow.instance.modular.task.strategy.sameneighbor.base.SameNeighborRule;
import cn.stylefeng.workflow.instance.modular.task.strategy.samesubmit.base.SameSubmitRule;

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

public class PreTaskProcessFactory {

    public static List<RuTask> processSameNeighbor(Node currentNode, List<RuTask> currentApproverTaskList, ApproverConfig approverConfig, InstanceContext instanceContext) {

        List<RuTask> finalRuTaskList = currentApproverTaskList;

        if (approverConfig == null) {
            return currentApproverTaskList;
        }

        ApproverJumpStrategy approverJumpStrategy = approverConfig.getApproverJumpStrategy();
        if (approverJumpStrategy == null) {
            return currentApproverTaskList;
        }

        Integer samePersonApprovalPolicy = approverJumpStrategy.getSamePersonApprovalPolicy();

        Map<String, SameSubmitRule> sameSubmitMap = SpringUtil.getBeansOfType(SameSubmitRule.class);
        for (SameSubmitRule sameSubmitRule : sameSubmitMap.values()) {
            SamePersonApprovalPolicyEnum sameSubmitRuleType = sameSubmitRule.getSameSubmitRuleType();
            if (sameSubmitRuleType.getCode().equals(samePersonApprovalPolicy)) {
                finalRuTaskList = sameSubmitRule.processSameSubmit(currentNode, currentApproverTaskList, instanceContext);
                break;
            }
        }

        Integer adjacentApproverSkipPolicy = approverJumpStrategy.getAdjacentApproverSkipPolicy();

        Map<String, SameNeighborRule> sameNeighborRuleMap = SpringUtil.getBeansOfType(SameNeighborRule.class);
        for (SameNeighborRule sameNeighborRule : sameNeighborRuleMap.values()) {
            AdjacentApproverSkipPolicyEnum strategyType = sameNeighborRule.getStrategyType();
            if (strategyType.getCode().equals(adjacentApproverSkipPolicy)) {
                finalRuTaskList = sameNeighborRule.processSameNeighbor(currentNode, finalRuTaskList, instanceContext);
                break;
            }
        }

        return finalRuTaskList;
    }

    public static void processEmptyApproverStrategy(Node currentNode, ApproverConfig approverConfig, InstanceContext instanceContext, RuntimeNode runtimeNode) {

        Integer emptyApproverStrategy = approverConfig.getApproverJumpStrategy().getEmptyApproverStrategy();

        Map<String, EmptyApproverRule> emptyApproverRuleMap = SpringUtil.getBeansOfType(EmptyApproverRule.class);
        for (EmptyApproverRule emptyApproverRule : emptyApproverRuleMap.values()) {
            EmptyApproverStrategyEnum strategyType = emptyApproverRule.getStrategyType();
            if (strategyType.getCode().equals(emptyApproverStrategy)) {
                emptyApproverRule.processEmptyApprover(currentNode, instanceContext, runtimeNode);
                break;
            }
        }

    }

}
