class StateLogic {
  constructor() {}

  async getBotState(pretreatment) {
    let bot = await this.botStateLogic(pretreatment);
    //解析成聚合数据
    let reloA = {
      bot: {
        state: "OPEN",
        id: "",
        disturb: bot.disturb,
        action: {
          doing: [],
          todo: bot.actions,
        },
      },
      SYS_VARS: pretreatment.summary.SYS_VARS,
      taskflow: {
        state: bot.state,
        node: bot.node,
      },
    };
    return reloA;
  }

  async botStateLogic(pretreatment) {
    let bot = {
      state: "listen",
      actions: [],
    };
    let node = this.getCurrentNode(pretreatment);
    bot.node = node;
    //更新disturb
    if (
      pretreatment.taskflows?.length > 0 &&
      pretreatment.exeption?.failure?.action_id == "fail_action"
    ) {
      bot.disturb = {};
    }

    //timeout
    if (pretreatment.kw.bot_timeout?.actions) {
      bot = this.get_timeout_bot_state(pretreatment, bot);
      //fail
      if (pretreatment.exeption?.fail) {
        bot = this.get_fail_bot_state(pretreatment, bot);
        bot.state = "fail";
        return bot;
      }
      //final
      if (pretreatment.kw.bot_final?.actions) {
        bot = this.get_fail_bot_state(pretreatment, bot);
        bot.state = "final";
        return bot;
      }
      //terminate
      if (pretreatment.kw.bot_terminate?.actions) {
        bot = this.get_fail_bot_state(pretreatment, bot);
        bot.state = "terminate";
        return bot;
      }
      return bot;
    }
    //fail
    if (pretreatment.exeption?.fail) {
      bot = this.get_fail_bot_state(pretreatment, bot);
      bot.state = "fail";
      return bot;
    }
    //final
    if (pretreatment.kw.bot_final?.actions) {
      bot = this.get_fail_bot_state(pretreatment, bot);
      bot.state = "final";
      return bot;
    }
    //terminate
    if (pretreatment.kw.bot_terminate?.actions) {
      bot = this.get_fail_bot_state(pretreatment, bot);
      bot.state = "terminate";
      return bot;
    }
    //idle
    if (pretreatment.kw?.faq?.length > 0 || pretreatment.kw?.kbqa?.length > 0) {
      if (pretreatment.taskflows.length <= 0) {
        bot.state = "idle";
        if (pretreatment.kw.faq) {
          this.pushToActions(bot.actions, pretreatment.kw.faq);
        }
        if (pretreatment.kw.kbqa) {
          this.pushToActions(bot.actions, pretreatment.kw.kbqa);
        }
        return bot;
      }
    }
    //say
    bot.state = "listen";
    if (pretreatment.kw?.faq) {
      this.pushToActions(bot.actions, pretreatment.kw.faq);
    }
    if (pretreatment.kw.kbqa) {
      this.pushToActions(bot.actions, pretreatment.kw.kbqa);
    }
    for (var taskflow of pretreatment.taskflows) {
      this.pushToActions(bot.actions, taskflow);
    }

    return bot;
  }

  get_fail_bot_state(pretreatment, bot) {
    //i
    if (pretreatment.kw.faq) {
      this.pushToActions(bot.actions, pretreatment.kw.faq);
    }
    if (pretreatment.kw.kbqa) {
      this.pushToActions(bot.actions, pretreatment.kw.kbqa);
    }
    //ii
    if (pretreatment.taskflows?.length > 0) {
      for (var taskflow of pretreatment.taskflows) {
        this.pushToActions(bot.actions, taskflow);
      }
    }
    //iv
    if (pretreatment.kw.bot_terminate?.actions) {
      this.pushToActions(bot.actions, pretreatment.kw.bot_terminate);
    }
    if (pretreatment.kw.bot_final?.actions) {
      this.pushToActions(bot.actions, pretreatment.kw.bot_final);
    }
    if (pretreatment.exeption?.fail) {
      bot.actions.push(...pretreatment.exeption?.fail);
    }
    return bot;
  }

  get_timeout_bot_state(pretreatment, bot) {
    bot.state = "timeout";
    //ii
    if (pretreatment.kw.bot_timeout.actions) {
      this.pushToActions(bot.actions, pretreatment.kw.bot_timeout);
    }
    return bot;
  }
  getCurrentNode(pretreatment) {
    let node = {};
    if (pretreatment.taskflows.length > 0) {
      if (
        pretreatment.kw?.faq?.length > 0 ||
        pretreatment.kw?.kbqa?.length > 0
      ) {
        pretreatment.taskflows[pretreatment.taskflows.length - 1].state =
          "interrupted";
      }
      node = Object.assign(
        node,
        pretreatment.taskflows[pretreatment.taskflows.length - 1]
      );
    } else {
      if (pretreatment.kw) {
        for (var key in pretreatment.kw) {
          node = Object.assign(node, pretreatment.kw[key]);
        }
      }
    }
    //yes_no_isolate 特殊处理
    if (node.name === "yes_no_isolate") {
      node.type = "yes_no";
    }
    delete node.actions;
    return node;
  }

  pushToActions(actions, node) {
    //yes_no_isolate 特殊处理
    if (node.name === "yes_no_isolate") {
      node.type = "yes_no";
    }
    for (var action of node.actions) {
      action.node = {
        id: node.id,
        name: node.name,
        type: node.type,
        botId: node.botId,
      };

      actions.push(action);
    }
  }
}

//判断是否在数组中
function isIn(list, target) {
  for (var item of list) {
    if (item == target) {
      return true;
    }
  }
  return false;
}

function is_empty(obj) {
  if (obj == null) {
    return true;
  }
  var arr = Object.keys(obj);
  return arr.length == 0;
}

exports.StateLogic = StateLogic;
