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

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.workflow.api.entity.design.Node;
import cn.stylefeng.workflow.api.entity.task.RuTask;
import cn.stylefeng.workflow.api.enums.NodeTypeEnum;
import cn.stylefeng.workflow.api.enums.strategy.AdjacentApproverSkipPolicyEnum;
import cn.stylefeng.workflow.api.pojo.InstanceContext;
import cn.stylefeng.workflow.instance.api.pojo.task.RuTaskRequest;
import cn.stylefeng.workflow.instance.core.path.NodePathCalc;
import cn.stylefeng.workflow.instance.modular.task.service.RuTaskService;
import jakarta.annotation.Resource;

import java.util.List;

public abstract class SameNeighborRule {

    @Resource
    private RuTaskService ruTaskService;

    public abstract AdjacentApproverSkipPolicyEnum getStrategyType();

    public abstract void processTask(RuTask originTask);

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

        Integer nodeType = currentNode.getNodeType();
        if (NodeTypeEnum.START.getNodeType().equals(nodeType) || NodeTypeEnum.APPLICANT.getNodeType().equals(nodeType)) {
            return currentApproverTaskList;
        }

        NodePathCalc nodePathCalc = new NodePathCalc(instanceContext);
        Long beforeApproveNode = nodePathCalc.getNodeBeforeApproveNode(currentNode.getNodeId());

        if (ObjectUtil.isEmpty(beforeApproveNode)) {
            return currentApproverTaskList;
        }

        RuTaskRequest ruTaskRequest = new RuTaskRequest();
        ruTaskRequest.setInstanceId(instanceContext.getRuntimeInstance().getInstanceId());
        ruTaskRequest.setReNodeId(beforeApproveNode);
        List<RuTask> list = ruTaskService.findList(ruTaskRequest);

        if (ObjectUtil.isEmpty(list)) {
            return currentApproverTaskList;
        }

        for (RuTask lastTask : list) {
            for (RuTask currentTask : currentApproverTaskList) {
                if (lastTask.getApprover().equals(currentTask.getApprover())) {
                    this.processTask(currentTask);
                }
            }
        }

        return currentApproverTaskList;
    }

}
