import { type QRCodeDocument } from "@hereconnect/types";
import { Conversation } from "@grammyjs/conversations";
import { InputFile } from "grammy";
import type { MyContext } from "../../types/myContext";
import { qrCodePlacements } from "../../types/models";
import {
  buildPlacementKeyboard,
  buildActionsKeyboard,
} from "../utils/keyboards";
import { createQRCode } from "../../api/qrCodes";
import { generateQRCodeImage } from "../../services/qrGenerator";
import { selectMultipleActions } from "./selectMultipleActions";
import { defaultMessages } from "@hereconnect/constants";
import { selectPredefinedMessages } from "./selectPredefinedMessages";

export async function newQRCodeConversation(
  conversation: Conversation<MyContext>,
  ctx: MyContext,
) {
  if (!ctx.userDoc) {
    await ctx.reply(
      "Не удалось определить вашего пользователя. Попробуйте позже.",
    );
    return;
  }

  const userUuid = ctx.userDoc.user_uuid;
  if (!userUuid) {
    await ctx.reply(
      "У вашего профиля отсутствует UUID. Обратитесь в поддержку.",
    );
    return;
  }

  // Выбор типа объекта (placement)
  await ctx.reply("Выберите объект, для которого будет создан QR-код:", {
    reply_markup: {
      inline_keyboard: buildPlacementKeyboard(qrCodePlacements),
    },
  });

  const placementChoice = await conversation.waitFor("callback_query:data");
  const placement = placementChoice.update.callback_query?.data;

  // Проверяем, что выбранное значение входит в допустимые типы
  if (!qrCodePlacements.some((p) => p.type === placement)) {
    await ctx.reply("Неверный выбор. Попробуйте снова /new");
    return;
  }

  // Преобразуем `placement` в строго типизированное значение
  const typedPlacement = placement as QRCodeDocument["placement"];

  // Подтверждаем выбор
  await placementChoice.answerCallbackQuery({ text: "Объект выбран!" });

  // Выбор действий
  const availableActions = [
    { action: "sendMessage", label: "Отправить сообщение" },
    { action: "viewContactInfo", label: "Посмотреть контактные данные" },
  ] as const;

  const chosenActions = await selectMultipleActions(
    conversation,
    ctx,
    availableActions,
  );

  if (chosenActions.length === 0) {
    await ctx.reply("Вы не выбрали ни одного действия. Попробуйте снова /new.");
    return;
  }

  // Ввод названия QR-кода
  let exampleName: string;

  switch (typedPlacement) {
    case "car":
      exampleName = "Моя машина";
      break;
    case "pet":
      exampleName = "Ошейник Барсика";
      break;
    case "door":
      exampleName = "Входная дверь квартиры";
      break;
    case "store":
      exampleName = "Магазин на углу";
      break;
    case "restaurant_table":
      exampleName = "Столик №12";
      break;
    case "other":
      exampleName = "Что-то другое";
      break;
  }

  let predefinedMessages: QRCodeDocument["predefinedMessages"] = undefined;
  if (chosenActions.includes("sendMessage")) {
    predefinedMessages = await selectPredefinedMessages(
      conversation,
      ctx,
      typedPlacement,
    );
  }

  // Отправляем сообщение пользователю с примером
  await ctx.reply(
    `Введите название для вашего QR-кода (например: «${exampleName}»):`,
  );

  const nameMsg = await conversation.waitFor("message:text");
  const name = nameMsg.message.text.trim();

  // Уведомление о создании QR-кода
  await ctx.reply("Создаём QR-код…");

  // Создание документа в БД
  const { url } = await createQRCode({
    userUuid,
    name,
    placement: typedPlacement,
    actions: chosenActions,
    predefinedMessages,
  });

  // Генерация QR-кода
  const pngBuffer = await generateQRCodeImage(url, { format: "png" });

  // Отправляем пользователю QR-код
  await ctx.reply("Ваш QR-код готов! Вот он:");

  await ctx.replyWithPhoto(
    new InputFile(new Uint8Array(pngBuffer.buffer), "qr.png"),
  );

  await ctx.reply(
    `Разместите этот код на вашем объекте. При сканировании по адресу ${url} посетители смогут взаимодействовать с вами.`,
  );

  // Завершаем разговор
}
