
import { actionAddins } from ".";
import { IAction, IActionProperty, IActionNode, IContext, IActionResult } from "../types/ActionTypes";
import { ConditionTree } from '../types/Conditions';
/**
 * アクションの属性定義
 */
interface IErrorShowProps {
    message: string;
    condition: string;
}   

export class ErrorShowAction implements IAction {
    name: string; 
    actionProps: IActionProperty[]; //调用从import导入关于显示类的定义
    props: IErrorShowProps;//从上方的interface 定义这个props所需要接受的属性
    constructor() { //解构函数定义需要的类名
        this.name = "エラー表示";
        this.actionProps = [];
        this.props = {
            message: '',
            condition: ''
        }
        this.register(); //重置以上注册表
    }

    /**
     * アクションの実行を呼び出す
     * @param actionNode 
     * @param event 
     * @returns 
     */
    async process(actionNode: IActionNode, event: any, context: IContext): Promise<IActionResult> { 
        let result = { 
            canNext: true,
            result: false
        };
        try { 
            this.actionProps = actionNode.actionProps;
            if (!('message' in actionNode.ActionValue) && !('condition' in actionNode.ActionValue)) { //如果message以及condition两者都不存在的情况下return
                return result
            }
            this.props = actionNode.ActionValue as IErrorShowProps; 
            const conditionResult = this.getConditionResult(context); 
            console.log("条件結果：",conditionResult);
            if (conditionResult) {
                event.error = this.props.message;
                result.canNext=false;
            }
            return result;
        } catch (error) {
            context.errors.handleError(error,actionNode);
            result.canNext = false;
            return result;
        }

    }
    /**
    * 
    * @param context 条件式を実行する
    * @returns 
    */
    getConditionResult(context: any): boolean {
        const tree = this.getCondition(this.props.condition);
        if (!tree) {
            //条件を設定されていません
            return true;
        }
        return tree.evaluate(tree.root, context);
    }

    /**
     * @param condition 条件式ツリーを取得する
     * @returns 
     */
    getCondition(condition: string): ConditionTree | null {
        try {
            const tree = new ConditionTree();
            tree.fromJson(condition);
            if (tree.getConditions(tree.root).length > 0) {
                return tree;
            } else {
                return null;
            }
        } catch (error) {
            return null;
        }
    }

    register(): void {
        actionAddins[this.name] = this;
    }

}
new ErrorShowAction();