import type { LogEventTypeDashboard, LoggingConfigDashboard, LoggingConfigDashboardPatch } from '@nexumi/shared';
import { prisma } from '../prisma';

async function ensureLoggingConfig(guildId: string) {
  await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
  return prisma.loggingConfig.upsert({
    where: { guildId },
    update: {},
    create: { guildId }
  });
}

export async function getLoggingDashboard(guildId: string): Promise<LoggingConfigDashboard> {
  const [config, channels] = await Promise.all([
    ensureLoggingConfig(guildId),
    prisma.logChannel.findMany({ where: { guildId }, orderBy: { eventType: 'asc' } })
  ]);

  return {
    enabled: config.enabled,
    ignoreBots: config.ignoreBots,
    ignoredChannelIds: config.ignoredChannelIds,
    ignoredRoleIds: config.ignoredRoleIds,
    retentionDays: config.retentionDays,
    logChannels: channels.map((channel) => ({
      eventType: channel.eventType as LogEventTypeDashboard,
      channelId: channel.channelId
    }))
  };
}

export async function updateLoggingDashboard(
  guildId: string,
  patch: LoggingConfigDashboardPatch
): Promise<LoggingConfigDashboard> {
  await ensureLoggingConfig(guildId);

  const { logChannels, ...configPatch } = patch;

  if (Object.keys(configPatch).length > 0) {
    await prisma.loggingConfig.update({ where: { guildId }, data: configPatch });
  }

  if (logChannels !== undefined) {
    await prisma.$transaction([
      prisma.logChannel.deleteMany({ where: { guildId } }),
      ...logChannels.map((mapping) =>
        prisma.logChannel.create({
          data: { guildId, eventType: mapping.eventType, channelId: mapping.channelId }
        })
      )
    ]);
  }

  return getLoggingDashboard(guildId);
}
