"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var chat_exports = {};
__export(chat_exports, {
  Chat: () => Chat
});
module.exports = __toCommonJS(chat_exports);
var import_chalk = __toESM(require("chalk"));
var readline = __toESM(require("readline"));
var uuid = __toESM(require("uuid"));
var utils = __toESM(require("../utils"));
const USER_ICONS = {
  myself: "\u{1F464}",
  bot: "\u{1F916}",
  other: "\u{1F465}"
};
const MESSAGE_ICONS = {
  audio: "\u{1F3B5}",
  card: "\u{1F0CF}",
  carousel: "\u{1F3A0}",
  choice: "\u{1F53D}",
  dropdown: "\u{1F53D}",
  file: "\u{1F4C1}",
  image: "\u{1F305}",
  location: "\u{1F4CD}",
  text: "",
  video: "\u{1F3A5}",
  markdown: "",
  bloc: "\u{1F9F1}"
};
const EXIT_KEYWORDS = ["exit", ".exit"];
class Chat {
  constructor(_props) {
    this._props = _props;
  }
  _events = new utils.emitter.EventEmitter();
  _state = { status: "stopped" };
  static launch(props) {
    const instance = new Chat(props);
    void instance._run();
    return instance;
  }
  async _run() {
    this._switchAlternateScreenBuffer();
    this._events.on("state", this._renderMessages);
    const connection = await this._props.client.listenConversation({ id: this._props.conversationId });
    const keyboard = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    connection.on("message_created", (m) => void this._onMessageReceived(m));
    keyboard.on("line", (l) => void this._onKeyboardInput(l));
    process.stdin.on("keypress", (_, key) => {
      if (key.name === "escape") {
        void this._onExit();
      }
    });
    this._setState({ status: "running", messages: [], connection, keyboard });
  }
  _setState = (newState) => {
    this._state = newState;
    this._events.emit("state", this._state);
  };
  _onMessageReceived = async (message) => {
    if (this._state.status === "stopped") {
      return;
    }
    if (message.userId === this._props.client.user.id) {
      return;
    }
    const source = message.isBot ? "bot" : "other";
    this._setState({ ...this._state, messages: [...this._state.messages, { ...message, source }] });
  };
  _onKeyboardInput = async (line) => {
    if (this._state.status === "stopped") {
      return;
    }
    if (EXIT_KEYWORDS.includes(line)) {
      await this._onExit();
      return;
    }
    if (!line) {
      this._setState({ ...this._state });
      return;
    }
    const message = this._textToMessage(line);
    this._setState({ ...this._state, messages: [...this._state.messages, message] });
    await this._props.client.createMessage(message);
  };
  _onExit = async () => {
    if (this._state.status === "stopped") {
      return;
    }
    const { connection, keyboard } = this._state;
    await connection.disconnect();
    connection.cleanup();
    keyboard.close();
    this._setState({ status: "stopped" });
    this._clearStdOut();
    this._restoreOriginalScreenBuffer();
  };
  wait() {
    return new Promise((resolve) => {
      const cb = (state) => {
        if (state.status === "stopped") {
          this._events.off("state", cb);
          resolve();
        }
      };
      this._events.on("state", cb);
    });
  }
  _renderMessages = () => {
    if (this._state.status === "stopped") {
      return;
    }
    this._clearStdOut();
    this._printHeader();
    for (const message of this._state.messages) {
      const prefix = USER_ICONS[message.source];
      const text = this._messageToText(message);
      const coloredText = message.source === "bot" ? text : import_chalk.default.gray(text);
      process.stdout.write(`${prefix} ${coloredText}
`);
    }
    this._state.keyboard.setPrompt(">> ");
    this._state.keyboard.prompt(true);
  };
  _printHeader = () => {
    process.stdout.write(import_chalk.default.bold("Botpress Chat\n"));
    process.stdout.write(import_chalk.default.gray('Type "exit" or press ESC key to quit\n'));
  };
  _switchAlternateScreenBuffer = () => {
    process.stdout.write("\x1B[?1049h");
  };
  _restoreOriginalScreenBuffer = () => {
    process.stdout.write("\x1B[?1049l");
  };
  _clearStdOut = () => {
    process.stdout.write("\x1B[2J\x1B[0;0H");
  };
  _messageToText = (message) => {
    const prefix = MESSAGE_ICONS[message.payload.type];
    switch (message.payload.type) {
      case "audio":
        return prefix + message.payload.audioUrl;
      case "card":
        return prefix + JSON.stringify(message.payload);
      case "carousel":
        return prefix + JSON.stringify(message.payload);
      case "choice":
        return prefix + [message.payload.text, ...message.payload.options.map((o) => `  - ${o.label} (${o.value})`)].join("\n");
      case "dropdown":
        return prefix + [message.payload.text, ...message.payload.options.map((o) => `  - ${o.label} (${o.value})`)].join("\n");
      case "file":
        return prefix + message.payload.fileUrl;
      case "image":
        return prefix + message.payload.imageUrl;
      case "location":
        return prefix + `${message.payload.latitude},${message.payload.longitude} (${message.payload.address})`;
      case "text":
        return prefix + message.payload.text;
      case "video":
        return prefix + message.payload.videoUrl;
      case "markdown":
        return prefix + message.payload.markdown;
      case "bloc":
        return [
          prefix,
          ...message.payload.items.map((item) => this._messageToText({ payload: item })).map((l) => `	${l}`)
        ].join("\n");
      default:
        return "<unknown>";
    }
  };
  _textToMessage = (text) => {
    return {
      id: uuid.v4(),
      userId: this._props.client.user.id,
      source: "myself",
      conversationId: this._props.conversationId,
      createdAt: (/* @__PURE__ */ new Date()).toISOString(),
      payload: { type: "text", text }
    };
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Chat
});
//# sourceMappingURL=index.js.map
