import { hasManageGuildPermission, type DashboardGuild } from '@nexumi/shared';
import { fetchDiscordUserGuildsCached } from './discord-oauth';
import { hasOwnerGuildBypass } from './owner-auth';
import { getOwnerGuildDiscordMeta } from './owner-guilds';
import { prisma } from './prisma';
import type { SessionPayload } from './session';

/** Administrator bit — used for synthetic owner-bypass guild entries. */
const ADMINISTRATOR_PERMISSION = '8';

/**
 * Returns the guilds the current session user can manage (Manage Guild
 * permission), enriched with whether Nexumi is already installed there.
 * SUPPORT+ owner-panel users also see all bot-installed guilds.
 * Guilds where the bot is present are sorted first.
 */
export async function getManageableGuilds(session: SessionPayload): Promise<DashboardGuild[]> {
  const discordGuilds = await fetchDiscordUserGuildsCached(session.accessToken).catch(() => []);
  const manageable = discordGuilds.filter((guild) => hasManageGuildPermission(guild.permissions));
  const byId = new Map<string, DashboardGuild>();

  const managedIds = manageable.map((guild) => guild.id);
  const presentManaged =
    managedIds.length > 0
      ? await prisma.guild.findMany({
          where: { id: { in: managedIds } },
          select: { id: true }
        })
      : [];
  const presentManagedIds = new Set(presentManaged.map((guild) => guild.id));

  for (const guild of manageable) {
    byId.set(guild.id, {
      id: guild.id,
      name: guild.name,
      icon: guild.icon,
      botPresent: presentManagedIds.has(guild.id),
      permissions: guild.permissions
    });
  }

  if (await hasOwnerGuildBypass(session.user.id)) {
    const installed = await prisma.guild.findMany({
      select: { id: true },
      take: 200,
      orderBy: { createdAt: 'desc' }
    });
    for (const row of installed) {
      if (byId.has(row.id)) {
        const existing = byId.get(row.id)!;
        byId.set(row.id, { ...existing, botPresent: true });
        continue;
      }
      const meta = await getOwnerGuildDiscordMeta(row.id);
      byId.set(row.id, {
        id: row.id,
        name: meta?.name ?? `Guild ${row.id}`,
        icon: meta?.icon ?? null,
        botPresent: true,
        permissions: ADMINISTRATOR_PERMISSION
      });
    }
  }

  return [...byId.values()].sort((a, b) => {
    if (a.botPresent !== b.botPresent) {
      return a.botPresent ? -1 : 1;
    }
    return a.name.localeCompare(b.name);
  });
}

/**
 * Looks up a single manageable guild by id, or null when the session user
 * does not manage it via Discord OAuth / owner bypass.
 */
export async function getManageableGuild(
  session: SessionPayload,
  guildId: string
): Promise<DashboardGuild | null> {
  const guilds = await getManageableGuilds(session);
  return guilds.find((guild) => guild.id === guildId) ?? null;
}

/**
 * Resolves a guild for the dashboard shell: normal Manage Guild membership,
 * or owner-panel bypass via Discord bot guild metadata when the bot is
 * installed but the user is not a Discord manager of that server.
 */
export async function resolveDashboardGuild(
  session: SessionPayload,
  guildId: string
): Promise<{ guild: DashboardGuild; ownerBypass: boolean } | null> {
  const managed = await getManageableGuild(session, guildId);
  if (managed?.botPresent) {
    const bypass = await hasOwnerGuildBypass(session.user.id);
    const onDiscord = Boolean(
      (await fetchDiscordUserGuildsCached(session.accessToken).catch(() => [])).find(
        (entry) => entry.id === guildId && hasManageGuildPermission(entry.permissions)
      )
    );
    return { guild: managed, ownerBypass: bypass && !onDiscord };
  }

  if (!(await hasOwnerGuildBypass(session.user.id))) {
    return managed ? { guild: managed, ownerBypass: false } : null;
  }

  const dbGuild = await prisma.guild.findUnique({ where: { id: guildId } });
  if (!dbGuild) {
    return null;
  }

  const meta = await getOwnerGuildDiscordMeta(guildId);
  return {
    ownerBypass: true,
    guild: {
      id: guildId,
      name: meta?.name ?? `Guild ${guildId}`,
      icon: meta?.icon ?? null,
      botPresent: true,
      permissions: ADMINISTRATOR_PERMISSION
    }
  };
}
