"""
Financial PII detection patterns.

Regex patterns for detecting sensitive financial information in logs and text.
"""

import re

# Social Security Number (SSN)
SSN_PATTERN = re.compile(
    r"\b\d{3}-\d{2}-\d{4}\b",  # With dashes: 123-45-6789
    re.IGNORECASE,
)

SSN_NO_DASH = re.compile(
    r"\b\d{9}\b",  # Without dashes: 123456789 (needs context)
    re.IGNORECASE,
)

# Bank Account Number (8-17 digits)
ACCOUNT_PATTERN = re.compile(r"\b\d{8,17}\b", re.IGNORECASE)

# ABA Routing Number (9 digits)
ROUTING_PATTERN = re.compile(
    r"\b\d{9}\b",  # Same as SSN_NO_DASH (needs context)
    re.IGNORECASE,
)

# Credit Card (major card networks)
CARD_PATTERN = re.compile(
    r"\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4,7}\b",  # 13-19 digits
    re.IGNORECASE,
)

# CVV (3-4 digits, context-dependent)
CVV_PATTERN = re.compile(r"\b\d{3,4}\b", re.IGNORECASE)

# Tax ID / Employer Identification Number (EIN)
EIN_PATTERN = re.compile(
    r"\b\d{2}-\d{7}\b",  # 12-3456789
    re.IGNORECASE,
)

# Email addresses (not PII but often sensitive)
EMAIL_PATTERN = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", re.IGNORECASE)

# Phone numbers (US format)
PHONE_PATTERN = re.compile(
    r"\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b", re.IGNORECASE
)

# Driver's License (state-specific patterns - simplified)
DL_PATTERN = re.compile(
    r"\b[A-Z]{1,2}\d{6,8}\b",  # Simplified (CA: A1234567, TX: 12345678)
    re.IGNORECASE,
)


def luhn_checksum(card_number: str) -> bool:
    """
    Validate credit card number using Luhn algorithm.

    Args:
        card_number: Credit card number (digits only)

    Returns:
        True if valid, False otherwise
    """

    def digits_of(n: int | str) -> list[int]:
        return [int(d) for d in str(n)]

    digits = digits_of(card_number)
    odd_digits = digits[-1::-2]
    even_digits = digits[-2::-2]
    checksum = sum(odd_digits)
    for d in even_digits:
        checksum += sum(digits_of(d * 2))
    return checksum % 10 == 0


def is_valid_routing_number(routing: str) -> bool:
    """
    Validate ABA routing number using checksum algorithm.

    Args:
        routing: 9-digit routing number

    Returns:
        True if valid, False otherwise
    """
    if len(routing) != 9 or not routing.isdigit():
        return False

    # ABA checksum algorithm
    # 3*(d1+d4+d7) + 7*(d2+d5+d8) + 1*(d3+d6+d9) mod 10 = 0
    digits = [int(d) for d in routing]
    checksum = (
        3 * (digits[0] + digits[3] + digits[6])
        + 7 * (digits[1] + digits[4] + digits[7])
        + 1 * (digits[2] + digits[5] + digits[8])
    )
    return checksum % 10 == 0


# Context keywords that indicate nearby number is PII
SSN_CONTEXT = ["ssn", "social security", "social-security", "tax id", "taxpayer"]
ACCOUNT_CONTEXT = ["account", "acct", "account_number", "account-number"]
ROUTING_CONTEXT = ["routing", "routing_number", "routing-number", "aba"]
CARD_CONTEXT = ["card", "credit card", "debit card", "pan", "card_number"]
CVV_CONTEXT = ["cvv", "cvc", "security code", "card code"]
