"""Privacy classifier -- determines if a request may leave the local machine.

PRIVATE (never leaves local machine):
- Contains PII patterns (email, phone, SSN, credit card)
- Contains medical/health data
- Contains credentials/API keys
- User explicitly flagged as sensitive

STANDARD (eligible for Hive routing):
- General code completion
- Knowledge questions
- Creative writing
"""

from __future__ import annotations

import logging
import re
from typing import ClassVar

from llmhosts.hive.models import PrivacyClassification, PrivacyTier

logger = logging.getLogger(__name__)


class PrivacyClassifier:
    """Classifies request privacy tier.

    PRIVATE (never leaves local machine):
    - Contains PII patterns (email, phone, SSN, credit card)
    - Contains medical/health data
    - Contains credentials/API keys
    - User explicitly flagged as sensitive

    STANDARD (eligible for Hive routing):
    - General code completion
    - Knowledge questions
    - Creative writing
    """

    # PII and sensitive data patterns (compiled once)
    PII_PATTERNS: ClassVar[list[re.Pattern[str]]] = [
        re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"),  # Email
        re.compile(r"\b\d{3}[-.\s]?\d{3}[-.\s]?\d{4}\b"),  # Phone (US)
        re.compile(r"\b\d{3}-\d{2}-\d{4}\b"),  # SSN
        re.compile(r"\b\d{4}[-.\s]?\d{4}[-.\s]?\d{4}[-.\s]?\d{4}\b"),  # Credit card
        re.compile(r"\b(?:sk|api[_-]?key|apikey)[-_:]\s*['\"]?[a-zA-Z0-9_-]{20,}['\"]?", re.I),  # API keys
        re.compile(r"\bBearer\s+[a-zA-Z0-9._-]{20,}\b", re.I),  # Bearer tokens
        re.compile(r"\bxox[baprs]-[a-zA-Z0-9-]{10,}\b", re.I),  # Slack tokens
    ]

    # Medical/health keywords (case-insensitive)
    MEDICAL_KEYWORDS: ClassVar[set[str]] = {
        "patient",
        "diagnosis",
        "medical record",
        "health insurance",
        "ssn",
        "phi",
        "hipaa",
        "prescription",
        "medication",
        "clinical",
        "symptom",
        "treatment",
        "doctor",
        "hospital",
    }

    # Explicit sensitive markers
    SENSITIVE_MARKERS: ClassVar[tuple[str, ...]] = (
        "[PRIVATE]",
        "[SENSITIVE]",
        "[CONFIDENTIAL]",
        "[DO NOT SHARE]",
        "do not share",
        "confidential",
        "private data",
    )

    def classify(self, prompt: str) -> PrivacyClassification:
        """Classify a prompt's privacy tier."""
        prompt_lower = prompt.lower().strip()
        reasons: list[str] = []
        pii_detected = False

        # Check explicit sensitive markers
        for marker in self.SENSITIVE_MARKERS:
            if marker.lower() in prompt_lower:
                return PrivacyClassification(
                    tier=PrivacyTier.PRIVATE,
                    confidence=1.0,
                    reasons=[f"Explicit marker: {marker}"],
                    pii_detected=True,
                )

        # Check PII patterns
        for pattern in self.PII_PATTERNS:
            if pattern.search(prompt):
                pii_detected = True
                reasons.append("PII or credential pattern detected")
                break

        # Check medical keywords
        for kw in self.MEDICAL_KEYWORDS:
            if kw in prompt_lower:
                reasons.append(f"Medical/health keyword: {kw}")
                pii_detected = True
                break

        if pii_detected or reasons:
            return PrivacyClassification(
                tier=PrivacyTier.PRIVATE,
                confidence=0.95 if pii_detected else 0.8,
                reasons=reasons if reasons else ["Potential sensitive content"],
                pii_detected=pii_detected,
            )

        return PrivacyClassification(
            tier=PrivacyTier.STANDARD,
            confidence=0.9,
            reasons=["No sensitive patterns detected"],
            pii_detected=False,
        )
