import re
import logging
from pydantic import BaseModel

logger = logging.getLogger("soagila.airlock.pii")


class PIIDetectionResult(BaseModel):
    pii_found: bool = False
    pii_types: list[str] = []
    pii_count: int = 0
    details: list[dict] = []  # [{type, start, end}] — positions only, not values


# PII detection patterns
PII_PATTERNS = {
    "phone_tr": r'\b0?[5]\d{9}\b',
    "phone_intl": r'\+\d{1,3}[\s-]?\(?\d{1,4}\)?[\s-]?\d{3,4}[\s-]?\d{3,4}',
    "email": r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
    "credit_card": r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b',
    "iban": r'\b[A-Z]{2}\d{2}[\s]?\d{4}[\s]?\d{4}[\s]?\d{4}[\s]?\d{4}[\s]?\d{2,4}\b',
    "tc_kimlik": r'\b\d{11}\b',
    "date": r'\b\d{1,2}[./]\d{1,2}[./]\d{2,4}\b',
    "date_iso": r'\b\d{4}-\d{2}-\d{2}\b',
    "currency_amount": r'\b\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?\s?(?:TL|₺|USD|\$|EUR|€|GBP|£)\b',
    "currency_prefix": r'\b(?:TL|₺|USD|\$|EUR|€|GBP|£)\s?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?\b',
    "person_title": r'\b(?:Bay|Bayan|Mr|Mrs|Ms|Dr|Prof)\s+[A-ZÇĞİÖŞÜ][a-zçğıöşü]+(?:\s+[A-ZÇĞİÖŞÜ][a-zçğıöşü]+)*\b',
    "ssn_us": r'\b\d{3}-\d{2}-\d{4}\b',
    "ip_address": r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b',
}

_compiled = {name: re.compile(pattern, re.IGNORECASE) for name, pattern in PII_PATTERNS.items()}


def detect_pii(text: str) -> PIIDetectionResult:
    """
    Detect PII in text using regex patterns.
    Returns PII types found (not values — we never expose PII).
    """
    result = PIIDetectionResult()
    found_types = set()
    details = []

    for pii_type, pattern in _compiled.items():
        matches = list(pattern.finditer(text))
        if matches:
            found_types.add(pii_type)
            for match in matches:
                details.append({
                    "type": pii_type,
                    "start": match.start(),
                    "end": match.end(),
                })

    result.pii_found = len(found_types) > 0
    result.pii_types = sorted(list(found_types))
    result.pii_count = len(details)
    result.details = details

    if result.pii_found:
        logger.debug(f"PII detected: {result.pii_types} ({result.pii_count} instances)")

    return result


# PII stripping replacements
PII_REPLACEMENTS = {
    "phone_tr": "[PHONE]",
    "phone_intl": "[PHONE]",
    "email": "[EMAIL]",
    "credit_card": "[CARD]",
    "iban": "[IBAN]",
    "tc_kimlik": "[ID_NUMBER]",
    "date": "[DATE]",
    "date_iso": "[DATE]",
    "currency_amount": "[AMOUNT]",
    "currency_prefix": "[AMOUNT]",
    "person_title": "[PERSON]",
    "ssn_us": "[SSN]",
    "ip_address": "[IP]",
}


def strip_pii(text: str) -> str:
    """Remove all detected PII from text, replacing with type tags."""
    result = text
    for pii_type, pattern in _compiled.items():
        replacement = PII_REPLACEMENTS.get(pii_type, "[REDACTED]")
        result = pattern.sub(replacement, result)
    return result
