import { prisma } from '../database'; export interface GuildSettings { welcomeChannelId?: string; logChannelId?: string; automodEnabled?: boolean; automodConfig?: any; statuspageEnabled?: boolean; statuspageConfig?: any; welcomeConfig?: { enabled?: boolean; channelId?: string; embedTitle?: string; embedDescription?: string; embedColor?: string; embedFooter?: string; embedThumbnail?: string; embedImage?: string; embedThumbnailData?: string; embedImageData?: string; }; loggingConfig?: { logChannelId?: string; categories?: { joinLeave?: boolean; messageEdit?: boolean; messageDelete?: boolean; automodActions?: boolean; ticketActions?: boolean; musicEvents?: boolean; }; }; levelingEnabled?: boolean; ticketsEnabled?: boolean; musicEnabled?: boolean; dynamicVoiceEnabled?: boolean; dynamicVoiceConfig?: { lobbyChannelId?: string; categoryId?: string; userLimit?: number; bitrate?: number; template?: string; }; eventsEnabled?: boolean; supportLoginConfig?: { panelChannelId?: string; panelMessageId?: string; title?: string; description?: string; loginLabel?: string; logoutLabel?: string; autoRefresh?: boolean; }; birthdayEnabled?: boolean; birthdayConfig?: { enabled?: boolean; channelId?: string; sendHour?: number; messageTemplate?: string; }; reactionRolesEnabled?: boolean; reactionRolesConfig?: any; supportRoleId?: string; welcomeEnabled?: boolean; } class SettingsStore { private cache = new Map(); private applyModuleDefaults(cfg: GuildSettings): GuildSettings { const normalized: GuildSettings = { ...cfg }; ( [ 'ticketsEnabled', 'automodEnabled', 'welcomeEnabled', 'levelingEnabled', 'musicEnabled', 'dynamicVoiceEnabled', 'statuspageEnabled', 'birthdayEnabled', 'reactionRolesEnabled', 'eventsEnabled' ] as const ).forEach((key) => { if (normalized[key] === undefined) normalized[key] = true; }); // keep welcomeConfig flag in sync when present if (normalized.welcomeConfig && normalized.welcomeConfig.enabled === undefined && normalized.welcomeEnabled !== undefined) { normalized.welcomeConfig = { ...normalized.welcomeConfig, enabled: normalized.welcomeEnabled }; } return normalized; } public async init() { const rows = await prisma.guildSettings.findMany(); rows.forEach((row) => { const cfg = { welcomeChannelId: row.welcomeChannelId ?? undefined, logChannelId: row.logChannelId ?? undefined, automodEnabled: row.automodEnabled ?? undefined, automodConfig: (row as any).automodConfig ?? undefined, statuspageEnabled: (row as any).statuspageEnabled ?? (row as any).automodConfig?.statuspageEnabled ?? undefined, statuspageConfig: (row as any).statuspageConfig ?? (row as any).automodConfig?.statuspageConfig ?? undefined, welcomeEnabled: (row as any).welcomeEnabled ?? undefined, welcomeConfig: (row as any).automodConfig?.welcomeConfig ?? undefined, loggingConfig: (row as any).automodConfig?.loggingConfig ?? undefined, levelingEnabled: row.levelingEnabled ?? undefined, ticketsEnabled: row.ticketsEnabled ?? undefined, musicEnabled: (row as any).musicEnabled ?? undefined, dynamicVoiceEnabled: (row as any).dynamicVoiceEnabled ?? undefined, dynamicVoiceConfig: (row as any).dynamicVoiceConfig ?? undefined, eventsEnabled: (row as any).eventsEnabled ?? undefined, supportLoginConfig: (row as any).supportLoginConfig ?? undefined, birthdayEnabled: (row as any).birthdayEnabled ?? undefined, birthdayConfig: (row as any).birthdayConfig ?? undefined, reactionRolesEnabled: (row as any).reactionRolesEnabled ?? undefined, reactionRolesConfig: (row as any).reactionRolesConfig ?? undefined, supportRoleId: row.supportRoleId ?? undefined } satisfies GuildSettings; this.cache.set(row.guildId, this.applyModuleDefaults(cfg)); }); return this.cache; } public get(guildId: string) { const cached = this.cache.get(guildId); return cached ? this.applyModuleDefaults(cached) : undefined; } public all() { return this.cache; } public async set(guildId: string, partial: GuildSettings) { if ((partial as any).welcomeEnabled !== undefined) { partial.welcomeConfig = { ...(partial.welcomeConfig ?? {}), enabled: (partial as any).welcomeEnabled }; delete (partial as any).welcomeEnabled; } if (partial.birthdayEnabled !== undefined) { partial.birthdayConfig = { ...(partial.birthdayConfig ?? {}), enabled: partial.birthdayEnabled }; } else if (partial.birthdayConfig?.enabled !== undefined) { partial.birthdayEnabled = partial.birthdayConfig.enabled; } if (partial.reactionRolesEnabled !== undefined) { partial.reactionRolesConfig = { ...(partial.reactionRolesConfig ?? {}), enabled: partial.reactionRolesEnabled }; } else if (partial.reactionRolesConfig?.enabled !== undefined) { partial.reactionRolesEnabled = partial.reactionRolesConfig.enabled; } const merged: GuildSettings = this.applyModuleDefaults({ ...(this.cache.get(guildId) ?? {}), ...partial }); const mergedAutomod = { ...(merged.automodConfig ?? {}), ...(partial.automodConfig ?? {}), loggingConfig: partial.loggingConfig ?? merged.loggingConfig ?? merged.automodConfig?.loggingConfig, welcomeConfig: partial.welcomeConfig ?? merged.welcomeConfig ?? merged.automodConfig?.welcomeConfig, statuspageEnabled: merged.statuspageEnabled, statuspageConfig: partial.statuspageConfig ?? merged.statuspageConfig ?? merged.automodConfig?.statuspageConfig }; if (partial.dynamicVoiceConfig) { merged.dynamicVoiceConfig = { ...(merged.dynamicVoiceConfig ?? {}), ...partial.dynamicVoiceConfig }; } if (partial.supportLoginConfig) { merged.supportLoginConfig = { ...(merged.supportLoginConfig ?? {}), ...partial.supportLoginConfig }; } if (partial.birthdayConfig) { merged.birthdayConfig = { ...(merged.birthdayConfig ?? {}), ...partial.birthdayConfig }; } if (partial.reactionRolesConfig) { merged.reactionRolesConfig = { ...(merged.reactionRolesConfig ?? {}), ...partial.reactionRolesConfig }; } merged.automodConfig = { ...mergedAutomod, supportLoginConfig: merged.supportLoginConfig ?? mergedAutomod['supportLoginConfig'] }; merged.statuspageEnabled = mergedAutomod.statuspageEnabled; merged.statuspageConfig = mergedAutomod.statuspageConfig; merged.loggingConfig = mergedAutomod.loggingConfig; merged.welcomeConfig = mergedAutomod.welcomeConfig; this.cache.set(guildId, merged); await prisma.guildSettings.upsert({ where: { guildId }, update: { welcomeChannelId: merged.welcomeChannelId ?? null, logChannelId: merged.logChannelId ?? null, automodEnabled: merged.automodEnabled ?? null, automodConfig: merged.automodConfig ?? null, levelingEnabled: merged.levelingEnabled ?? null, ticketsEnabled: merged.ticketsEnabled ?? null, musicEnabled: merged.musicEnabled ?? null, statuspageEnabled: merged.statuspageEnabled ?? null, statuspageConfig: merged.statuspageConfig ?? null, dynamicVoiceEnabled: merged.dynamicVoiceEnabled ?? null, dynamicVoiceConfig: merged.dynamicVoiceConfig ?? null, eventsEnabled: (merged as any).eventsEnabled ?? null, birthdayEnabled: merged.birthdayEnabled ?? null, birthdayConfig: merged.birthdayConfig ?? null, reactionRolesEnabled: merged.reactionRolesEnabled ?? null, reactionRolesConfig: merged.reactionRolesConfig ?? null, supportRoleId: merged.supportRoleId ?? null }, create: { guildId, welcomeChannelId: merged.welcomeChannelId ?? null, logChannelId: merged.logChannelId ?? null, automodEnabled: merged.automodEnabled ?? null, automodConfig: merged.automodConfig ?? null, levelingEnabled: merged.levelingEnabled ?? null, ticketsEnabled: merged.ticketsEnabled ?? null, musicEnabled: merged.musicEnabled ?? null, statuspageEnabled: merged.statuspageEnabled ?? null, statuspageConfig: merged.statuspageConfig ?? null, dynamicVoiceEnabled: merged.dynamicVoiceEnabled ?? null, dynamicVoiceConfig: merged.dynamicVoiceConfig ?? null, eventsEnabled: (merged as any).eventsEnabled ?? null, birthdayEnabled: merged.birthdayEnabled ?? null, birthdayConfig: merged.birthdayConfig ?? null, reactionRolesEnabled: merged.reactionRolesEnabled ?? null, reactionRolesConfig: merged.reactionRolesConfig ?? null, supportRoleId: merged.supportRoleId ?? null } }); return merged; } } export const settingsStore = new SettingsStore(); // Backwards compatibility for existing imports (read-only) export const settings = settingsStore.all();