import { Bot, session } from "grammy";
import { conversations, createConversation } from "@grammyjs/conversations";
import { MyContext } from "../types/myContext";
import { env } from "../config/env";
import { CouchDBStorageAdapter } from "./storageAdapters/CouchDBStorageAdapter";
import { loadUserMiddleware } from "./middleware/loadUser";
import { forwardQrCodeMessageMiddleware } from "./middleware/forwardQrCodeMessageMiddleware";
import { tgBotSessionsDb } from "../dbs";
import { startCommand } from "./commands/start";
import { helpCommand } from "./commands/help";
import { newCommand } from "./commands/new";
import { manageCommand } from "./commands/manage";
import { callbackQueryHandler } from "./callbackHandlers";
import { newQRCodeConversation } from "./conversations/newQRCodeConversation";
import { hydrateReply } from "@grammyjs/parse-mode";

export { setupCommands } from "./commands/setupCommands";

export const createBot = ({
  abortController,
}: {
  abortController: AbortController;
}) => {
  const storage = new CouchDBStorageAdapter(tgBotSessionsDb, {
    softDelete: true,
    type: "tg_bot_session",
  });

  // Инициализируем бота с нужным типом контекста
  const bot = new Bot<MyContext>(env.BOT_TOKEN, {
    client: {
      baseFetchConfig: {
        signal: abortController.signal,
      },
    },
  });

  bot.use(hydrateReply);

  // Подключаем сессии. По необходимости определите initial state для сессии
  bot.use(session({ storage, initial: () => ({}) }));

  // Middleware для загрузки или создания пользователя
  bot.use(loadUserMiddleware);

  // Подключаем conversations для многошаговых сценариев
  bot.use(conversations());

  // Регистрация команд
  bot.command("start", startCommand);
  bot.command("help", helpCommand);
  bot.command("manage", manageCommand);
  bot.command("cancel", async (ctx) => {
    await ctx.conversation.exit();
    await ctx.reply("Leaving.");
  });

  // Middleware для обработки ответов на сообщения
  bot.use(forwardQrCodeMessageMiddleware);

  // /new
  bot.use(createConversation(newQRCodeConversation));
  bot.command("new", newCommand);

  // Обработка callback_query
  bot.on("callback_query:data", callbackQueryHandler);

  return bot;
};
