"""Chat input validation.

``detect_contact_info`` is a best-effort, server-side heuristic used to keep
negotiations on-platform: it flags messages that appear to share personal
contact details before an offer is accepted. It cannot catch every evasion
(deliberate obfuscation will slip through); it is a safety net, not a guarantee.
"""

from __future__ import annotations

import re

# Email, e.g. someone@example.com
_EMAIL_RE = re.compile(r"[\w.+-]+@[\w-]+\.[\w.-]+")

# Obvious URLs / domains, e.g. http://x.y, www.x.y, example.com
_URL_RE = re.compile(
    r"(https?://\S+|www\.\S+|\b[\w-]+\.(?:com|net|org|io|me|in|co|app|gg|xyz|link)\b)",
    re.IGNORECASE,
)

# Standalone @handle (at start or after whitespace), e.g. "@john_doe"
_HANDLE_RE = re.compile(r"(?:^|\s)@\w{2,}")

# Named platforms / contact-intent keywords.
_KEYWORD_RE = re.compile(
    r"\b("
    r"whats\s*app|whatsapp|telegram|insta(?:gram)?|snap\s*chat|snapchat|"
    r"discord|facebook|messenger|signal|viber|wechat|"
    r"phone\s*number|call\s*me|text\s*me|dm\s*me"
    r")\b",
    re.IGNORECASE,
)

# A phone-like run: a digit, then digits/separators, then a digit.
_PHONE_CANDIDATE_RE = re.compile(r"\+?\d[\d\s().\-]{5,}\d")


def _has_phone_number(text: str) -> bool:
    """True if the text contains a run with 7+ digits (phone-like)."""
    for match in _PHONE_CANDIDATE_RE.finditer(text):
        digits = re.sub(r"\D", "", match.group())
        if len(digits) >= 7:
            return True
    return False


def detect_contact_info(text: str) -> bool:
    """Return True if the message appears to contain personal contact info."""
    if not text:
        return False
    return bool(
        _EMAIL_RE.search(text)
        or _URL_RE.search(text)
        or _HANDLE_RE.search(text)
        or _KEYWORD_RE.search(text)
        or _has_phone_number(text)
    )
