import Foundation

/// Vangnet tegen "model antwoordt i.p.v. opschonen".
///
/// Soms ziet het enhancement-model een gedicteerde vraag/opdracht als een
/// commando aan zichzelf en genereert een antwoord in plaats van de tekst
/// op te schonen. In dat geval verdwijnen vrijwel alle oorspronkelijke
/// woorden. We detecteren dat via woord-behoud en vallen dan terug op de
/// (al gefilterde) rauwe transcriptie, zodat de gebruiker nooit een
/// AI-antwoord in plaats van zijn eigen woorden krijgt.
enum EnhancementDivergenceGuard {

    /// Geeft de veilige output terug: de enhanced tekst, of de originele
    /// transcriptie als de enhanced output te sterk afwijkt.
    /// - Returns: tuple van (gekozen tekst, of er teruggevallen is, behoud-ratio)
    static func resolve(original: String, enhanced: String) -> (text: String, didFallback: Bool, retention: Double) {
        let originalWords = contentWords(original)
        let enhancedWords = Set(contentWords(enhanced))

        // Te kort om betrouwbaar te oordelen: korte zinnen mogen sterk
        // veranderen door legitieme correctie. Niet ingrijpen.
        guard originalWords.count >= 4 else {
            return (enhanced, false, 1.0)
        }

        let originalSet = Set(originalWords)
        guard !originalSet.isEmpty else {
            return (enhanced, false, 1.0)
        }

        let kept = originalSet.intersection(enhancedWords).count
        let retention = Double(kept) / Double(originalSet.count)

        // < 50% van de oorspronkelijke inhoudswoorden overgebleven:
        // vrijwel zeker een gegenereerd antwoord, niet een opschoning.
        if retention < 0.5 {
            return (original, true, retention)
        }
        return (enhanced, false, retention)
    }

    /// Lowercase, leestekens weg, opgesplitst op witruimte. Lege strings eruit.
    private static func contentWords(_ s: String) -> [String] {
        let lowered = s.lowercased()
        let stripped = lowered.unicodeScalars.map { scalar -> Character in
            if CharacterSet.alphanumerics.contains(scalar) || scalar == " " || scalar == "\n" || scalar == "\t" {
                return Character(scalar)
            }
            return " "
        }
        return String(stripped)
            .split(whereSeparator: { $0 == " " || $0 == "\n" || $0 == "\t" })
            .map(String.init)
            .filter { !$0.isEmpty }
    }
}
