"""LLM-based intent classifier implementation."""

import json
from typing import Dict, Any, Optional
from ..models.intent_result import IntentResult


class LLMIntentClassifier:
    """Classify user intent using LLM with structured JSON output."""

    def __init__(self, llm_client: Any, confidence_threshold: float = 0.7, model_name: str = "gpt-4", available_actions: list = None):
        """Initialize classifier.
        
        Args:
            llm_client: LLM client instance
            confidence_threshold: Minimum confidence for classification
            model_name: Model name to use
            available_actions: List of available action_ids
        """
        self.llm = llm_client
        self.confidence_threshold = confidence_threshold
        self.model_name = model_name
        self.available_actions = available_actions or []
        self._system_prompt = self._build_system_prompt()

    def _build_system_prompt(self) -> str:
        """Build system prompt for intent classification."""
        actions_list = "\n".join([f"- {a}" for a in self.available_actions]) if self.available_actions else "- file.move, file.delete, file.copy, file.read, file.write\n- folder.create\n- system.restart\n- monitor.cpu_threshold, monitor.ram_spike, monitor.crash_loop\n- monitor.error_logs, monitor.root_cause, monitor.disk_full\n- monitor.predict_failure\n- autofix.config_mismatch, autofix.rollback_update"
        
        return f"""You are an intent classifier for a system automation tool.

Your task: Analyze the user's request and map it to ONE action from the list below.

Available Actions:
{actions_list}

Response Format (JSON only):
{{
  "action_id": "exact_action_id_from_list",
  "confidence": 0.95,
  "reasoning": "brief explanation"
}}

Action Categories:

1. Application Management:
   - app.install: Install/download an application (e.g., "install chrome", "download spotify")
   - app.uninstall: Remove an application (e.g., "uninstall firefox", "remove vlc")
   - app.update: Update an application (e.g., "update chrome")
   - app.open: Launch/start an application (e.g., "open notepad", "launch chrome")
   - app.force_close: Force close/kill an application (e.g., "kill chrome", "force close excel")
   - app.list: List installed applications (e.g., "show installed apps")
   - app.version: Check application version (e.g., "chrome version")

2. System Control:
   - system.lock: Lock the screen (e.g., "lock screen", "lock my computer")
   - system.sleep: Put system to sleep (e.g., "sleep", "suspend")
   - system.hibernate: Hibernate system (e.g., "hibernate")
   - system.restart: Restart/reboot system (e.g., "restart", "reboot")
   - system.shutdown: Shutdown system (e.g., "shutdown", "power off")
   - system.volume: Control volume (e.g., "mute", "unmute", "set volume to 50")
   - system.info: Get system information (e.g., "system info")
   - system.resources: Check CPU/RAM usage (e.g., "check cpu usage", "show memory")

3. File Operations:
   - file.copy: Copy a file (e.g., "copy file.txt to backup.txt")
   - file.move: Move a file (e.g., "move file.txt to folder/")
   - file.delete: Delete a file (e.g., "delete file.txt")
   - file.read: Read file contents (e.g., "read file.txt")
   - file.write: Write to a file (e.g., "write hello to file.txt")
   - folder.create: Create a folder (e.g., "create folder test")

4. Browser:
   - browser.open: Open URL in browser (e.g., "open youtube", "open google.com")

Rules:
- Use ONLY action_ids from the list above
- Set confidence between 0.0 and 1.0
- If unclear or ambiguous, set confidence below 0.7
- Match the user's intent, not just keywords

Examples:
- "install spotify" → {{"action_id": "app.install", "confidence": 0.95, "reasoning": "User wants to install Spotify application"}}
- "mute my computer" → {{"action_id": "system.volume", "confidence": 0.95, "reasoning": "User wants to mute system volume"}}
- "open chrome" → {{"action_id": "app.open", "confidence": 0.95, "reasoning": "User wants to launch Chrome browser"}}
- "lock screen" → {{"action_id": "system.lock", "confidence": 0.95, "reasoning": "User wants to lock the screen"}}"""

    async def classify(self, user_input: str, context: Optional[Dict[str, Any]] = None) -> IntentResult:
        """Classify user intent.
        
        Args:
            user_input: User's natural language input
            context: Optional context information
            
        Returns:
            IntentResult with action_id and confidence
        """
        messages = [
            {"role": "system", "content": self._system_prompt},
            {"role": "user", "content": user_input}
        ]

        if context:
            messages.append({"role": "system", "content": f"Context: {json.dumps(context)}"})

        try:
            response = await self._call_llm(messages)
            result = self._parse_response(response)
            
            # Check confidence threshold
            if result.confidence < self.confidence_threshold:
                result.needs_clarification = True
            
            return result
            
        except Exception as e:
            return IntentResult(
                action_id="unknown",
                confidence=0.0,
                reasoning=f"Classification error: {str(e)}",
                needs_clarification=True
            )

    async def _call_llm(self, messages: list) -> str:
        """Call LLM and get response.
        
        Args:
            messages: Conversation messages
            
        Returns:
            LLM response text
        """
        try:
            import asyncio
            import litellm
            
            # Set LiteLLM request timeout (increased for local models)
            litellm.request_timeout = 120
            
            # Add timeout to prevent hanging
            response = await asyncio.wait_for(
                asyncio.to_thread(
                    self.llm.chat.completions.create,
                    model=self.model_name,
                    messages=messages
                ),
                timeout=150
            )
            return response.choices[0].message.content
        except asyncio.TimeoutError:
            raise Exception("LLM request timed out after 150 seconds")
        except Exception as e:
            raise

    def _parse_response(self, response: str) -> IntentResult:
        """Parse LLM JSON response.
        
        Args:
            response: JSON string from LLM
            
        Returns:
            IntentResult object
        """
        try:
            # Extract JSON from response (handle markdown code blocks)
            if "```json" in response:
                response = response.split("```json")[1].split("```")[0].strip()
            elif "```" in response:
                response = response.split("```")[1].split("```")[0].strip()
            
            data = json.loads(response)
            return IntentResult(
                action_id=data.get("action_id", "unknown"),
                confidence=float(data.get("confidence", 0.0)),
                reasoning=data.get("reasoning"),
                needs_clarification=False
            )
        except (json.JSONDecodeError, KeyError, ValueError) as e:
            return IntentResult(
                action_id="unknown",
                confidence=0.0,
                reasoning=f"Parse error: {str(e)}",
                needs_clarification=True
            )

    def classify_sync(self, user_input: str, context: Optional[Dict[str, Any]] = None) -> IntentResult:
        """Synchronous version of classify (for testing without async)."""
        user_lower = user_input.lower()
        
        # App install/uninstall patterns - check first
        if ("install" in user_lower or "download" in user_lower) and not ("uninstall" in user_lower):
            return IntentResult(action_id="app.install", confidence=0.95, reasoning="Install application")
        elif "uninstall" in user_lower or "remove" in user_lower:
            return IntentResult(action_id="app.uninstall", confidence=0.95, reasoning="Uninstall application")
        
        # Browser patterns
        if "open" in user_lower and ("youtube" in user_lower or "google" in user_lower or "browser" in user_lower or "http" in user_lower or "www" in user_lower):
            return IntentResult(action_id="browser.open", confidence=0.95, reasoning="Open browser")
        
        # System control patterns
        if ("open" in user_lower or "launch" in user_lower or "start" in user_lower or "run" in user_lower):
            return IntentResult(action_id="app.open", confidence=0.95, reasoning="Open application")
        elif "update" in user_lower and ("app" in user_lower or "application" in user_lower or "program" in user_lower):
            return IntentResult(action_id="app.update", confidence=0.95, reasoning="Update application")
        elif ("list" in user_lower or "show" in user_lower or "check" in user_lower) and ("installed" in user_lower or "apps" in user_lower or "applications" in user_lower or "programs" in user_lower):
            return IntentResult(action_id="app.list", confidence=0.95, reasoning="List installed applications")
        elif ("close" in user_lower or "kill" in user_lower or "terminate" in user_lower) and ("app" in user_lower or "application" in user_lower or "program" in user_lower):
            return IntentResult(action_id="app.force_close", confidence=0.95, reasoning="Force close application")
        elif ("set" in user_lower or "make" in user_lower) and "default" in user_lower:
            return IntentResult(action_id="app.set_default", confidence=0.95, reasoning="Set default application")
        elif "schedule" in user_lower and ("autostart" in user_lower or "auto-start" in user_lower or "startup" in user_lower):
            return IntentResult(action_id="app.schedule_autostart", confidence=0.95, reasoning="Schedule app autostart")
        elif ("enable" in user_lower or "disable" in user_lower) and "startup" in user_lower:
            return IntentResult(action_id="app.startup_toggle", confidence=0.95, reasoning="Toggle app startup")
        elif "version" in user_lower:
            return IntentResult(action_id="app.version", confidence=0.95, reasoning="Get app version")
        elif ("mute" in user_lower or "unmute" in user_lower or "volume" in user_lower):
            return IntentResult(action_id="system.volume", confidence=0.95, reasoning="Control system volume")
        # Monitoring patterns
        elif "monitor" in user_lower and "cpu" in user_lower:
            return IntentResult(action_id="monitor.cpu_threshold", confidence=0.95, reasoning="Monitor CPU threshold")
        elif "monitor" in user_lower and "ram" in user_lower:
            return IntentResult(action_id="monitor.ram_spike", confidence=0.95, reasoning="Monitor RAM spike")
        elif "crash" in user_lower and "loop" in user_lower:
            return IntentResult(action_id="monitor.crash_loop", confidence=0.95, reasoning="Detect crash loop")
        elif "error" in user_lower and "log" in user_lower:
            return IntentResult(action_id="monitor.error_logs", confidence=0.95, reasoning="Analyze error logs")
        elif "root" in user_lower and "cause" in user_lower:
            return IntentResult(action_id="monitor.root_cause", confidence=0.95, reasoning="Identify root cause")
        elif "disk" in user_lower and "full" in user_lower:
            return IntentResult(action_id="monitor.disk_full", confidence=0.95, reasoning="Detect disk full")
        elif "predict" in user_lower and "failure" in user_lower:
            return IntentResult(action_id="monitor.predict_failure", confidence=0.95, reasoning="Predict failure")
        elif "fix" in user_lower and "config" in user_lower:
            return IntentResult(action_id="autofix.config_mismatch", confidence=0.95, reasoning="Auto-fix config")
        elif "rollback" in user_lower:
            return IntentResult(action_id="autofix.rollback_update", confidence=0.95, reasoning="Auto-rollback update")
        elif ("turn" in user_lower or "disable" in user_lower or "enable" in user_lower) and ("internet" in user_lower or "network" in user_lower or "wifi" in user_lower):
            return IntentResult(action_id="system.settings", confidence=0.95, reasoning="Change network settings")
        elif "sleep" in user_lower or "suspend" in user_lower:
            return IntentResult(action_id="system.sleep", confidence=0.95, reasoning="Sleep system")
        elif "hibernate" in user_lower:
            return IntentResult(action_id="system.hibernate", confidence=0.95, reasoning="Hibernate system")
        elif "lock" in user_lower and ("screen" in user_lower or "computer" in user_lower or "pc" in user_lower or "my" in user_lower or "the" in user_lower):
            return IntentResult(action_id="system.lock", confidence=0.95, reasoning="Lock screen")
        elif ("info" in user_lower or "information" in user_lower) and "system" in user_lower:
            return IntentResult(action_id="system.info", confidence=0.95, reasoning="System info")
        elif ("cpu" in user_lower or "ram" in user_lower or "memory" in user_lower or "resources" in user_lower or "usage" in user_lower):
            return IntentResult(action_id="system.resources", confidence=0.95, reasoning="System resources")
        elif "shutdown" in user_lower or "power off" in user_lower:
            return IntentResult(action_id="system.shutdown", confidence=0.95, reasoning="Shutdown system")
        elif "restart" in user_lower or "reboot" in user_lower:
            return IntentResult(action_id="system.restart", confidence=0.95, reasoning="Restart system")
        elif "kill" in user_lower and "process" in user_lower:
            return IntentResult(action_id="process.kill", confidence=0.9, reasoning="Kill process")
        elif "start" in user_lower and "service" in user_lower:
            return IntentResult(action_id="service.start", confidence=0.9, reasoning="Start service")
        elif "stop" in user_lower and "service" in user_lower:
            return IntentResult(action_id="service.stop", confidence=0.9, reasoning="Stop service")
        elif "enable" in user_lower and "service" in user_lower:
            return IntentResult(action_id="service.enable", confidence=0.9, reasoning="Enable service")
        elif "disable" in user_lower and "service" in user_lower:
            return IntentResult(action_id="service.disable", confidence=0.9, reasoning="Disable service")
        elif "update" in user_lower and ("system" in user_lower or "os" in user_lower):
            return IntentResult(action_id="system.update", confidence=0.9, reasoning="Update OS")
        # File operations
        elif ("create" in user_lower or "make" in user_lower or "mkdir" in user_lower) and ("folder" in user_lower or "directory" in user_lower or "dir" in user_lower):
            return IntentResult(action_id="folder.create", confidence=0.95, reasoning="Create folder")
        elif "copy" in user_lower and "file" in user_lower:
            return IntentResult(action_id="file.copy", confidence=0.9, reasoning="Copy file")
        elif "move" in user_lower and "file" in user_lower:
            return IntentResult(action_id="file.move", confidence=0.9, reasoning="Move file")
        elif "delete" in user_lower and ("file" in user_lower or "remove" in user_lower):
            return IntentResult(action_id="file.delete", confidence=0.85, reasoning="Delete file")
        elif ("read" in user_lower or "show" in user_lower or "cat" in user_lower) and "file" in user_lower:
            return IntentResult(action_id="file.read", confidence=0.9, reasoning="Read file")
        elif "write" in user_lower and ("file" in user_lower or "to" in user_lower):
            return IntentResult(action_id="file.write", confidence=0.85, reasoning="Write file")
        else:
            return IntentResult(action_id="unknown", confidence=0.3, reasoning="No clear intent", needs_clarification=True)
