import PouchDB from "./PouchDB";
import { ServiceSeqTrackerDatabase } from "@hereconnect/lib-service-seq-tracker";

import type {
  QRCodeDocument,
  UserChatSettingsDocument,
  PublicSettingsDocument,
  UserDocument,
  MessageDocument,
} from "@hereconnect/types";

import type { ServiceSeqTrackerDocument } from "@hereconnect/lib-service-seq-tracker";

import type { TgBotUpdateWebhookDesignDocument } from "@hereconnect/tg-bot-update-webhook-ddoc";
import { CouchDBSessionDocument } from "./bot/storageAdapters/CouchDBStorageAdapter";
import type { SessionData } from "./types/myContext";
import { TgBotUpdateDocument } from "./types/TgBotUpdateDocument";
import { env } from "./config/env";

if (!env.API_URL) {
  throw new Error("Environment variable API_URL is not set");
}

export const TG_BOT_UPDATES_DB_NAME = "tg_bot_updates";
export const MESSAGES_DB_NAME = "messages";
export const TG_BOT_UPDATES_DB_URL = `${env.API_URL}/${TG_BOT_UPDATES_DB_NAME}`;
export const MESSAGES_DB_URL = `${env.API_URL}/${MESSAGES_DB_NAME}`;

export const messagesDb = new PouchDB<MessageDocument>(MESSAGES_DB_URL, {
  skip_setup: true,
});
export const messagesServiceSeqTrackerDb =
  messagesDb satisfies PouchDB.Database as PouchDB.Database as PouchDB.Database<ServiceSeqTrackerDocument>;

export const publicSettingsDb = new PouchDB<PublicSettingsDocument>(
  `${env.API_URL}/public_settings`,
  { skip_setup: true },
);

export const qrDb = new PouchDB<QRCodeDocument>(`${env.API_URL}/qr`, {
  skip_setup: true,
});

export const tgBotSessionsDb = new PouchDB<CouchDBSessionDocument<SessionData>>(
  `${env.API_URL}/tg_bot_sessions`,
  { skip_setup: true },
);

export const tgBotUpdatesDb = new PouchDB<TgBotUpdateDocument>(
  `${TG_BOT_UPDATES_DB_URL}`,
  { skip_setup: true },
);

export const tgBotUpdatesDesignDocumentsDb =
  tgBotUpdatesDb satisfies PouchDB.Database as PouchDB.Database as PouchDB.Database<TgBotUpdateWebhookDesignDocument>;

export const tgBotUpdatesServiceSeqTrackerDb =
  tgBotUpdatesDb satisfies PouchDB.Database as PouchDB.Database as ServiceSeqTrackerDatabase;

export const userChatSettingsDb = new PouchDB<UserChatSettingsDocument>(
  `${env.API_URL}/user_chat_settings`,
  { skip_setup: true },
);

export const usersDb = new PouchDB<UserDocument>(`${env.API_URL}/_users`, {
  skip_setup: true,
});

const checkDatabases = async () => {
  const databases = {
    publicSettingsDb,
    qrDb,
    usersDb,
    userChatSettingsDb,
    tgBotUpdatesDb,
    tgBotSessionsDb,
    messagesServiceSeqTrackerDb,
    messagesDb,
  } as const;

  const databasesEntries = Object.entries(databases);

  const resultEntries = await Promise.all(
    databasesEntries.map(
      async ([name, db]): Promise<
        [typeof name, Awaited<ReturnType<typeof db.info>>]
      > => {
        const info = await db.info();
        return [name, info];
      },
    ),
  );

  for (const [name, info] of resultEntries) {
    if ("error" in info && "reason" in info) {
      console.error(info);
      throw new Error(`[${name}] ${info.error}: ${info.reason}`);
    }
    if ("error" in info) {
      throw new Error(`[${name}] ${info.error}`);
    }
  }

  return Object.fromEntries(resultEntries);
};

export const checkDatabasesPromise = checkDatabases();
