import { UIActionContext } from "@/logic/ui-logic";
import { LogicReturnType } from "@/logic/const/logic-return-type";
import { UILogicParamType } from "@/logic/const/ui-logic-param-type";
import { Util, Verify } from "@/utils";
import { AppMessageBox } from "@/utils/app-message-box/app-message-box";
import { Subject } from "rxjs";
import { Environment } from "@/environments/environment";
/**
 * 准备参数
 * 基于 APP/src/uiservice/%DE_PKGPATH%/%APP_DEUILOGIC%-ui-logic-base.ts.ftl 生成
 * @export
 * @class ParamsUILogicBase
 */
export default class ParamsUILogicBase {

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

    /**
     * 逻辑参数
     *
     * @protected
     * @type {any[]}
     * @memberof ParamsUILogicBase
     */
    protected logicParams: any[] = [
        {
            name: '测试数组',
            codeName: 'tempArrData',
            entityListParam: true,
        },
        {
            name: '操作参数',
            codeName: 'params',
            entityParam: true,
        },
        {
            name: '过滤参数',
            codeName: 'filter',
            filterParam: true,
        },
        {
            name: '绑定参数',
            codeName: 'bangParam',
            entityParam: true,
        },
        {
            name: '数据集数据',
            codeName: 'arrData',
            entityListParam: true,
        },
        {
            name: '消息弹窗返回值',
            codeName: 'msgTest',
            simpleParam: true,
        },
        {
            name: '传入变量',
            codeName: 'Default',
            default: true,
            entityParam: true,
        },
    ];

    /**
     * 执行前
     *
     * @param {*} args
     * @param {*} [context={}]
     * @param {*} [params={}]
     * @param {*} [$event]
     * @param {*} [xData]
     * @param {*} [actioncontext]
     * @param {string} [srfParentDeName]
     * @return {*} 
     * @memberof ParamsUILogicBase
     */
    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 ParamsUILogicBase
     */
    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);
            await this.execute_begin_node(actionContext);
            return actionContext.getResult();
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }

    /**
     * 获取条件参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @param {string} param 节点参数
     * @param {string} property 参数属性
     * @return {*} 
     * @memberof ParamsUILogicBase
     */
    public getCondParam(actionContext: UIActionContext, param: string, property: string) {
        const resultParam = actionContext.getParam(param).getReal();
        //  当不存在参数属性时，返回直接值
        if (property === '') {
            return resultParam;
        }
        if (resultParam && resultParam.hasOwnProperty(property)) {
            return resultParam[property];
        }
        return null;
    }

    /**
     * 开始
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_begin_node(actionContext: UIActionContext) {
        actionContext.setResult(actionContext.defaultParam.getReal());
    console.log(`已完成执行开始节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行准备参数节点`);
        await this.execute_preparejsparam1_node(actionContext);
    }
    
    /**
     * 重置参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_resetparam1_node(actionContext: UIActionContext) {
        const dstParam: any = actionContext.getParam('params');
        dstParam.resetAll();
        actionContext.bindLastReturnParam(null);
    console.log(`已完成执行重置参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行调试逻辑参数节点`);
        await this.execute_debugparam2_node(actionContext);
    }
    
    /**
     * 调试逻辑参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_debugparam2_node(actionContext: UIActionContext) {
    console.log(`已完成执行调试逻辑参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行消息弹窗节点`);
        await this.execute_msgbox1_node(actionContext);
    }
    
    /**
     * 消息弹窗
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_msgbox1_node(actionContext: UIActionContext) {
        return new Promise<void>((resolve: any) => {
            const msgBoxParam: any = actionContext.getParam('msgTest');
            const data = msgBoxParam ? msgBoxParam.getReal() : {};
            const options = {
                type: 'QUESTION',
                title: data && data.title ? data.title : '是否查询数据集',
                content: data && data.message ? data.message : ``,
                buttonType: 'yesno',
                showMode: '',
                showClose: false,
                mask: true,
                maskClosable: true
            };
            const subject: Subject<any> | null =  AppMessageBox.getInstance().open(options);
            if (subject) {
                const handleResponse = (result: any) => {
                    if (msgBoxParam) {
                        msgBoxParam.bind(result);
                    }
                    actionContext.bindLastReturnParam(result);
                    if(Verify.testCond(this.getCondParam(actionContext, 'msgTest', ''), 'EQ', 'true')) {
                        resolve(this.execute_dedataset1_node(actionContext));
                    }
                    if(Verify.testCond(this.getCondParam(actionContext, 'msgTest', ''), 'EQ', 'false')) {
                        resolve(this.execute_end1_node(actionContext));
                    }
                }
                const subscription = subject.subscribe((result: any) => {
                    resolve(handleResponse(result));
                    subscription!.unsubscribe();
                    subject.complete();
                });
            } else {
                resolve(true);
            }
        });
    }
    
    /**
     * 调试逻辑参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_debugparam1_node(actionContext: UIActionContext) {
        const dstParamValue = actionContext.getParam('Default').getReal();
        console.log(`逻辑节点调试逻辑参数操作参数值:`,  Util.deepCopy(dstParamValue));
    console.log(`已完成执行调试逻辑参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行绑定参数节点`);
        await this.execute_bindparam1_node(actionContext);
    }
    
    /**
     * 准备参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_preparejsparam1_node(actionContext: UIActionContext) {
        try {
            //  目标数据
            const dstParam_1: any = actionContext.getParam('params');
            //  无值类型
            //  直接值
            const result_1 = '2131414';
            dstParam_1.set('test', result_1);
        } catch (error: any) {
            throw new Error(`逻辑节点 准备参数 ${error && error.message ? error.message : '发生未知错误！'}`);
        }
    console.log(`已完成执行准备参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行调试逻辑参数节点`);
        await this.execute_debugparam1_node(actionContext);
    }
    
    /**
     * 排序数组参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_sortparam1_node(actionContext: UIActionContext) {
        // 目标数据
        const dstParam: any = actionContext.getParam('tempArrData');
        // 目标属性
        const dstFieldName: string = 'price';
        if (!dstFieldName) {
            throw new Error(`逻辑参数排序数组参数未指定设置排序属性`);
        }
        dstParam.sort(dstFieldName, 'DESC');
        actionContext.bindLastReturnParam(null);
    console.log(`已完成执行排序数组参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行调试逻辑参数节点`);
        await this.execute_debugparam5_node(actionContext);
    }
    
    /**
     * 结束
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_end1_node(actionContext: UIActionContext) {
        const strReturnType: string = '';
        if (Object.is(strReturnType, LogicReturnType.NONEVALUE) || Object.is(strReturnType, LogicReturnType.NULLVALUE)) {
            actionContext.setResult(null);
        } else if (Object.is(strReturnType, LogicReturnType.SRCVALUE)) {
            actionContext.setResult('');
        } else if (Object.is(strReturnType, LogicReturnType.BREAK)) {
            actionContext.setResult(LogicReturnType.BREAK);
        } else if (Object.is(strReturnType, LogicReturnType.LOGICPARAM) || Object.is(strReturnType, LogicReturnType.LOGICPARAMFIELD)) {
            const returnParam = actionContext.getParam('');
            if (Object.is(strReturnType, LogicReturnType.LOGICPARAM)) {
                actionContext.setResult(returnParam.getReal());
            } else {
                actionContext.setResult(returnParam.get(''));
            }
        } else {
            throw new Error(`无法识别的返回值类型${strReturnType}`);
        }
    console.log(`已完成执行结束节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
    }
    
    /**
     * 调试逻辑参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_debugparam4_node(actionContext: UIActionContext) {
        const dstParamValue = actionContext.getParam('tempArrData').getReal();
        console.log(`逻辑节点调试逻辑参数操作参数值:`,  Util.deepCopy(dstParamValue));
    console.log(`已完成执行调试逻辑参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行排序数组参数节点`);
        await this.execute_sortparam1_node(actionContext);
    }
    
    /**
     * 调试逻辑参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_debugparam3_node(actionContext: UIActionContext) {
        const dstParamValue = actionContext.getParam('bangParam').getReal();
        console.log(`逻辑节点调试逻辑参数操作参数值:`,  Util.deepCopy(dstParamValue));
    console.log(`已完成执行调试逻辑参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行重置参数节点`);
        await this.execute_resetparam1_node(actionContext);
    }
    
    /**
     * 实体数据集
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_dedataset1_node(actionContext: UIActionContext) {
        const dstParam = actionContext.getParam('filter');
        if (!Object.is(dstParam.logicParamType, UILogicParamType.filterParam)) {
            throw new Error(`传入参数 filter 类型不正确，必须为过滤器对象`);
        }
        try {
            const service: any = await window.entityServiceRegister.getService('ibizbook');
            const res = await service['FetchDefault'](actionContext.context, dstParam.getReal() ? dstParam.getReal() : {});
            if (res && res.status === 200 && res.data) {
                // 返回值绑定逻辑参数对象
                const retParam = actionContext.getParam('arrData');
                retParam.bind(res.data);
                actionContext.bindLastReturnParam(res.data);
            }
        } catch (error: any) {
            throw new Error(`${error.message ? error.message : error.data && error.data.message ? error.data.message : '查询实体数据集失败'}`);
        }
    console.log(`已完成执行实体数据集节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行附加到数组参数节点`);
        await this.execute_appendparam1_node(actionContext);
    }
    
    /**
     * 绑定参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_bindparam1_node(actionContext: UIActionContext) {
        try {
            //  源数据
            const srcParam = actionContext.getParam('params');
            //  目标数据
            const dstParam = actionContext.getParam('bangParam');
            //  源属性
            const srcFieldName: string = 'test';
            if (srcFieldName) {
                dstParam.bind(srcParam.get(srcFieldName));
            } else {
                dstParam.bind(srcParam.getReal());
            }
            actionContext.bindLastReturnParam(null);
        } catch (error: any) {
            throw new Error(`逻辑参数绑定参数 ${error && error.message ? error.message : '发生未知错误!'}`);
        }
    console.log(`已完成执行绑定参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行调试逻辑参数节点`);
        await this.execute_debugparam3_node(actionContext);
    }
    
    /**
     * 调试逻辑参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_debugparam5_node(actionContext: UIActionContext) {
        const dstParamValue = actionContext.getParam('tempArrData').getReal();
        console.log(`逻辑节点调试逻辑参数操作参数值:`,  Util.deepCopy(dstParamValue));
    console.log(`已完成执行调试逻辑参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行结束节点`);
        await this.execute_end1_node(actionContext);
    }
    
    /**
     * 附加到数组参数
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ParamsUILogicBase
     */
    protected async execute_appendparam1_node(actionContext: UIActionContext) {
        // 源数据
        const srcParam: any = actionContext.getParam('arrData');
        // 目标数据
        const dstParam: any = actionContext.getParam('tempArrData');
        // 源属性
        const srcFieldName: string = '';
        let objParam: any;
        if (srcFieldName) {
            objParam = srcParam.get(srcFieldName);
        } else {
            objParam = srcParam.getReal();
        }
        dstParam.append(0, objParam, 2, 7);
        actionContext.bindLastReturnParam(null);
    console.log(`已完成执行附加到数组参数节点，操作参数数据如下:`);
    if (actionContext.paramsMap && (actionContext.paramsMap.size > 0)) {
        for (let [key, value] of actionContext.paramsMap) {
            console.log(key, Util.deepCopy(value.getReal()));
        }
    }
        console.log(`即将执行调试逻辑参数节点`);
        await this.execute_debugparam4_node(actionContext);
    }
    

}