package cn.stylefeng.workflow.instance.core.condition;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.roses.kernel.sys.api.OrgApproverServiceApi;
import cn.stylefeng.roses.kernel.sys.api.enums.org.DetectModeEnum;
import cn.stylefeng.workflow.api.enums.ApproverTypeEnum;
import cn.stylefeng.workflow.api.enums.FormFieldTypeEnum;
import cn.stylefeng.workflow.api.pojo.InstanceContext;
import cn.stylefeng.workflow.api.pojo.InstanceVariable;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverConfig;
import cn.stylefeng.workflow.api.pojo.config.node.approver.ApproverSummary;
import cn.stylefeng.workflow.api.pojo.config.node.approver.detail.NodeApproverVariable;
import cn.stylefeng.workflow.instance.core.condition.base.BaseApproverRule;
import lombok.extern.slf4j.Slf4j;

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

@Slf4j
public class VariableApproverRule extends BaseApproverRule {

    @Override
    public boolean approverEvaluate(InstanceContext instanceContext, ApproverConfig approverConfig) {
        ApproverSummary mainApprover = approverConfig.getMainApprover();
        if (ObjectUtil.isEmpty(mainApprover)) {
            return false;
        }

        if (!ApproverTypeEnum.VARIABLE_SELECT.getValue().equals(mainApprover.getApproverType())) {
            return false;
        }

        List<NodeApproverVariable> approverVariableList = mainApprover.getNodeApproverVariableList();
        if (ObjectUtil.isEmpty(approverVariableList)) {
            return false;
        }

        return true;
    }

    @Override
    public void approverExecute(InstanceContext instanceContext, ApproverConfig approverConfig) {

        InstanceVariable instanceVariable = instanceContext.getInstanceVariable();
        if (instanceVariable == null) {
            return;
        }

        Map<String, Object> customVueFormData = instanceVariable.getCustomVueFormData();
        if (ObjectUtil.isEmpty(customVueFormData)) {
            return;
        }

        ApproverSummary mainApprover = approverConfig.getMainApprover();
        if (mainApprover == null) {
            return;
        }
        List<NodeApproverVariable> nodeApproverVariableList = mainApprover.getNodeApproverVariableList();
        if (ObjectUtil.isEmpty(nodeApproverVariableList)) {
            return;
        }

        List<Long> userIdList = new ArrayList<>();
        for (NodeApproverVariable nodeApproverVariable : nodeApproverVariableList) {

            String fieldCode = nodeApproverVariable.getFieldCode();

            Object fieldValue = customVueFormData.get(fieldCode);
            List<Long> bizIdList = getFieldValue(fieldValue);
            if (bizIdList == null || bizIdList.isEmpty()) {
                continue;
            }

            if (FormFieldTypeEnum.PERSONAL.getValue().equals(nodeApproverVariable.getVariableFieldType())) {
                userIdList.addAll(bizIdList);
            }

            else if (FormFieldTypeEnum.DEPT.getValue().equals(nodeApproverVariable.getVariableFieldType())) {
                OrgApproverServiceApi orgApproverServiceApi = SpringUtil.getBean(OrgApproverServiceApi.class);
                for (Long orgId : bizIdList) {
                    List<Long> tempUserIdList = orgApproverServiceApi.getDeptOrgApprover(orgId, Convert.toInt(nodeApproverVariable.getApproveGroupType()), 0, DetectModeEnum.TO_TOP);
                    if (ObjectUtil.isNotEmpty(tempUserIdList)) {
                        userIdList.addAll(tempUserIdList);
                    }
                }
            }
        }

        if (ObjectUtil.isNotEmpty(userIdList)) {
            setResult(userIdList);
        }
    }

    @Override
    public String getBaseRuleName() {
        return VariableApproverRule.class.getName();
    }

    @Override
    public int getBaseRulePriority() {
        return 800;
    }

    private static List<Long> getFieldValue(Object obj) {

        if (obj instanceof Long) {
            return ListUtil.of((Long) obj);
        }

        else if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            if (!list.isEmpty() && list.get(0) instanceof Long) {
                return (List<Long>) list;
            }
        }

        return null;
    }

}




