import { MyContext } from "../../types/myContext";
import { Conversation } from "@grammyjs/conversations";
import { defaultMessages } from "@hereconnect/constants";
import { InlineKeyboardMarkup } from "@grammyjs/types";

// Тип разговора
type MyConversation = Conversation<MyContext>;
export async function selectPredefinedMessages(
  conversation: MyConversation,
  ctx: MyContext,
  placement: keyof typeof defaultMessages,
): Promise<string[]> {
  const messages: string[] = [...defaultMessages[placement]];
  let mode: "default" | "edit" | "sort" = "default";
  let selectedIndex: number | null = null;
  let sortOrder: number[] = [];

  const updateKeyboard = (): InlineKeyboardMarkup => ({
    inline_keyboard: messages
      .map((message, index) => {
        const prefix =
          mode === "edit" && selectedIndex === index
            ? "📝 "
            : mode === "sort" && sortOrder.includes(index)
              ? `${sortOrder.indexOf(index) + 1}. `
              : "";
        return [
          {
            text: `${prefix}${message}`,
            callback_data: `select:${index}`,
          },
        ];
      })
      .concat(
        mode === "sort"
          ? [
              [{ text: "✅ Завершить сортировку", callback_data: "done_sort" }],
              [
                {
                  text: "❌ Отменить сортировку",
                  callback_data: "cancel_sort",
                },
              ],
            ]
          : mode === "edit" && selectedIndex !== null
            ? [
                [
                  {
                    text: `❌ Удалить «${messages[selectedIndex]}»`,
                    callback_data: `delete:${selectedIndex}`,
                  },
                ],
                [
                  {
                    text: "❌ Отменить редактирование",
                    callback_data: "cancel_edit",
                  },
                ],
              ]
            : messages.length > 0
              ? [
                  [{ text: "🔀 Поменять порядок", callback_data: "sort" }],
                  [{ text: "✅ Готово", callback_data: "done" }],
                ]
              : [[{ text: "✅ Готово", callback_data: "done" }]],
      ),
  });

  // Функция для отправки или редактирования сообщения
  const sendOrEditMessage = async (
    text: string,
    options: {
      reply_markup: InlineKeyboardMarkup;
      parse_mode?: "Markdown" | "MarkdownV2" | "HTML";
    },
    forceNew = false,
  ) => {
    try {
      if (forceNew && ctx.session.messageId) {
        try {
          await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId);
          ctx.session.messageId = undefined;
          console.log("deleteMessage", ctx.session.messageId);
        } catch (deleteErr) {
          console.warn(
            "Ошибка удаления старого сообщения:",
            ctx.session.messageId,
            deleteErr,
          );
          ctx.session.messageId = undefined;
        }
      }
      if (ctx.session.messageId) {
        await ctx.api.editMessageText(
          ctx.chat!.id,
          ctx.session.messageId,
          text,
          options,
        );
      } else {
        const replyMessage = await ctx.reply(text, options);
        console.log("replyMessage.message_id", replyMessage.message_id);
        ctx.session.messageId = replyMessage.message_id;
      }
    } catch (err) {
      console.error(
        "Ошибка обновления сообщения, создаем новое:",
        ctx.session.messageId,
        err,
      );
      if (ctx.session.messageId) {
        try {
          await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId);
          console.log("deleteMessage", ctx.session.messageId);
        } catch (deleteErr) {
          console.warn(
            "Ошибка удаления старого сообщения:",
            ctx.session.messageId,
            deleteErr,
          );
        }
      }
      const newMessage = await ctx.reply(text, options);
      console.log("newMessage.message_id", newMessage.message_id);
      ctx.session.messageId = newMessage.message_id;
    }
  };

  // Начальное сообщение
  await sendOrEditMessage(
    `**Настройка предустановленных сообщений**
Эти сообщения будут предлагаться пользователю при сканировании QR‑кода. Он сможет выбрать одно из них или написать своё.

Напишите сообщение для добавления, нажмите на сообщение для редактирования или выберите "🔀 Поменять порядок" для сортировки.`,
    { parse_mode: "Markdown", reply_markup: updateKeyboard() },
  );

  while (true) {
    const actionChoice = await conversation.waitFor([
      "callback_query:data",
      "message:text",
    ]);
    const choice = actionChoice.update.callback_query?.data;

    if (!choice && !actionChoice.message) {
      if (choice) {
        // await actionChoice.answerCallbackQuery({
        //   text: "Произошла ошибка. Попробуйте снова.",
        // });
        continue;
      }
      ctx.session.messageId = undefined;
      break;
    }

    const messageText = actionChoice.message?.text.trim();

    if (!choice) {
      if (messageText) {
        if (mode === "edit" && selectedIndex !== null) {
          messages[selectedIndex] = messageText;
          mode = "default";
          selectedIndex = null;
          // await ctx.reply(`Сообщение обновлено: ${messageText}`);
          await sendOrEditMessage(
            "Сообщение обновлено.",
            {
              parse_mode: "Markdown",
              reply_markup: updateKeyboard(),
            },
            true,
          );
        } else {
          messages.push(messageText);
          // await ctx.reply(`Сообщение добавлено: ${messageText}`);
          await sendOrEditMessage(
            "Сообщение добавлено.",
            {
              parse_mode: "Markdown",
              reply_markup: updateKeyboard(),
            },
            true,
          );
        }
      } else {
        await ctx.reply(`Введите текст сообщения.`);
      }

      continue;
    }

    if (choice === "done") {
      // await actionChoice.answerCallbackQuery({ text: "Настройка завершена!" });
      await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId!);
      ctx.session.messageId = undefined;
      break;
    }

    if (choice === "sort") {
      mode = "sort";
      sortOrder.length = 0;
      // await actionChoice.answerCallbackQuery({ text: "Режим сортировки." });
      await sendOrEditMessage("Нажмите на сообщения по порядку.", {
        parse_mode: "Markdown",
        reply_markup: updateKeyboard(),
      });
      continue;
    }

    if (mode === "sort" && choice.startsWith("select:")) {
      const index = parseInt(choice.replace("select:", ""), 10);

      if (sortOrder.includes(index)) {
        sortOrder.splice(sortOrder.indexOf(index), 1);
      } else {
        sortOrder.push(index);
      }

      const sortedMessages: string[] = [];
      sortOrder.forEach((sortIndex, messagesIndex) => {
        sortedMessages[messagesIndex] = messages[sortIndex];
      });
      messages.forEach((message, index) => {
        if (!sortOrder.includes(index)) {
          sortedMessages.push(message);
        }
      });

      // Обновляем порядок сообщений
      for (let i = 0; i < sortedMessages.length; i++) {
        messages[i] = sortedMessages[i];
      }
      for (let i = 0; i < sortOrder.length; i++) {
        sortOrder[i] = i;
      }

      // await actionChoice.answerCallbackQuery({ text: "Сообщение перемещено." });
      await sendOrEditMessage(
        "Нажмите на сообщения по порядку, начиная с первого.",
        { parse_mode: "Markdown", reply_markup: updateKeyboard() },
      );
      continue;
    }

    if (choice === "cancel_sort") {
      mode = "default";
      sortOrder.length = 0;
      // await actionChoice.answerCallbackQuery({ text: "Сортировка отменена." });
      await sendOrEditMessage(
        "Сортировка отменена. Возврат к стандартному режиму.",
        { parse_mode: "Markdown", reply_markup: updateKeyboard() },
      );
      continue;
    }

    if (choice === "done_sort") {
      mode = "default";
      sortOrder.length = 0;
      // await actionChoice.answerCallbackQuery({ text: "Сортировка завершена." });
      await sendOrEditMessage("Сортировка завершена.", {
        parse_mode: "Markdown",
        reply_markup: updateKeyboard(),
      });
      continue;
    }

    if (choice.startsWith("select:")) {
      const index = parseInt(choice.replace("select:", ""), 10);

      if (selectedIndex === index) {
        // await actionChoice.answerCallbackQuery({
        //   text: "Редактирование отменено.",
        // });
        mode = "default";
        selectedIndex = null;
        await sendOrEditMessage("Редактирование отменено.", {
          parse_mode: "Markdown",
          reply_markup: updateKeyboard(),
        });
        continue;
      }

      mode = "edit";
      selectedIndex = index;

      // await actionChoice.answerCallbackQuery({
      //   text: `Редактирование сообщения: "${messages[index]}"`,
      // });
      await sendOrEditMessage(
        `Редактирование сообщения: "${messages[index]}"`,
        { parse_mode: "Markdown", reply_markup: updateKeyboard() },
      );
      continue;
    }

    if (choice === "cancel_edit") {
      mode = "default";
      selectedIndex = null;
      // await actionChoice.answerCallbackQuery({
      //   text: "Редактирование отменено.",
      // });
      await sendOrEditMessage("Редактирование отменено.", {
        parse_mode: "Markdown",
        reply_markup: updateKeyboard(),
      });
      continue;
    }

    if (choice.startsWith("delete:")) {
      const index = parseInt(choice.replace("delete:", ""), 10);
      const deletedMessage = messages.splice(index, 1)[0];
      mode = "default";
      selectedIndex = null;
      // await actionChoice.answerCallbackQuery({
      //   text: `Сообщение "${deletedMessage}" удалено.`,
      // });
      await sendOrEditMessage(`Сообщение "${deletedMessage}" удалено.`, {
        parse_mode: "Markdown",
        reply_markup: updateKeyboard(),
      });
    }
  }

  return messages;
}
