"""
Built-in regex patterns for common use cases
"""

import re

# Pattern database with regex, description, and explanation
PATTERNS = {
    "email": {
        "pattern": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
        "description": "Match email addresses",
        "explanation": [
            "[a-zA-Z0-9._%+-]+ - Username (letters, numbers, dots, underscores, etc.)",
            "@ - The @ symbol",
            "[a-zA-Z0-9.-]+ - Domain name",
            "\\. - A literal dot",
            "[a-zA-Z]{2,} - Top-level domain (com, org, etc.)"
        ],
        "examples": ["user@example.com", "test.email+tag@domain.co.uk"]
    },
    "phone": {
        "pattern": r"(\+?1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}",
        "description": "Match US phone numbers",
        "explanation": [
            "(\\+?1[-.\\s]?)? - Optional country code (+1)",
            "(\\(?\\d{3}\\)?[-.\\s]?)? - Optional area code with optional parentheses",
            "\\d{3} - First three digits",
            "[-.\\s]? - Optional separator",
            "\\d{4} - Last four digits"
        ],
        "examples": ["555-123-4567", "(555) 123-4567", "+1 555 123 4567"]
    },
    "url": {
        "pattern": r"https?://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)",
        "description": "Match URLs (http and https)",
        "explanation": [
            "https? - http or https",
            "(?:www\\.)? - Optional www.",
            "[-a-zA-Z0-9@:%._\\+~#=]{1,256} - Domain name",
            "\\.[a-zA-Z0-9()]{1,6} - TLD (.com, .org, etc.)",
            "(?:[-a-zA-Z0-9()@:%_\\+.~#?&//=]*) - Optional path and query"
        ],
        "examples": ["https://example.com", "http://www.test.org/path?q=1"]
    },
    "ipv4": {
        "pattern": r"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",
        "description": "Match IPv4 addresses",
        "explanation": [
            "\\b - Word boundary",
            "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) - Number 0-255",
            "\\. - Literal dot",
            "{3} - Repeat 3 times (first 3 octets)",
            "Final octet (same pattern)"
        ],
        "examples": ["192.168.1.1", "10.0.0.255", "172.16.0.1"]
    },
    "ipv6": {
        "pattern": r"(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}",
        "description": "Match IPv6 addresses (full form)",
        "explanation": [
            "[0-9a-fA-F]{1,4} - 1-4 hex digits",
            ": - Colon separator",
            "{7} - Repeat 7 times",
            "Final group of hex digits"
        ],
        "examples": ["2001:0db8:85a3:0000:0000:8a2e:0370:7334"]
    },
    "date-mdy": {
        "pattern": r"(0?[1-9]|1[0-2])[/\-](0?[1-9]|[12][0-9]|3[01])[/\-](\d{2}|\d{4})",
        "description": "Match dates (MM/DD/YYYY or MM-DD-YY)",
        "explanation": [
            "(0?[1-9]|1[0-2]) - Month (1-12, optional leading zero)",
            "[/\\-] - Slash or dash separator",
            "(0?[1-9]|[12][0-9]|3[01]) - Day (1-31)",
            "(\\d{2}|\\d{4}) - Year (2 or 4 digits)"
        ],
        "examples": ["12/25/2023", "1-5-99", "01/01/2000"]
    },
    "date-ymd": {
        "pattern": r"(\d{4})[/\-](0?[1-9]|1[0-2])[/\-](0?[1-9]|[12][0-9]|3[01])",
        "description": "Match dates (YYYY-MM-DD)",
        "explanation": [
            "\\d{4} - Four digit year",
            "[/\\-] - Slash or dash separator",
            "(0?[1-9]|1[0-2]) - Month (1-12)",
            "(0?[1-9]|[12][0-9]|3[01]) - Day (1-31)"
        ],
        "examples": ["2023-12-25", "2000/01/01"]
    },
    "time": {
        "pattern": r"(0?[1-9]|1[0-2]):[0-5][0-9]\s?(AM|PM|am|pm)|((?:[01]?[0-9]|2[0-3]):[0-5][0-9])",
        "description": "Match time (12-hour or 24-hour format)",
        "explanation": [
            "(0?[1-9]|1[0-2]) - Hour (1-12 for 12-hour)",
            ":[0-5][0-9] - Minutes",
            "\\s?(AM|PM|am|pm) - Optional space + AM/PM",
            "| - OR",
            "(?:[01]?[0-9]|2[0-3]):[0-5][0-9] - 24-hour format"
        ],
        "examples": ["3:30 PM", "11:59pm", "14:30", "09:00"]
    },
    "credit-card": {
        "pattern": r"\b(?:\d[ -]*?){13,16}\b",
        "description": "Match credit card numbers (13-16 digits)",
        "explanation": [
            "\\b - Word boundary",
            "\\d - A digit",
            "[ -]*? - Optional spaces or dashes",
            "{13,16} - 13 to 16 digits total"
        ],
        "examples": ["4111111111111111", "4111-1111-1111-1111", "4111 1111 1111 1111"]
    },
    "ssn": {
        "pattern": r"\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b",
        "description": "Match US Social Security Numbers",
        "explanation": [
            "\\d{3} - First 3 digits",
            "[-\\s]? - Optional dash or space",
            "\\d{2} - Middle 2 digits",
            "[-\\s]? - Optional dash or space",
            "\\d{4} - Last 4 digits"
        ],
        "examples": ["123-45-6789", "123 45 6789", "123456789"]
    },
    "zip": {
        "pattern": r"\b\d{5}(?:-\d{4})?\b",
        "description": "Match US ZIP codes (5 or 9 digit)",
        "explanation": [
            "\\d{5} - Five digits",
            "(?:-\\d{4})? - Optional dash and 4 more digits"
        ],
        "examples": ["12345", "12345-6789"]
    },
    "hex-color": {
        "pattern": r"#(?:[0-9a-fA-F]{3}){1,2}\b",
        "description": "Match hex color codes",
        "explanation": [
            "# - Hash symbol",
            "[0-9a-fA-F]{3} - 3 hex digits",
            "{1,2} - Once (3-digit) or twice (6-digit)"
        ],
        "examples": ["#fff", "#FF5733", "#000000"]
    },
    "username": {
        "pattern": r"^[a-zA-Z][a-zA-Z0-9_]{2,29}$",
        "description": "Match usernames (3-30 chars, starts with letter)",
        "explanation": [
            "^ - Start of string",
            "[a-zA-Z] - Must start with a letter",
            "[a-zA-Z0-9_]{2,29} - 2-29 more letters, numbers, or underscores",
            "$ - End of string"
        ],
        "examples": ["john_doe", "User123", "admin"]
    },
    "password-strong": {
        "pattern": r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$",
        "description": "Match strong passwords (8+ chars, upper, lower, number, special)",
        "explanation": [
            "(?=.*[a-z]) - At least one lowercase",
            "(?=.*[A-Z]) - At least one uppercase",
            "(?=.*\\d) - At least one digit",
            "(?=.*[@$!%*?&]) - At least one special char",
            "{8,} - Minimum 8 characters"
        ],
        "examples": ["Passw0rd!", "Str0ng@Pass"]
    },
    "slug": {
        "pattern": r"^[a-z0-9]+(?:-[a-z0-9]+)*$",
        "description": "Match URL slugs (lowercase, hyphens)",
        "explanation": [
            "^[a-z0-9]+ - Start with lowercase letters/numbers",
            "(?:-[a-z0-9]+)* - Optionally followed by hyphen + more chars",
            "$ - End of string"
        ],
        "examples": ["my-blog-post", "article123", "hello-world-2023"]
    },
    "hashtag": {
        "pattern": r"#[a-zA-Z][a-zA-Z0-9_]*",
        "description": "Match hashtags",
        "explanation": [
            "# - Hash symbol",
            "[a-zA-Z] - Starts with a letter",
            "[a-zA-Z0-9_]* - Followed by letters, numbers, underscores"
        ],
        "examples": ["#Python", "#coding101", "#hello_world"]
    },
    "mention": {
        "pattern": r"@[a-zA-Z][a-zA-Z0-9_]*",
        "description": "Match @mentions",
        "explanation": [
            "@ - At symbol",
            "[a-zA-Z] - Starts with a letter",
            "[a-zA-Z0-9_]* - Followed by letters, numbers, underscores"
        ],
        "examples": ["@username", "@John_Doe", "@user123"]
    },
    "word": {
        "pattern": r"\b\w+\b",
        "description": "Match whole words",
        "explanation": [
            "\\b - Word boundary",
            "\\w+ - One or more word characters",
            "\\b - Word boundary"
        ],
        "examples": ["hello", "world", "test123"]
    },
    "number": {
        "pattern": r"-?\d+\.?\d*",
        "description": "Match numbers (integers and decimals)",
        "explanation": [
            "-? - Optional negative sign",
            "\\d+ - One or more digits",
            "\\.? - Optional decimal point",
            "\\d* - Zero or more digits after decimal"
        ],
        "examples": ["42", "-3.14", "0.5", "1000"]
    },
    "whitespace": {
        "pattern": r"\s+",
        "description": "Match whitespace (spaces, tabs, newlines)",
        "explanation": [
            "\\s+ - One or more whitespace characters"
        ],
        "examples": ["   ", "\\t", "\\n"]
    },
    "html-tag": {
        "pattern": r"<[^>]+>",
        "description": "Match HTML tags",
        "explanation": [
            "< - Opening bracket",
            "[^>]+ - One or more chars that aren't >",
            "> - Closing bracket"
        ],
        "examples": ["<div>", "<p class='test'>", "</span>"]
    },
    "markdown-link": {
        "pattern": r"\[([^\]]+)\]\(([^)]+)\)",
        "description": "Match Markdown links",
        "explanation": [
            "\\[ - Opening bracket",
            "([^\\]]+) - Link text (captured)",
            "\\] - Closing bracket",
            "\\( - Opening parenthesis",
            "([^)]+) - URL (captured)",
            "\\) - Closing parenthesis"
        ],
        "examples": ["[Google](https://google.com)", "[click here](http://example.com)"]
    },
    "file-extension": {
        "pattern": r"\.[a-zA-Z0-9]{1,10}$",
        "description": "Match file extensions",
        "explanation": [
            "\\. - Literal dot",
            "[a-zA-Z0-9]{1,10} - 1-10 alphanumeric chars",
            "$ - End of string"
        ],
        "examples": [".txt", ".py", ".json", ".html"]
    },
    "uuid": {
        "pattern": r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
        "description": "Match UUIDs",
        "explanation": [
            "[0-9a-fA-F]{8} - 8 hex digits",
            "- - Dash separator",
            "[0-9a-fA-F]{4} - 4 hex digits (x3)",
            "[0-9a-fA-F]{12} - 12 hex digits"
        ],
        "examples": ["550e8400-e29b-41d4-a716-446655440000"]
    },
}

# Aliases for common search terms
ALIASES = {
    "emails": "email",
    "mail": "email",
    "e-mail": "email",
    "phones": "phone",
    "telephone": "phone",
    "tel": "phone",
    "urls": "url",
    "link": "url",
    "links": "url",
    "website": "url",
    "ip": "ipv4",
    "ip-address": "ipv4",
    "ipaddress": "ipv4",
    "date": "date-mdy",
    "dates": "date-mdy",
    "iso-date": "date-ymd",
    "times": "time",
    "credit": "credit-card",
    "card": "credit-card",
    "cc": "credit-card",
    "social": "ssn",
    "zipcode": "zip",
    "postal": "zip",
    "color": "hex-color",
    "colour": "hex-color",
    "colors": "hex-color",
    "user": "username",
    "users": "username",
    "pass": "password-strong",
    "password": "password-strong",
    "passwords": "password-strong",
    "tag": "hashtag",
    "tags": "hashtag",
    "words": "word",
    "numbers": "number",
    "integer": "number",
    "float": "number",
    "decimal": "number",
    "spaces": "whitespace",
    "html": "html-tag",
    "markdown": "markdown-link",
    "md-link": "markdown-link",
    "extension": "file-extension",
    "ext": "file-extension",
    "guid": "uuid",
}


def get_pattern(name):
    """Get a pattern by name or alias"""
    name = name.lower().strip()

    # Check aliases first
    if name in ALIASES:
        name = ALIASES[name]

    if name in PATTERNS:
        return PATTERNS[name]

    return None


def list_patterns():
    """List all available patterns"""
    return {name: p["description"] for name, p in PATTERNS.items()}


def test_pattern(pattern, text):
    """Test a regex pattern against text, return all matches"""
    try:
        matches = re.findall(pattern, text)
        return {
            "success": True,
            "matches": matches,
            "count": len(matches)
        }
    except re.error as e:
        return {
            "success": False,
            "error": str(e),
            "matches": [],
            "count": 0
        }


def explain_pattern(name):
    """Get explanation for a pattern"""
    pattern_data = get_pattern(name)
    if pattern_data:
        return {
            "pattern": pattern_data["pattern"],
            "description": pattern_data["description"],
            "explanation": pattern_data["explanation"],
            "examples": pattern_data["examples"]
        }
    return None
