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

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

  if (manageable.length === 0) {
    return [];
  }

  const presentGuilds = await prisma.guild.findMany({
    where: { id: { in: manageable.map((guild) => guild.id) } },
    select: { id: true }
  });
  const presentIds = new Set(presentGuilds.map((guild) => guild.id));

  return manageable
    .map<DashboardGuild>((guild) => ({
      id: guild.id,
      name: guild.name,
      icon: guild.icon,
      botPresent: presentIds.has(guild.id),
      permissions: guild.permissions
    }))
    .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.
 */
export async function getManageableGuild(
  session: SessionPayload,
  guildId: string
): Promise<DashboardGuild | null> {
  const guilds = await getManageableGuilds(session);
  return guilds.find((guild) => guild.id === guildId) ?? null;
}
