"""GameGrip Safety API — Content Classifiers

Each classifier returns a score 0-100 and confidence 0-1.
Replace mock implementations with real model APIs (Detoxify, Perspective, etc.)
"""

import re
from typing import Optional, Dict, Tuple
from models import CategoryScore


# ───────────────────────────────────────────────
# Keyword / Pattern Databases (Phase 1 + Phase 2)
# ───────────────────────────────────────────────
TOXIC_KEYWORDS = [
    "kill", "die", "stupid", "noob", "trash", "hate", "idiot", "loser",
    "suicide", "kys", "garbage", "worthless", "pathetic", "die in a fire"
]

SEXUAL_KEYWORDS = [
    "sex", "nude", "naked", "porn", "xxx", "nsfw", "boobs", "dick",
    "cum", "fuck", "horny", "onlyfans", "cam girl"
]

SCAM_PATTERNS = [
    "free skins", "account boost", "trade me", "click here", "free robux",
    "free vbucks", "double your", "send me your password", "verify your account",
    "i'm a moderator", "admin giveaway", "free gift card"
]

GROOMING_PATTERNS = [
    "don't tell your parents", "our secret", "meet me after", "send me a pic",
    "how old are you", "you're mature for your age", "private chat",
    "add me on discord", "move to snapchat", "what are you wearing"
]

HARASSMENT_PATTERNS = [
    "everyone hates you", "leave the game", "uninstall", "reported",
    "you're bad", "quit", "kill yourself", "nobody likes you"
]


# ───────────────────────────────────────────────
# Base Classifier Interface
# ───────────────────────────────────────────────
class BaseClassifier:
    name: str = "base"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        """Return (score 0-100, confidence 0-1)."""
        raise NotImplementedError


# ───────────────────────────────────────────────
# Text Classifiers
# ───────────────────────────────────────────────
class ToxicityClassifier(BaseClassifier):
    name = "toxicity"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        if not text:
            return 0.0, 0.0
        text_lower = text.lower()
        score = sum(12 for kw in TOXIC_KEYWORDS if kw in text_lower)
        # Bonus for severity stacking
        if sum(1 for kw in TOXIC_KEYWORDS if kw in text_lower) >= 3:
            score += 20
        return min(score, 80), 0.75


class SexualContentClassifier(BaseClassifier):
    name = "sexual"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        if not text:
            return 0.0, 0.0
        text_lower = text.lower()
        score = sum(20 for kw in SEXUAL_KEYWORDS if kw in text_lower)
        return min(score, 85), 0.80


class ScamClassifier(BaseClassifier):
    name = "scam"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        if not text:
            return 0.0, 0.0
        text_lower = text.lower()
        score = sum(25 for pattern in SCAM_PATTERNS if pattern in text_lower)
        # Urgency signals
        if any(w in text_lower for w in ["hurry", "limited", "now", "quick"]):
            score += 15
        return min(score, 75), 0.70


class GroomingClassifier(BaseClassifier):
    name = "grooming"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        if not text:
            return 0.0, 0.0
        text_lower = text.lower()
        score = sum(30 for pattern in GROOMING_PATTERNS if pattern in text_lower)
        return min(score, 90), 0.65


class HarassmentClassifier(BaseClassifier):
    name = "harassment"

    def classify(self, text: Optional[str]) -> Tuple[float, float]:
        if not text:
            return 0.0, 0.0
        text_lower = text.lower()
        score = sum(15 for pattern in HARASSMENT_PATTERNS if pattern in text_lower)
        return min(score, 70), 0.72


# ───────────────────────────────────────────────
# Image Classifier (Placeholder)
# ───────────────────────────────────────────────
class ImageRiskClassifier(BaseClassifier):
    name = "image"

    def classify(self, image_url: Optional[str], image_b64: Optional[str]) -> Tuple[float, float]:
        if not image_url and not image_b64:
            return 0.0, 0.0
        # Mock: any image gets baseline risk until real NSFW model is plugged in
        if image_b64:
            return min(len(image_b64) / 12000, 30), 0.50
        return 8.0, 0.50


# ───────────────────────────────────────────────
# Classifier Registry
# ───────────────────────────────────────────────
CLASSIFIERS: Dict[str, BaseClassifier] = {
    "toxicity": ToxicityClassifier(),
    "sexual": SexualContentClassifier(),
    "scam": ScamClassifier(),
    "grooming": GroomingClassifier(),
    "harassment": HarassmentClassifier(),
    "image": ImageRiskClassifier(),
}


def run_classifiers(text: Optional[str], image_url: Optional[str], image_b64: Optional[str],
                    enabled_categories: list[str]) -> list[CategoryScore]:
    """Run all enabled classifiers and return category scores."""
    results = []
    for cat in enabled_categories:
        classifier = CLASSIFIERS.get(cat)
        if not classifier:
            continue
        if cat == "image":
            score, confidence = classifier.classify(image_url, image_b64)
        else:
            score, confidence = classifier.classify(text)
        results.append(CategoryScore(category=cat, score=score, confidence=confidence))
    return results
