"""
Parse plain English descriptions into regex patterns
"""

import re
from .patterns import get_pattern, PATTERNS, ALIASES

# Keywords that map to regex components
KEYWORDS = {
    # Quantifiers
    "one or more": "+",
    "zero or more": "*",
    "optional": "?",
    "at least": "{",
    "exactly": "{",
    "between": "{",

    # Character classes
    "letter": "[a-zA-Z]",
    "letters": "[a-zA-Z]+",
    "lowercase": "[a-z]",
    "uppercase": "[A-Z]",
    "digit": r"\d",
    "digits": r"\d+",
    "number": r"\d+",
    "numbers": r"\d+",
    "alphanumeric": "[a-zA-Z0-9]",
    "word": r"\w+",
    "words": r"\w+(?:\s+\w+)*",
    "whitespace": r"\s+",
    "space": r"\s",
    "spaces": r"\s+",
    "any character": ".",
    "anything": ".*",

    # Anchors
    "start": "^",
    "end": "$",
    "beginning": "^",
    "word boundary": r"\b",

    # Common patterns
    "dot": r"\.",
    "comma": ",",
    "dash": "-",
    "hyphen": "-",
    "underscore": "_",
    "at sign": "@",
    "at symbol": "@",
    "hash": "#",
    "dollar": r"\$",
    "percent": "%",
    "slash": "/",
    "backslash": r"\\",
    "colon": ":",
    "semicolon": ";",
    "quote": '"',
    "single quote": "'",
    "parentheses": r"\(.*?\)",
    "brackets": r"\[.*?\]",
    "braces": r"\{.*?\}",
    "newline": r"\n",
    "tab": r"\t",
}


def parse_description(description):
    """
    Parse a plain English description and try to generate a regex.
    Returns dict with pattern, explanation, and confidence.
    """
    description = description.lower().strip()

    # First, check if it matches a known pattern
    for alias, name in ALIASES.items():
        if alias in description:
            pattern_data = PATTERNS.get(name)
            if pattern_data:
                return {
                    "pattern": pattern_data["pattern"],
                    "method": "matched_builtin",
                    "matched": name,
                    "confidence": "high",
                    "explanation": f"Matched built-in pattern: {name}"
                }

    for name in PATTERNS.keys():
        if name.replace("-", " ") in description or name in description:
            pattern_data = PATTERNS[name]
            return {
                "pattern": pattern_data["pattern"],
                "method": "matched_builtin",
                "matched": name,
                "confidence": "high",
                "explanation": f"Matched built-in pattern: {name}"
            }

    # Try to build a custom pattern from keywords
    pattern_parts = []
    explanations = []

    # Check for "starts with" / "ends with"
    if "starts with" in description or "beginning" in description:
        pattern_parts.append("^")
        explanations.append("^ - Start of string")

    if "ends with" in description or "ending" in description:
        # Will add $ at the end
        pass

    # Check for character types
    if "letter" in description and "number" in description:
        pattern_parts.append("[a-zA-Z0-9]+")
        explanations.append("[a-zA-Z0-9]+ - Letters and numbers")
    elif "letter" in description:
        if "only" in description or "just" in description:
            pattern_parts.append("[a-zA-Z]+")
            explanations.append("[a-zA-Z]+ - Only letters")
        else:
            pattern_parts.append("[a-zA-Z]+")
            explanations.append("[a-zA-Z]+ - One or more letters")
    elif "digit" in description or "number" in description:
        if "only" in description or "just" in description:
            pattern_parts.append(r"\d+")
            explanations.append(r"\d+ - Only digits")
        else:
            pattern_parts.append(r"\d+")
            explanations.append(r"\d+ - One or more digits")

    # Check for word patterns
    if "word" in description and not pattern_parts:
        pattern_parts.append(r"\b\w+\b")
        explanations.append(r"\b\w+\b - Whole word")

    # Check for specific characters to match
    for keyword, regex_part in KEYWORDS.items():
        if keyword in description and regex_part not in pattern_parts:
            if keyword in ["start", "beginning", "end"]:
                continue  # Already handled
            if len(regex_part) <= 2:  # Simple characters
                continue  # Skip simple chars unless specifically building

    # Check for "ends with"
    if "ends with" in description or "ending" in description:
        pattern_parts.append("$")
        explanations.append("$ - End of string")

    # Check for specific length requirements
    length_match = re.search(r"(\d+)\s*(?:to|-)\s*(\d+)\s*(?:char|letter|digit)", description)
    if length_match:
        min_len, max_len = length_match.groups()
        if pattern_parts:
            # Modify last pattern to have length
            last = pattern_parts[-1]
            if last.endswith("+"):
                pattern_parts[-1] = last[:-1] + "{" + min_len + "," + max_len + "}"
        explanations.append(f"{{{min_len},{max_len}}} - Between {min_len} and {max_len} characters")

    exact_length = re.search(r"exactly\s*(\d+)\s*(?:char|letter|digit)", description)
    if exact_length:
        length = exact_length.group(1)
        if pattern_parts:
            last = pattern_parts[-1]
            if last.endswith("+"):
                pattern_parts[-1] = last[:-1] + "{" + length + "}"
        explanations.append(f"{{{length}}} - Exactly {length} characters")

    # If we couldn't build anything useful
    if not pattern_parts:
        return {
            "pattern": None,
            "method": "failed",
            "confidence": "none",
            "explanation": "Could not parse description. Try using a built-in pattern name like 'email', 'phone', 'url', etc.",
            "suggestions": list(PATTERNS.keys())[:10]
        }

    pattern = "".join(pattern_parts)

    return {
        "pattern": pattern,
        "method": "custom_built",
        "confidence": "medium",
        "explanation": explanations
    }


def suggest_patterns(description):
    """Suggest relevant built-in patterns based on description"""
    description = description.lower()
    suggestions = []

    for name, data in PATTERNS.items():
        # Check if any words in description match pattern name or description
        if any(word in name or word in data["description"].lower()
               for word in description.split() if len(word) > 2):
            suggestions.append({
                "name": name,
                "description": data["description"],
                "pattern": data["pattern"]
            })

    return suggestions[:5]  # Return top 5 suggestions
