import {
  MessageComponentsV2Schema,
  WelcomeEmbedSchema,
  type MessageComponentsV2,
  type WelcomeConfigDashboard,
  type WelcomeConfigDashboardPatch,
  type WelcomeEmbed
} from '@nexumi/shared';
import { Prisma } from '@prisma/client';
import { prisma } from '../prisma';

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

function parseEmbed(raw: unknown): WelcomeEmbed | null {
  const parsed = WelcomeEmbedSchema.safeParse(raw);
  return parsed.success ? parsed.data : null;
}

function parseComponents(raw: unknown): MessageComponentsV2 | null {
  const parsed = MessageComponentsV2Schema.safeParse(raw);
  return parsed.success ? parsed.data : null;
}

function toDashboard(config: Awaited<ReturnType<typeof ensureWelcomeConfig>>): WelcomeConfigDashboard {
  return {
    welcomeEnabled: config.welcomeEnabled,
    leaveEnabled: config.leaveEnabled,
    welcomeChannelId: config.welcomeChannelId ?? '',
    leaveChannelId: config.leaveChannelId ?? '',
    welcomeType: config.welcomeType as WelcomeConfigDashboard['welcomeType'],
    welcomeContent: config.welcomeContent,
    welcomeEmbed: parseEmbed(config.welcomeEmbed),
    welcomeComponents: parseComponents(config.welcomeComponents),
    leaveType: config.leaveType as WelcomeConfigDashboard['leaveType'],
    leaveContent: config.leaveContent,
    leaveEmbed: parseEmbed(config.leaveEmbed),
    leaveComponents: parseComponents(config.leaveComponents),
    welcomeDmEnabled: config.welcomeDmEnabled,
    welcomeDmContent: config.welcomeDmContent,
    userAutoroleIds: config.userAutoroleIds,
    botAutoroleIds: config.botAutoroleIds,
    imageTitle: config.imageTitle,
    imageSubtitle: config.imageSubtitle
  };
}

export async function getWelcomeDashboard(guildId: string): Promise<WelcomeConfigDashboard> {
  const config = await ensureWelcomeConfig(guildId);
  return toDashboard(config);
}

export async function updateWelcomeDashboard(
  guildId: string,
  patch: WelcomeConfigDashboardPatch
): Promise<WelcomeConfigDashboard> {
  await ensureWelcomeConfig(guildId);

  const {
    welcomeChannelId,
    leaveChannelId,
    welcomeEmbed,
    leaveEmbed,
    welcomeComponents,
    leaveComponents,
    ...rest
  } = patch;

  const data: Prisma.WelcomeConfigUpdateInput = { ...rest };
  if (welcomeChannelId !== undefined) {
    data.welcomeChannelId = welcomeChannelId === '' ? null : welcomeChannelId;
  }
  if (leaveChannelId !== undefined) {
    data.leaveChannelId = leaveChannelId === '' ? null : leaveChannelId;
  }
  if (welcomeEmbed !== undefined) {
    data.welcomeEmbed = welcomeEmbed === null ? Prisma.JsonNull : (welcomeEmbed as Prisma.InputJsonValue);
  }
  if (leaveEmbed !== undefined) {
    data.leaveEmbed = leaveEmbed === null ? Prisma.JsonNull : (leaveEmbed as Prisma.InputJsonValue);
  }
  if (welcomeComponents !== undefined) {
    data.welcomeComponents =
      welcomeComponents === null ? Prisma.JsonNull : (welcomeComponents as Prisma.InputJsonValue);
  }
  if (leaveComponents !== undefined) {
    data.leaveComponents =
      leaveComponents === null ? Prisma.JsonNull : (leaveComponents as Prisma.InputJsonValue);
  }

  const updated = await prisma.welcomeConfig.update({ where: { guildId }, data });
  return toDashboard(updated);
}
