"""
Brynq Intent Classifier — Natural language to command routing.

Instead of /commands, users just type naturally:
  "create a room called Our App"  →  /room create Our App
  "join BRYNQ-7X3K"               →  /room join BRYNQ-7X3K
  "show me the files"             →  /project files
  "what models do I have?"        →  /models

Slash commands still work as power-user shortcuts.
"""

import re
from typing import Optional, Tuple

# Pattern: (regex, slash_command_template)
# Template uses {0}, {1}, etc. for captured groups
_PATTERNS = [
    # Room commands
    (r"(?:create|start|make|open)\s+(?:a\s+)?room\s+(?:called\s+)?(.+)", "/room create {0}"),
    (r"(?:join|connect(?:\s+to)?)\s+(BRYNQ-\w+)", "/room join {0}"),
    (r"(?:join|connect(?:\s+to)?)\s+room\s+(BRYNQ-\w+)", "/room join {0}"),
    (r"(?:leave|exit|disconnect(?:\s+from)?)\s+(?:the\s+)?room", "/room leave"),
    (r"(?:close|end|destroy|delete)\s+(?:the\s+)?room", "/room close"),
    (r"(?:room|who(?:'s| is))\s+(?:status|info|members|here|online)", "/room status"),

    # Project commands
    (r"(?:create|start|init|new)\s+(?:a\s+)?project\s+(?:called\s+)?(.+)", "/project create {0}"),
    (r"(?:show|list|what are)\s+(?:me\s+)?(?:the\s+)?files?", "/project files"),
    (r"(?:save|write|store)\s+(?:this\s+)?(?:as\s+|to\s+)?(\S+\.?\w+)", "/project save {0}"),
    (r"(?:open|read|show|view|cat)\s+(?:the\s+)?(?:file\s+)?(\S+\.\w+)", "/project open {0}"),
    (r"(?:project\s+)?(?:history|changes|log|changelog)", "/project history"),
    (r"(?:delete|remove)\s+(?:the\s+)?project", "/project delete"),

    # Model commands
    (r"(?:what|which|show|list)\s+(?:models?|ais?)\s+(?:do\s+I\s+have|are\s+available|installed|active)", "/models"),
    (r"(?:show|list)\s+(?:me\s+)?(?:my\s+)?models?", "/models"),
    (r"(?:add|use|enable|connect)\s+(\w+)\s+(?:model|ai)?", "/add {0}"),
    (r"(?:remove|disable|disconnect)\s+(\w+)\s+(?:model|ai)?", "/remove {0}"),

    # Identity / Auth commands
    (r"(?:create|make|sign\s*up\s+for)\s+(?:an?\s+)?account", "/signup"),
    (r"^(?:sign\s*up|register)$", "/signup"),
    (r"^(?:log\s*in|sign\s*in)$", "/login"),
    (r"^(?:log\s*out|sign\s*out)$", "/logout"),
    (r"^(?:who\s*am\s*i|my\s+(?:account|profile|identity))$", "/whoami"),

    # System commands
    (r"^(?:help|commands|what can (?:you|i) do|how (?:do(?:es)?\s+)?(?:this|brynq)\s+work)\??$", "/help"),
    (r"(?:status|health|how(?:'s| is)\s+(?:everything|the system|brynq))", "/status"),
    (r"^(?:quit|exit|bye|goodbye|close brynq)$", "/quit"),
    (r"^(?:clear|reset|start over|new chat)$", "/clear"),

    # Search
    (r"(?:search|find|look for|where did (?:we|i))\s+(?:for\s+)?[\"']?(.+?)[\"']?\s*$", "/search {0}"),

    # Skills
    (r"(?:show|list|what are)\s+(?:my\s+)?(?:learned\s+)?skills?", "/skills"),

    # Chat commands (in room) — "say X" or "send X" but NOT "tell me about"
    (r"^(?:say|send|message)\s+(.+)", "/chat {0}"),
    (r"^tell\s+(?!me\b)(\S+)\s+(.+)", "/chat {1}"),

    # Gateway
    (r"(?:connect|link|bridge)\s+(?:to\s+)?(telegram|discord|slack)", "/gateway connect {0}"),
    (r"(?:disconnect|unlink)\s+(?:from\s+)?(telegram|discord|slack)", "/gateway disconnect {0}"),

    # Chain strategies (explicit)
    (r"(?:debate|argue)\s+(?:about\s+)?(.+)", "/chain debate {0}"),
    (r"(?:compare|vs)\s+(.+)", "/chain debate {0}"),
    (r"(?:refine|improve|polish)\s+(.+)", "/chain refine {0}"),
    (r"(?:research|fan.?out|investigate)\s+(.+)", "/chain fan_out {0}"),
]

# Compile patterns once
_COMPILED = [(re.compile(p, re.IGNORECASE), template) for p, template in _PATTERNS]


def classify_intent(user_input: str) -> Tuple[Optional[str], str]:
    """Classify natural language input as a command or chat message.

    Args:
        user_input: Raw text from the user.

    Returns:
        (command, original_input) where command is:
        - A slash command string if intent was detected (e.g., "/room create Our App")
        - None if this is a regular chat message (pass to AI)

    Slash commands (starting with /) are returned as-is without classification.
    """
    text = user_input.strip()

    if not text:
        return None, text

    # Slash commands pass through directly
    if text.startswith("/"):
        return text, text

    # Try each pattern
    for pattern, template in _COMPILED:
        match = pattern.search(text)
        if match:
            groups = match.groups()
            command = template
            for i, group in enumerate(groups):
                command = command.replace(f"{{{i}}}", group.strip())
            return command, text

    # No intent matched — it's a chat message for the AI
    return None, text


def is_command_like(text: str) -> bool:
    """Quick check: does this look like it could be a command?

    Used to decide whether to show "Did you mean /command?" suggestions
    when the intent classifier isn't confident.
    """
    command_words = {
        "create", "join", "leave", "close", "status",
        "files", "save", "open", "history", "delete",
        "models", "help", "quit", "clear", "search",
        "skills", "connect", "disconnect",
        "room", "project", "gateway",
    }
    words = set(text.lower().split())
    return len(words & command_words) >= 1
