import { fetch } from "pouchdb-fetch";

const dbsSecurity = {
  _users: null,
  _replicator: null,
  _global_changes: null,

  server_settings: {
    admins: { roles: ["_admin"] },
    members: { roles: ["_admin"] },
  },
  web_push_subscriptions: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  messages: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  chats: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  qr: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  public_settings: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  user_chat_settings: {
    admins: { roles: ["_admin"] },
    members: { roles: [] },
  },
  tg_bot_updates: {
    admins: { roles: ["_admin"] },
    members: { roles: ["_admin"] },
  },
  tg_bot_sessions: {
    admins: { roles: ["_admin"] },
    members: { roles: ["_admin"] },
  },
};

if (!process.env.API_URL) {
  throw new Error("Environment variable API_URL is not set");
}
const urlObject = new URL(process.env.API_URL);
const auth = `${urlObject.username}:${urlObject.password}`;
const headers = {
  "Content-Type": "application/json",
  Authorization: "Basic " + btoa(auth),
};
const getUrl = (dbUrlPath) => {
  return `${urlObject.protocol}//${urlObject.host}${urlObject.pathname}/${dbUrlPath}${urlObject.search}${urlObject.hash}`;
};

export const up = async () => {
  for (const [dbName, dbSecurity] of Object.entries(dbsSecurity)) {
    const responseCreateDb = await fetch(getUrl(dbName), {
      method: "PUT",
      headers,
    }).then((response) => response.json());

    if (responseCreateDb.ok) {
      console.log(`created ${dbName}`);
    } else if (responseCreateDb.error === "file_exists") {
      console.log(`exists ${dbName}`);
    } else {
      throw new Error(
        `${dbName} create error ${JSON.stringify(responseCreateDb)}`,
      );
    }

    if (!dbSecurity) {
      continue;
    }

    const responseSetSecurity = await fetch(getUrl(`${dbName}/_security`), {
      method: "PUT",
      headers,
      body: JSON.stringify(dbSecurity),
    }).then((response) => response.json());

    if (responseSetSecurity.ok) {
      console.log(`security ${dbName}`);
    } else {
      throw new Error(
        `${dbName} security error ${JSON.stringify(responseSetSecurity)}`,
      );
    }
  }
};

export const down = async () => {
  const promises = Object.keys(dbsSecurity).map(async (dbName) => {
    const responseDeleteDb = await fetch(getUrl(dbName), {
      headers,
      method: "DELETE",
    }).then((response) => response.json());
    if (responseDeleteDb.ok) {
      console.log(`deleted ${dbName}`);
    } else {
      console.error(
        `${dbName} delete error ${JSON.stringify(responseDeleteDb)}`,
      );
    }
  });
  await Promise.allSettled(promises);
  await Promise.all(promises);
};
