"""
SMS keyword detection and phone normalization utilities.

Used by the SMS connector webhook handlers to detect opt-out commands,
affirmative responses, and call-back requests from inbound SMS replies.
"""

import re
import logging

logger = logging.getLogger(__name__)

# ---------------------------------------------------------------------------
# Keyword definitions
# ---------------------------------------------------------------------------
# Order matters: check compound keywords before single-word ones.

KEYWORD_PATTERNS = {
    # Compound keywords (must be checked before single-word matches)
    'CALL_ME': [r'(?i)\bcall\s*me\b'],
    # Single-word keywords
    'STOP': [r'(?i)\b(?:stop|unsubscribe|opt[- ]?out|cancel)\b'],
    'YES': [r'(?i)\b(?:yes|yeah|sure|ok|okay|yep)\b'],
}

# All recognized keywords
KNOWN_KEYWORDS = {'STOP', 'YES', 'CALL_ME'}

# ---------------------------------------------------------------------------
# Keyword detection
# ---------------------------------------------------------------------------

def detect_keyword(body: str) -> str:
    """
    Detect SMS keywords in message body.

    Returns keyword string (e.g., 'STOP', 'YES', 'CALL_ME') or '' if none found.

    Priority order: STOP > CALL_ME > YES
    (Opt-out always takes precedence over other actions)
    """
    if not body or not isinstance(body, str):
        return ''

    body_stripped = body.strip()
    if not body_stripped:
        return ''

    # Check STOP first (highest priority — TCPA compliance)
    if _match_keyword(body_stripped, 'STOP'):
        return 'STOP'

    # Check CALL_ME next
    if _match_keyword(body_stripped, 'CALL_ME'):
        return 'CALL_ME'

    # Check YES last
    if _match_keyword(body_stripped, 'YES'):
        return 'YES'

    return ''


def _match_keyword(text: str, keyword: str) -> bool:
    """Check if text matches any pattern for the given keyword."""
    patterns = KEYWORD_PATTERNS.get(keyword, [])
    for pattern in patterns:
        if re.search(pattern, text):
            return True
    return False


# ---------------------------------------------------------------------------
# Phone normalization
# ---------------------------------------------------------------------------

def normalize_phone(phone: str) -> str:
    """
    Normalize phone number to E.164 format (country code + digits).

    Handles:
    - (555) 123-4567
    - 555-123-4567
    - 555.123.4567
    - 5551234567
    - +15551234567
    - 1-555-123-4567

    Returns: normalized phone string (e.g., '+15551234567')
    """
    if not phone:
        return ''

    # Strip all non-digit characters except leading +
    digits = re.sub(r'[^\d]', '', phone)

    # Handle leading country code
    if digits.startswith('1') and len(digits) == 11:
        return f'+{digits}'
    elif len(digits) == 10:
        return f'+1{digits}'
    elif len(digits) == 11 and not digits.startswith('1'):
        return f'+{digits}'
    elif len(digits) > 11:
        # Keep as-is if already E.164-ish
        return f'+{digits}' if not phone.startswith('+') else phone

    # Fallback: return stripped digits
    return digits


def phones_match(phone1: str, phone2: str) -> bool:
    """Compare two phone numbers after normalization."""
    return normalize_phone(phone1) == normalize_phone(phone2)
