import { ILogicNode } from "@/interface/logic";
import {
    UIActionContext,
    UILogicAppendParamNode,
    UILogicBeginNode,
    UILogicBindParamNode,
    UILogicCopyParamNode,
    UILogicDataSetNode,
    UILogicDeActionNode,
    UILogicDebugParamNode,
    UILogicDeLogicNode,
    UILogicDeUIActionNode,
    UILogicEndNode,
    UILogicMsgboxNode,
    UILogicPrepareParamNode,
    UILogicRawCodeNode,
    UILogicReNewParamNode,
    UILogicResetParamNode,
    UILogicSortParamNode,
    UILogicThrowExceptionNode,
    UILogicViewctrlFireEventNode,
    UILogicViewctrlInvokeNode
} from "@/logic/ui-logic";

/**
 * 打开语雀文档
 *
 * @export
 * @class OpenYuQueUILogicBase
 */
export default class OpenYuQueUILogicBase {

    /**
     * Creates an instance of  OpenYuQueBase.
     * 
     * @param {*} [opts={}]
     * @memberof OpenYuQueUILogicBase
     */
    constructor(opts: any = {}) { }

    /**
     * 开始节点
     *
     * @protected
     * @type {string}
     * @memberof OpenYuQueUILogicBase
     */
    protected readonly startLogicNode: string = 'Begin';

    /**
     * 逻辑参数
     *
     * @protected
     * @type {any[]}
     * @memberof OpenYuQueUILogicBase
     */
    protected logicParams: any[] = [
        {
            name: '传入变量',
            codeName: 'Default',
            activeContainerParam: false,
            activeCtrlParam: false,
            activeViewParam: false,
            appGlobalParam: false,
            applicationParam: false,
            ctrlParam: false,
            default: true,
            entityParam: true,
            entityListParam: false,
            entityPageParam: false,
            filterParam: false,
            navContextParam: false,
            simpleParam: false,
            simpleListParam: false,
            routeViewSessionParam: false,
            viewNavDataParam: false,
            viewSessionParam: false,
            lastReturnParam: false
        },
    ];

    /**
     * 逻辑节点
     *
     * @protected
     * @type {ILogicNode[]}
     * @memberof OpenYuQueUILogicBase
     */
    protected logicNodes: ILogicNode[] = [
        { codeName: 'Begin', name: '开始', logicNodeType: 'BEGIN', logicLinks: [ { name: '连接名称', dstLogicNode: 'DEUIACTION1', } ] },
        { codeName: 'END1', name: '结束', logicNodeType: 'END', returnType: 'NONEVALUE', returnRawValue: '', },
        { codeName: 'DEUIACTION1', name: '界面行为', logicNodeType: 'DEUIACTION', dstParam: 'Default', logicLinks: [ { name: '连接名称', dstLogicNode: 'END1', } ] },
    ];

    /**
     * 执行前
     *
     * @param {*} args
     * @param {*} [context={}]
     * @param {*} [params={}]
     * @param {*} [$event]
     * @param {*} [xData]
     * @param {*} [actioncontext]
     * @param {string} [srfParentDeName]
     * @return {*} 
     * @memberof OpenYuQueUILogicBase
     */
    public beforeExecute(args: any, context: any = {}, params: any = {},
        $event?: any, xData?: any, actioncontext?: any, srfParentDeName?: string) {
        return new UIActionContext(this.logicParams, args, context, params, $event, xData, actioncontext, srfParentDeName)
    }

    /**
     * 执行
     *
     * @param {any[]} args
     * @param {*} [context={}]
     * @param {*} [params={}]
     * @param {*} [$event]
     * @param {*} [xData]
     * @param {*} [actionContext]
     * @param {string} [srfParentDeName]
     * @memberof OpenYuQueUILogicBase
     */
    async execute(args: any[], context:any = {} ,params: any = {}, $event?: any, xData?: any, actioncontext?: any, srfParentDeName?: string) {
        try {
            const actionContext = this.beforeExecute(args, context, params, $event, xData, actioncontext, srfParentDeName);
            if (!this.startLogicNode) {
                throw new Error('没有开始节点');
            }
            await this.executeNode(this.startLogicNode, actionContext);
            return actionContext.getResult();
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }

    /**
     * 执行节点
     *
     * @param {ILogicNode} logicNode
     * @param {UIActionContext} actionContext
     * @memberof OpenYuQueUILogicBase
     */
    async executeNode(logicNodeName: string, actionContext: UIActionContext) {
        const logicNode = this.logicNodes.find((node: ILogicNode) => node.codeName === logicNodeName) as ILogicNode;
        if (!logicNode) {
            console.log(`未找到 ${logicNodeName} 节点`);
        }
        let result: any = { actionContext };
        try {
            switch (logicNode.logicNodeType) {
                // 开始节点
                case 'BEGIN':
                    result = await new UILogicBeginNode().executeNode(logicNode, actionContext);
                    break;
                // 准备参数节点
                case 'PREPAREJSPARAM':
                    result = await new UILogicPrepareParamNode().executeNode(logicNode, actionContext);
                    break;
                // 重置参数节点
                case 'RESETPARAM':
                    result = await new UILogicResetParamNode().executeNode(logicNode, actionContext);
                    break;
                // 拷贝参数
                case 'COPYPARAM':
                    result = await new UILogicCopyParamNode().executeNode(logicNode, actionContext);
                    break;
                // 绑定参数
                case 'BINDPARAM':
                    result = await new UILogicBindParamNode().executeNode(logicNode, actionContext);
                    break;
                // 重新建立参数
                case 'RENEWPARAM':
                    result = await new UILogicReNewParamNode().executeNode(logicNode, actionContext);
                    break;
                // 调用实体界面行为
                case 'DEUIACTION':
                    result = await new UILogicDeUIActionNode().executeNode(logicNode, actionContext);
                    break;
                // 行为处理节点
                case 'DEACTION':
                    result = await new UILogicDeActionNode().executeNode(logicNode, actionContext);
                    break;
                // 实体处理逻辑
                case 'DELOGIC':
                    result = await new UILogicDeLogicNode().executeNode(logicNode, actionContext);
                    break;
                // 实体数据集
                case 'DEDATASET':
                    result = await new UILogicDataSetNode().executeNode(logicNode, actionContext);
                    break;
                // 附加到数组参数
                case 'APPENDPARAM':
                    result = await new UILogicAppendParamNode().executeNode(logicNode, actionContext);
                    break;
                // 排序数组参数
                case 'SORTPARAM':
                    result = await new UILogicSortParamNode().executeNode(logicNode, actionContext);
                    break;
                // 视图部件调用
                case 'VIEWCTRLINVOKE':
                    result = await new UILogicViewctrlInvokeNode().executeNode(logicNode, actionContext);
                    break;
                // 视图部件事件触发
                case 'VIEWCTRLFIREEVENT':
                    result = await new UILogicViewctrlFireEventNode().executeNode(logicNode, actionContext);
                    break;
                // 调试逻辑参数
                case 'DEBUGPARAM':
                    result = await new UILogicDebugParamNode().executeNode(logicNode, actionContext);
                    break;
                // 消息弹窗
                case 'MSGBOX':
                    result = await new UILogicMsgboxNode().executeNode(logicNode, actionContext);
                    break;
                // 前端代码
                case 'RAWJSCODE':
                    result = await new UILogicRawCodeNode().executeNode(logicNode, actionContext);
                    break;
                // 异常处理
                case 'THROWEXCEPTION':
                    result = await new UILogicThrowExceptionNode().executeNode(logicNode, actionContext);
                    break;
                // 结束
                case 'END':
                    result = await new UILogicEndNode().executeNode(logicNode, actionContext);
                    break;
                default:
                    console.log(`${logicNode.logicNodeType}暂未支持`);
            }
            // 有后续节点时继续递归，反之返回,抛异常无返回值
            if (result && result.nextNodes && result.nextNodes.length > 0) {
                await this.executeNextNodes(result.nextNodes, actionContext);
            }
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }

    /**
     * 执行后续节点集合
     *
     * @param {any[]} nextNodes
     * @param {UIActionContext} actionContext
     * @memberof OpenYuQueUILogicBase
     */
    public async executeNextNodes(nextNodes: any[], actionContext: UIActionContext) {
        if (nextNodes && (nextNodes.length > 0)) {
            for (let nextNode of nextNodes) {
                await this.executeNode(nextNode, actionContext);
            }
        }
    }


}