import type { PrismaClient } from '@prisma/client';
import type { WelcomeEmbed, WelcomeMessageType } from '@nexumi/shared';
import { applyWelcomePlaceholders, parseMessageComponentsV2 } from '@nexumi/shared';
import type { Guild, GuildMember } from 'discord.js';
import { ensureGuild } from '../../guild.js';

export async function getWelcomeConfig(prisma: PrismaClient, guildId: string) {
  await ensureGuild(prisma, guildId);
  let config = await prisma.welcomeConfig.findUnique({ where: { guildId } });
  if (!config) {
    config = await prisma.welcomeConfig.create({ data: { guildId } });
  }
  return config;
}

export type WelcomePlaceholderOptions = {
  /**
   * When false, `{user}` becomes the member display name instead of `<@id>`.
   * Required for embed title/author/footer and canvas text — Discord does not
   * resolve mentions in those surfaces.
   */
  mentionUser?: boolean;
};

export function buildPlaceholderVars(
  member: GuildMember,
  guild: Guild,
  options: WelcomePlaceholderOptions = {}
) {
  const mentionUser = options.mentionUser !== false;
  return {
    user: mentionUser ? `<@${member.id}>` : member.displayName,
    'user.name': member.displayName,
    'user.tag': member.user.tag,
    'user.id': member.id,
    'user.avatar': member.user.displayAvatarURL({ size: 256 }),
    server: guild.name,
    memberCount: guild.memberCount,
    'server.icon': guild.iconURL({ size: 128 }) ?? ''
  };
}

export function renderWelcomeText(
  template: string,
  member: GuildMember,
  guild: Guild,
  options: WelcomePlaceholderOptions = {}
): string {
  return applyWelcomePlaceholders(template, buildPlaceholderVars(member, guild, options));
}

/** Fields where Discord will not turn `<@id>` into a clickable mention. */
const EMBED_PLAIN_USER_FIELDS = new Set(['title', 'authorName', 'footerText']);

export function renderWelcomeEmbedText(
  template: string,
  member: GuildMember,
  guild: Guild,
  field: string
): string {
  return renderWelcomeText(template, member, guild, {
    mentionUser: !EMBED_PLAIN_USER_FIELDS.has(field)
  });
}

export function parseWelcomeEmbed(raw: unknown): WelcomeEmbed | null {
  if (!raw || typeof raw !== 'object') {
    return null;
  }
  return raw as WelcomeEmbed;
}

export type WelcomePayload = {
  type: WelcomeMessageType;
  content?: string | null;
  embed?: WelcomeEmbed | null;
  components?: import('@nexumi/shared').MessageComponentsV2 | null;
  imageTitle?: string | null;
  imageSubtitle?: string | null;
};

export function resolveWelcomePayload(
  config: Awaited<ReturnType<typeof getWelcomeConfig>>
): WelcomePayload {
  return {
    type: config.welcomeType as WelcomeMessageType,
    content: config.welcomeContent,
    embed: parseWelcomeEmbed(config.welcomeEmbed),
    components: parseMessageComponentsV2(config.welcomeComponents),
    imageTitle: config.imageTitle,
    imageSubtitle: config.imageSubtitle
  };
}

export type LeavePayload = {
  type: import('@nexumi/shared').LeaveMessageType;
  content?: string | null;
  embed?: WelcomeEmbed | null;
  components?: import('@nexumi/shared').MessageComponentsV2 | null;
};

export function resolveLeavePayload(
  config: Awaited<ReturnType<typeof getWelcomeConfig>>
): LeavePayload {
  return {
    type: (config.leaveType as LeavePayload['type']) || 'TEXT',
    content: config.leaveContent,
    embed: parseWelcomeEmbed(config.leaveEmbed),
    components: parseMessageComponentsV2(config.leaveComponents)
  };
}
