"""
Code Generation Tool for Metis Agent.

This tool specializes in generating high-quality code in various programming languages.
"""
from typing import Any, Dict, List, Optional
import re
from ..core.llm_interface import get_llm
from ..auth.api_key_manager import APIKeyManager
from .base import BaseTool


class CodeGenerationTool(BaseTool):
    """
    Specializes in generating high-quality code in various programming languages.
    Use for any task involving writing code, creating scripts, implementing algorithms,
    or developing software applications.
    """
    
    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the code generation tool.
        
        Args:
            api_key: API key for the LLM (optional)
        """
        # Initialize LLM (uses configured provider - no need for API key here)
        # The LLM is already configured via configure_llm() in the main application
        self.llm = get_llm()
        
        # Define language-specific prompts
        self.language_prompts = {
            "python": "Write clean, efficient, and well-documented Python code with proper error handling.",
            "javascript": "Write clean, efficient JavaScript code following modern ES6+ practices.",
            "typescript": "Write clean TypeScript code with proper type annotations and interfaces.",
            "java": "Write clean, object-oriented Java code following best practices.",
            "c++": "Write efficient C++ code with proper memory management.",
            "go": "Write idiomatic Go code with proper error handling.",
            "rust": "Write safe and efficient Rust code with proper error handling.",
            "html": "Write semantic HTML5 markup with accessibility considerations.",
            "css": "Write clean CSS with a focus on maintainability and responsiveness.",
            "sql": "Write efficient SQL queries with proper indexing considerations.",
            "bash": "Write robust shell scripts with proper error handling and variable quoting.",
            "powershell": "Write clean PowerShell scripts following best practices.",
            "php": "Write secure PHP code following modern practices.",
            "ruby": "Write elegant Ruby code following community conventions.",
            "swift": "Write clean Swift code following Apple's guidelines.",
            "kotlin": "Write concise Kotlin code leveraging language features.",
            "csharp": "Write clean C# code following .NET conventions.",
        }
        
    def can_handle(self, task: str) -> bool:
        """
        Determine if this tool can handle the given task.
        
        Args:
            task: The task to check
            
        Returns:
            True if the tool can handle the task, False otherwise
        """
        task_lower = task.lower()
        words = set(re.findall(r'\b\w+\b', task_lower))
        
        # Check for explicit coding keywords
        coding_keywords = {
            'code', 'program', 'script', 'function', 'class', 'algorithm',
            'implement', 'develop', 'application', 'app', 'software',
            'programming', 'compile', 'debug', 'refactor'
        }
        
        # Check for programming languages
        languages = {
            'python', 'javascript', 'java', 'c++', 'html', 'css', 'typescript',
            'ruby', 'golang', 'rust', 'php', 'swift', 'kotlin', 'c#', 'cpp',
            'nodejs', 'react', 'angular', 'vue', 'django', 'flask', 'express',
            'spring', 'dotnet', 'sql', 'bash', 'powershell', 'csharp'
        }
        
        # Check for technical file extensions
        if any(ext in task_lower for ext in ['.py', '.js', '.html', '.css', '.java', '.cpp', '.ts']):
            return True
            
        # Check for coding keywords
        if any(keyword in words for keyword in coding_keywords):
            return True
            
        # Check for programming languages
        if any(lang in words for lang in languages):
            return True
            
        # Check for coding phrases
        coding_phrases = [
            'write code', 'write a program', 'coding task', 'programming task',
            'develop an application', 'build a software', 'implement an algorithm',
            'create a function', 'code a script', 'programming project'
        ]
        
        if any(phrase in task_lower for phrase in coding_phrases):
            return True
            
        return False
        
    def execute(self, task: str) -> str:
        """
        Generate code based on the task description.
        
        Args:
            task: The code generation task
            
        Returns:
            Generated code with explanations
        """
        # Detect programming language
        language = self._detect_language(task)
        
        # Get language-specific prompt
        language_prompt = self.language_prompts.get(language, "Write clean, well-documented code.")
        
        # Create prompt for code generation
        prompt = [
            {"role": "system", "content": f"""You are an expert software developer specializing in {language} development.
Your task is to generate high-quality, production-ready code based on the user's requirements.

{language_prompt}

Guidelines:
1. Write complete, working code that fulfills all requirements
2. Include clear comments explaining complex logic
3. Follow best practices and design patterns for {language}
4. Consider edge cases and include error handling
5. Optimize for readability and maintainability
6. Include usage examples where appropriate
7. Explain your implementation choices

Format your response as follows:
```{language}
// Your code here
```

Followed by:
## Explanation
Brief explanation of the implementation and any important considerations.

## Usage Example
Show how to use the code with a simple example."""},
            {"role": "user", "content": task}
        ]
        
        # Generate code
        response = self.llm.chat(prompt)
        
        return response
        
    def _detect_language(self, task: str) -> str:
        """
        Detect the programming language from the task description.
        
        Args:
            task: The task description
            
        Returns:
            Detected programming language
        """
        task_lower = task.lower()
        
        # Check for explicit language mentions
        language_keywords = {
            'python': 'python',
            'javascript': 'javascript',
            'js': 'javascript',
            'typescript': 'typescript',
            'ts': 'typescript',
            'java': 'java',
            'c++': 'c++',
            'cpp': 'c++',
            'c#': 'csharp',
            'csharp': 'csharp',
            'go': 'go',
            'golang': 'go',
            'rust': 'rust',
            'html': 'html',
            'css': 'css',
            'sql': 'sql',
            'bash': 'bash',
            'shell': 'bash',
            'powershell': 'powershell',
            'php': 'php',
            'ruby': 'ruby',
            'swift': 'swift',
            'kotlin': 'kotlin',
            'react': 'javascript',
            'angular': 'typescript',
            'vue': 'javascript',
            'node': 'javascript',
            'nodejs': 'javascript',
            'django': 'python',
            'flask': 'python',
            'express': 'javascript',
            'spring': 'java',
            'dotnet': 'csharp'
        }
        
        for keyword, language in language_keywords.items():
            if keyword in task_lower.split():
                return language
                
        # Check for file extensions
        extensions = {
            '.py': 'python',
            '.js': 'javascript',
            '.ts': 'typescript',
            '.java': 'java',
            '.cpp': 'c++',
            '.cs': 'csharp',
            '.go': 'go',
            '.rs': 'rust',
            '.html': 'html',
            '.css': 'css',
            '.sql': 'sql',
            '.sh': 'bash',
            '.ps1': 'powershell',
            '.php': 'php',
            '.rb': 'ruby',
            '.swift': 'swift',
            '.kt': 'kotlin'
        }
        
        for ext, language in extensions.items():
            if ext in task_lower:
                return language
                
        # Default to Python if no language is detected
        return 'python'
        
    def get_examples(self) -> List[str]:
        """
        Get example tasks that this tool can handle.
        
        Returns:
            List of example tasks
        """
        return [
            "Write a Python script for a snake game",
            "Create a React component for a todo app",
            "Implement a binary search algorithm in Java",
            "Develop a Flask web API",
            "Generate a JavaScript function to validate forms",
            "Create a machine learning model using TensorFlow",
            "Build a game using Pygame",
            "Write a script to process CSV files",
            "Implement a REST API endpoint",
            "Create a data visualization with D3.js"
        ]