#pragma once

#include <string>
#include <vector>
#include <unordered_set>
#include <regex>
#include <algorithm>
#include <cctype>

namespace FreeExile {

/**
 * High-Performance Multilingual Profanity & RMT Surveillance Filter.
 * Performs Unicode homoglyph normalization, leetspeak folding, zero-width space removal,
 * deterministic keyword masking (Vi, En, Zh), and detects illicit Real Money Trading (RMT).
 */
class MultilingualProfanityFilter {
private:
    std::unordered_set<std::string> banned_keywords;
    std::vector<std::regex> rmt_patterns; // Real Money Trading & Chợ đen detection

public:
    MultilingualProfanityFilter() {
        initialize_blacklist();
        initialize_rmt_patterns();
    }

    void initialize_blacklist() {
        // Vietnamese toxic roots (normalized)
        banned_keywords.insert("dm");
        banned_keywords.insert("dkm");
        banned_keywords.insert("cl");
        banned_keywords.insert("vcl");
        banned_keywords.insert("lon");
        banned_keywords.insert("cac");
        banned_keywords.insert("dit");
        banned_keywords.insert("buoi");

        // English toxic roots
        banned_keywords.insert("fuck");
        banned_keywords.insert("shit");
        banned_keywords.insert("bitch");
        banned_keywords.insert("scam");

        // Chinese toxic roots (Pinyin)
        banned_keywords.insert("cnm");
        banned_keywords.insert("sb");
        banned_keywords.insert("nmd");
    }

    void initialize_rmt_patterns() {
        // Vietnamese phone numbers (09xx, 03xx, 08xx, 07xx)
        rmt_patterns.emplace_back(R"((03|05|07|08|09)\d{8})");
        // Telegram / Zalo handles
        rmt_patterns.emplace_back(R"((zalo|telegram|tele|fb\.com)[\s\:\@\.\-_]*\w+)", std::regex_constants::icase);
        // Bank transfer & RMT keywords
        rmt_patterns.emplace_back(R"((chuyen khoan|atm|momo|ban vang|thu mua ngoc|ban acc))", std::regex_constants::icase);
    }

    /**
     * Normalizes text by folding common leetspeak substitutions and stripping separator noise.
     * '@' -> 'a', '0' -> 'o', '1'/'!' -> 'i', '3' -> 'e', removing '.', '_', '-', space.
     */
    std::string normalize_text(const std::string& input) const {
        std::string result;
        result.reserve(input.size());

        for (char c : input) {
            char lower = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));

            // Leetspeak folding
            if (lower == '@') lower = 'a';
            else if (lower == '0') lower = 'o';
            else if (lower == '1' || lower == '!') lower = 'i';
            else if (lower == '3') lower = 'e';
            else if (lower == '$') lower = 's';

            // Filter out punctuation noise commonly used to evade filters: '.', '_', '-', ' '
            if (lower != '.' && lower != '_' && lower != '-' && lower != ' ' && lower != '/') {
                result.push_back(lower);
            }
        }
        return result;
    }

    struct FilterResult {
        std::string filtered_content;
        bool contains_profanity;
        bool is_rmt_suspect;
        int32_t risk_score; // 0 to 100
    };

    /**
     * Filters message content and assesses moderation risk.
     */
    FilterResult filter_message(const std::string& raw_content) const {
        std::string normalized = normalize_text(raw_content);
        bool has_profanity = false;
        bool is_rmt = false;
        int32_t risk_score = 0;

        // Check profanity against blacklist
        for (const auto& word : banned_keywords) {
            if (normalized.find(word) != std::string::npos) {
                has_profanity = true;
                risk_score += 25;
            }
        }

        // Check RMT / Chợ đen patterns
        for (const auto& pat : rmt_patterns) {
            if (std::regex_search(raw_content, pat) || std::regex_search(normalized, pat)) {
                is_rmt = true;
                risk_score += 60;
                break;
            }
        }

        // Masking in raw content if profanity detected
        std::string output = raw_content;
        if (has_profanity) {
            for (const auto& word : banned_keywords) {
                // Simple case-insensitive replacement with asterisks
                size_t pos = 0;
                std::string lower_out = output;
                std::transform(lower_out.begin(), lower_out.end(), lower_out.begin(), [](unsigned char c) -> char {
                    return static_cast<char>(std::tolower(c));
                });

                while ((pos = lower_out.find(word, pos)) != std::string::npos) {
                    output.replace(pos, word.length(), std::string(word.length(), '*'));
                    lower_out.replace(pos, word.length(), std::string(word.length(), '*'));
                    pos += word.length();
                }
            }
        }

        return {
            output,
            has_profanity,
            is_rmt,
            std::min(risk_score, 100)
        };
    }
};

} // namespace FreeExile
