import { KNOWN_COMMAND_NAMES, type CommandOverrideDashboard, type CommandOverrideDashboardUpsert } from '@nexumi/shared';
import type { CommandOverride } from '@prisma/client';
import { prisma } from '../prisma';

function toDashboard(override: CommandOverride): CommandOverrideDashboard {
  return {
    commandName: override.commandName,
    enabled: override.enabled,
    allowedRoleIds: override.allowedRoleIds,
    deniedRoleIds: override.deniedRoleIds,
    allowedChannelIds: override.allowedChannelIds,
    deniedChannelIds: override.deniedChannelIds,
    cooldownSeconds: override.cooldownSeconds
  };
}

function defaultDashboard(commandName: string): CommandOverrideDashboard {
  return {
    commandName,
    enabled: true,
    allowedRoleIds: [],
    deniedRoleIds: [],
    allowedChannelIds: [],
    deniedChannelIds: [],
    cooldownSeconds: null
  };
}

/**
 * Lists every known command with its dashboard override (or sensible
 * defaults for commands that have never been overridden on this guild),
 * sorted alphabetically for a stable table.
 */
export async function listCommandOverridesDashboard(guildId: string): Promise<CommandOverrideDashboard[]> {
  const overrides = await prisma.commandOverride.findMany({ where: { guildId } });
  const byName = new Map(overrides.map((entry) => [entry.commandName, entry]));

  return [...KNOWN_COMMAND_NAMES]
    .sort((a, b) => a.localeCompare(b))
    .map((commandName) => {
      const existing = byName.get(commandName);
      return existing ? toDashboard(existing) : defaultDashboard(commandName);
    });
}

export async function upsertCommandOverrideDashboard(
  guildId: string,
  input: CommandOverrideDashboardUpsert
): Promise<CommandOverrideDashboard> {
  await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });

  const data = {
    enabled: input.enabled,
    allowedRoleIds: input.allowedRoleIds,
    deniedRoleIds: input.deniedRoleIds,
    allowedChannelIds: input.allowedChannelIds,
    deniedChannelIds: input.deniedChannelIds,
    cooldownSeconds: input.cooldownSeconds ?? null
  };

  const updated = await prisma.commandOverride.upsert({
    where: { guildId_commandName: { guildId, commandName: input.commandName } },
    update: data,
    create: { guildId, commandName: input.commandName, ...data }
  });
  return toDashboard(updated);
}

export async function resetCommandOverrideDashboard(
  guildId: string,
  commandName: string
): Promise<CommandOverrideDashboard> {
  await prisma.commandOverride.deleteMany({ where: { guildId, commandName } });
  return defaultDashboard(commandName);
}
