class EventLogic {
    constructor() { }

    eventOutputLogic(botState) {
        var action = {};
        if (botState.taskflow.state == "final") {
            action = { eventKey: "BOT_FINAL" };
        } else if (botState.taskflow.state == "terminate") {
            action = { eventKey: "BOT_TERMINATE" };
        } else if (botState.taskflow.state == "fail") {
            action = { eventKey: "BOT_FAIL" };
        } else {
            action = { eventKey: "BOT_REPLY" };
        }
        return action;
    }

    eventInputLogic(ctx, param) {
        let keys = ['openLogic', 'stopLogic', 'nextLogic', 'timeoutLogic', 'utteranceLogic'];
        let obj = {
            actions: {},
            event: param,
            ctx: ctx,
        }
        let items = {};
        let logs = {};
        keys.forEach((item) => {
            let itemRet = this[item](ctx, param);
            if (itemRet) {
                if (Object.keys(itemRet) == 'log') {
                    itemRet.log = Object.assign(logs, { ...itemRet.log })
                }
                obj.actions = Object.assign(items, { ...itemRet })
            }
        })

        return obj;
    }

    openLogic(ctx, event) {
        if (['DIALOG_OPEN'].includes(event.key)) {
            return {
                lifecycle: {
                    open: {}
                }
            }
        }
    }

    startLogic(ctx, event) {
        if (['DIALOG_OPEN'].includes(event.key)) {
            return {
                ctrl: {
                    start: {}
                }
            }
        }
    }

    stopLogic(ctx, event) {
        if (['DIALOG_CLOSE'].includes(event.key)) {
            return {
                lifecycle: {
                    close: {}
                }
            }
        }
    }

    nextLogic(ctx, event) {
        let _ctx = { ...ctx };
        if (['SPEAK_END', 'END_SPEAK'].includes(event.key) && ctx?.bot?.action?.todo?.length > 0) {
            return {
                log: {
                    next: '还有话要说，不做next'
                }
            }
        }
        if (['SPEAK_END', 'END_SPEAK'].includes(event.key) &&
            (['final', 'fail', 'terminate', 'FINAL', 'FAIL', 'TERMINATE'].includes(ctx?.taskflow?.state) ||
                ['yes_no', 'slot_filling', 'select'].includes(_ctx?.taskflow?.node.type) ||
                (['reply'].includes(_ctx?.taskflow?.node.type) && (['faq', 'kbqa','yes_no_isolate'].includes(_ctx?.taskflow?.node.name) || _ctx?.taskflow?.node.name.startsWith("wait_of_")))
            )) {
            return {
                log: {
                    next: 'SPEAK_END后，等用户动作，不做next'
                }
            }
        }
        if ((['SPEAK_END', 'END_SPEAK'].includes(event.key) && ctx?.bot?.action?.todo.length == 0) ||
            ((event.key.endsWith('OPEN') || event.key.endsWith('INPUT') || event.key.endsWith('SUBMIT'))
                && (['reply'].includes(ctx?.taskflow?.node.type) && ctx?.taskflow?.node.name.startsWith('wait_of_')))
        ) {
            return {
                ctrl: {
                    next: {}
                }
            }
        }
    }

    timeoutLogic(ctx, event) {
        if (['FORM_TIMEOUT',"TIMEOUT"].includes(event.key) && ['final', 'fail', 'terminate', 'FINAL', 'FAIL', 'TERMINATE'].includes(ctx?.taskflow?.state)) {
            return {
                'log': {
                    'timeout': 'BOT.state' + ctx?.taskflow?.state + '无效TIMEOUT事件'
                }
            }
        }
        if (['FORM_TIMEOUT',"TIMEOUT"].includes(event.key)) {
            return {
                ctrl: {
                    timeout: {}
                }
            }
        }
    }

    utteranceLogic(ctx, event) {
        if (['utterance'].includes(event.key) && ['final', 'fail', 'terminate', 'FINAL', 'FAIL', 'TERMINATE'].includes(ctx?.taskflow?.state)) {
            return {
                'log': {
                    'utterance': 'BOT.state' + ctx?.taskflow?.state + '无法响应utterance'
                }
            };
        }

        if (['utterance'].includes(event.key)) {
            return {
                ctrl: {
                    utterance: {}
                }
            }
        }
    }

}

exports.EventLogic = EventLogic;
