import { prisma } from '../../../config/database';
import { WordFilterLevel } from '@prisma/client';

export interface WordFilterResult {
  blocked: boolean;
  autoHide: boolean;
  flagged: boolean;
  reason?: string;
  matchedWords: string[];
  highestLevel: WordFilterLevel | null;
}

// In-memory cache of word list (refreshed periodically)
let wordListCache: { word: string; level: WordFilterLevel }[] = [];
let cacheLoadedAt = 0;
const CACHE_TTL = 60 * 1000; // 1 minute

async function loadWordList(): Promise<void> {
  const now = Date.now();
  if (now - cacheLoadedAt < CACHE_TTL && wordListCache.length > 0) {
    return;
  }

  const words = await prisma.moderationWordList.findMany({
    select: { word: true, level: true },
  });

  wordListCache = words;
  cacheLoadedAt = now;
}

/**
 * Check content against the moderation word list.
 *
 * Levels:
 * - high: auto-block (reject submission entirely)
 * - medium: auto-hide (saved but hidden, pending review)
 * - low: flag for review (saved and visible, but flagged)
 */
export async function checkContent(text: string): Promise<WordFilterResult> {
  await loadWordList();

  if (wordListCache.length === 0) {
    return { blocked: false, autoHide: false, flagged: false, matchedWords: [], highestLevel: null };
  }

  const normalizedText = text.toLowerCase();
  const matchedWords: string[] = [];
  let highestLevel: WordFilterLevel | null = null;

  const levelPriority: Record<string, number> = {
    high: 3,
    medium: 2,
    low: 1,
    custom: 0,
  };

  for (const entry of wordListCache) {
    // Word boundary match (case-insensitive)
    const escaped = entry.word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const regex = new RegExp(`\\b${escaped}\\b`, 'i');

    if (regex.test(normalizedText)) {
      matchedWords.push(entry.word);

      if (!highestLevel || levelPriority[entry.level] > levelPriority[highestLevel]) {
        highestLevel = entry.level;
      }
    }
  }

  if (matchedWords.length === 0) {
    return { blocked: false, autoHide: false, flagged: false, matchedWords: [], highestLevel: null };
  }

  const blocked = highestLevel === 'high';
  const autoHide = highestLevel === 'medium' || highestLevel === 'high';
  const flagged = highestLevel === 'low';

  return {
    blocked,
    autoHide,
    flagged,
    reason: `Matched word filter: ${matchedWords.join(', ')} (level: ${highestLevel})`,
    matchedWords,
    highestLevel,
  };
}

/**
 * Invalidate the word list cache (call after adding/removing words)
 */
export function invalidateWordListCache(): void {
  cacheLoadedAt = 0;
}
