package cc.smtweb.system.bpm.web.design.flow;

import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.system.bpm.web.design.flow.define.Activity;
import cc.smtweb.system.bpm.web.design.flow.define.ProcInfo;
import cc.smtweb.system.bpm.web.design.flow.define.Trans;
import cc.smtweb.system.bpm.web.sys.base.billFlow.BillFlow;
import cc.smtweb.system.bpm.web.sys.base.billFlow.BillFlowCache;
import cc.smtweb.system.bpm.web.sys.user.userGroup.UserGroupHelper;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

/**
 * Created by Akmm at 2022-08-02 18:38
 * 工作流定义辅助类
 */
public class ModelProcHelper {
    public static ModelProc getFromCache(long proc_id) {
        return ModelProcCache.getInstance().get(proc_id);
    }

    public static ProcInfo getProcFromCache(long proc_id) {
        ModelProc proc = getFromCache(proc_id);
        if (proc == null) return null;
        return proc.getProcInfo();
    }

    /**
     * 获取配置的工作流程定义
     *
     * @param bill_type 单据类型，常量
     * @param user_id
     * @return
     */
    public static ModelProc getBillProc(long bill_type, long user_id) {
        Set<BillFlow> list = BillFlowCache.getInstance().getByBillType(bill_type);

        if (CommUtil.isEmpty(list)) {
            return null;
        }
        long pcid = 0L;
        for (BillFlow bean : list) {
            //找到一个就走
            if (UserGroupHelper.isInGroup(user_id, bean.getUserGroup())) {
                pcid = bean.getProc();
                break;
            }
        }

        return getFromCache(pcid);
    }

    /**
     * 得到流程的第一个活动步骤（开始节点出来的第一个节点）
     *
     * @param proc_id
     * @return
     */
    public static Activity getFirstActivity(long proc_id) {
        ProcInfo proc = getProcFromCache(proc_id);
        if (proc == null) return null;
        Activity start = null;
        //先找开始节点
        List<Activity> list = proc.getActivities();
        for (Activity act : list) {
            if (act.getType() == FlowConst.ActivityType.START.value) {
                start = act;
                break;
            }
        }
        if (start == null) return null;

        //开始节点出去的第一个节点就是制单节点
        for (Trans trans : proc.getTrans()) {
            if (start.getId().equals(trans.getSrc())) {
                return proc.findActivity(trans.getDst());
            }
        }
        return null;
    }

    /**
     * 得到指定活动的下一任务节点
     *
     * @param act_id
     * @return
     */
    public static Activity getNextActivity(long proc_id, String act_id) throws BizException {
        ProcInfo proc = getProcFromCache(proc_id);
        if (proc == null) return null;
        Activity act = proc.findActivity(act_id);
        if (act == null) {
            throw new BizException("未找到指定的活动节点定义！");
        }
        List<Trans> list = proc.getTrans();
        for (Trans t : list) {
            if (act_id.equals(t.getSrc())) {
                act = proc.findActivity(t.getDst());
                return act;
            }
        }

        return null;
    }

    /**
     * 得到指定活动的流出转移条件列表，按序号排序，act为并发/条件分支
     *
     * @param act_id
     * @return
     */
    public static List<Trans> getNextTrans(long proc_id, String act_id) throws BizException {
        ProcInfo proc = getProcFromCache(proc_id);
        if (proc == null) return null;
        Activity act = proc.findActivity(act_id);
        if (act == null) {
            throw new BizException("未找到指定的活动节点定义！");
        }

        List<Trans> listRet = new ArrayList<>();
        List<Trans> list = proc.getTrans();
        for (Trans t : list) {
            if (act_id.equals(t.getSrc())) {
                listRet.add(t);
            }
        }
        listRet.sort(Comparator.comparingInt(Trans::getSeq));
        return listRet;
    }

    /**
     * 获取流程定义属性值
     *
     * @param proc_id 流程定义id
     * @param ele_id  元素id
     * @param key     属性名
     * @return
     */
    /*public static String getPropStr(String proc_id, String ele_id, String key) {
//        return PropertyEntityBuffer.getInstance().getPropValue(proc_id, ele_id, key);
        return null;
    }

    public static boolean getPropBool(String proc_id, String ele_id, String key) {
//        return UtilPub.toBoolean(getPropStr(proc_id, ele_id, key), false);
        return false;
    }

    public static int getPropInt(String proc_id, String ele_id, String key) {
//        return UtilPub.getIntIgnoreErr(getPropStr(proc_id, ele_id, key));
        return 0;
    }*/
}
