import type { MyContext } from "../types/myContext";
import { Bot } from "grammy";
import type { ServiceSeqTracker } from "@hereconnect/lib-service-seq-tracker";
import type { CouchDBChangesStream } from "@hereconnect/couchdb-changes-stream";
import type { MessageDocument, UserDocument } from "@hereconnect/types";
import { qrDb, userChatSettingsDb, usersDb } from "../dbs";
import { env } from "../config/env";
import { escapeHtml } from "../utils/escapeHtml";

async function handleChange(msgDoc: MessageDocument, bot: Bot<MyContext>) {
  const qrDoc = await qrDb.get(`qr_code:${msgDoc.qr_code_uri}`);
  if (qrDoc.messageDeliveryMethod !== "telegram") {
    console.log(`Skip !telegram`);
    return;
  }

  const fields = ["telegram_id"] as const;
  const [{ docs: telegramUsersDocs }, { rows: userChatSettingsRows }] =
    await Promise.all([
      usersDb.find({
        selector: {
          user_uuid: qrDoc.user_uuid,
          telegram_id: {
            $exists: true,
            $ne: null,
          },
        },
        fields: [...fields],
      }) as Promise<{
        docs: Required<Pick<UserDocument, (typeof fields)[number]>>[];
      }>,

      userChatSettingsDb.allDocs({
        startkey: `user_chat_settings:${msgDoc.qr_code_uri}:${msgDoc.chat}:owner:`,
        endkey: `user_chat_settings:${msgDoc.qr_code_uri}:${msgDoc.chat}:owner:\uffff`,
        include_docs: true,
      }),
    ]);

  if (
    userChatSettingsRows.some(
      (row) => row.doc?.is_telegram_messages_enabled === false,
    )
  ) {
    console.log("telegram notifications is disabled");
    return;
  }

  if (telegramUsersDocs.length === 0) {
    console.log("NO TELEGRAM USERS");
  } else {
    console.log(`sending to ${telegramUsersDocs.length} telegram accounts`);
  }

  const hashTag = `#qr${qrDoc.uri}_c${msgDoc.chat}`;
  const manageMessageUrl = `${env.APP_BASE_URL}/manage/qr/${qrDoc.uri}/chat/${msgDoc.chat}#msg-${encodeURIComponent(msgDoc.created_at)}`;
  const text = `${escapeHtml(msgDoc.body.trim())} — <i><a href="${escapeHtml(manageMessageUrl)}">сообщение диалога QR-кода «${escapeHtml(qrDoc.name)}»</a> ${escapeHtml(hashTag)}</i>`;
  for (const telegramUserDoc of telegramUsersDocs) {
    await bot.api.sendMessage(telegramUserDoc.telegram_id, text, {
      parse_mode: "HTML",
      link_preview_options: { is_disabled: true },
      reply_markup: { force_reply: true },
    });
  }
}

export const iterateMessagesChanges = async ({
  changesStream,
  serviceSeqTracker,
  bot,
}: {
  changesStream: CouchDBChangesStream<MessageDocument>;
  serviceSeqTracker: ServiceSeqTracker;
  bot: Bot<MyContext>;
}) => {
  for await (const change of changesStream) {
    const { id, seq, doc: msgDoc, changes } = change;

    console.log("seq", seq);

    try {
      if (!msgDoc) {
        console.error("Change missing document:", change);
        continue;
      }

      serviceSeqTracker.checkNextSeq(seq);

      await handleChange(msgDoc, bot);
    } catch (error) {
      console.error(
        `Failed processing: ${JSON.stringify(error)} change: ${JSON.stringify({ id, rev: changes.map((c) => c.rev).join(","), seq: seq })}`,
      );
    } finally {
      await serviceSeqTracker.saveSeq(seq);
    }
  }
};
