import type { PrismaClient } from '@prisma/client';
import {
  DEFAULT_AUTOMOD_RULES,
  type AutoModExceptions,
  type AutoModThreshold,
  type AutoModWordList
} from '@nexumi/shared';
import { ensureGuild } from '../../guild.js';

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

export async function ensureDefaultAutoModRules(prisma: PrismaClient, guildId: string) {
  await ensureGuild(prisma, guildId);
  const existing = await prisma.autoModRule.findMany({
    where: { guildId },
    select: { ruleType: true }
  });
  const have = new Set(existing.map((row) => row.ruleType));
  const missing = DEFAULT_AUTOMOD_RULES.filter((rule) => !have.has(rule.ruleType));
  if (missing.length === 0) {
    return;
  }
  await prisma.autoModRule.createMany({
    data: missing.map((rule) => ({
      guildId,
      ruleType: rule.ruleType,
      action: rule.action,
      threshold: rule.threshold ?? undefined,
      wordList: rule.wordList ?? undefined,
      enabled: ['SPAM', 'MASS_MENTION', 'INVITE_LINK', 'PHISHING'].includes(rule.ruleType)
    }))
  });
}

export async function getEnabledAutoModRules(prisma: PrismaClient, guildId: string) {
  await ensureDefaultAutoModRules(prisma, guildId);
  return prisma.autoModRule.findMany({
    where: { guildId, enabled: true }
  });
}

export function parseExceptions(raw: unknown): AutoModExceptions {
  if (!raw || typeof raw !== 'object') {
    return { roleIds: [], channelIds: [] };
  }
  const obj = raw as Record<string, unknown>;
  return {
    roleIds: Array.isArray(obj.roleIds) ? obj.roleIds.map(String) : [],
    channelIds: Array.isArray(obj.channelIds) ? obj.channelIds.map(String) : []
  };
}

export function parseThreshold(raw: unknown): AutoModThreshold {
  if (!raw || typeof raw !== 'object') {
    return {};
  }
  return raw as AutoModThreshold;
}

export function parseWordList(raw: unknown): AutoModWordList {
  if (!raw || typeof raw !== 'object') {
    return { words: [], regexPatterns: [] };
  }
  const obj = raw as Record<string, unknown>;
  return {
    words: Array.isArray(obj.words) ? obj.words.map(String) : [],
    regexPatterns: Array.isArray(obj.regexPatterns) ? obj.regexPatterns.map(String) : []
  };
}

export function isExcepted(
  exceptions: AutoModExceptions,
  channelId: string,
  roleIds: string[]
): boolean {
  if (exceptions.channelIds.includes(channelId)) {
    return true;
  }
  return roleIds.some((roleId) => exceptions.roleIds.includes(roleId));
}
