"""
AbuLang AI-Assisted Parser - Natural language to AbuLang translation
Uses lightweight LLM for understanding ambiguous statements
"""

import re
import json


class AIParser:
    """
    AI-assisted parser for translating natural language to AbuLang
    
    Supports multiple backends:
    - OpenAI API (GPT-3.5/4)
    - Ollama (local models)
    - Anthropic Claude
    - Fallback pattern matching
    """
    
    def __init__(self, backend="pattern", api_key=None, model=None):
        """
        Initialize AI parser
        
        Args:
            backend: "openai", "ollama", "anthropic", or "pattern"
            api_key: API key for cloud services
            model: Model name (e.g., "gpt-3.5-turbo", "llama2")
        """
        self.backend = backend
        self.api_key = api_key
        self.model = model or self._default_model()
        self.client = None
        
        if backend != "pattern":
            self._initialize_client()
    
    def _default_model(self):
        """Get default model for backend"""
        defaults = {
            "openai": "gpt-3.5-turbo",
            "ollama": "llama2",
            "anthropic": "claude-3-haiku-20240307"
        }
        return defaults.get(self.backend, None)
    
    def _initialize_client(self):
        """Initialize API client based on backend"""
        try:
            if self.backend == "openai":
                import openai
                self.client = openai.OpenAI(api_key=self.api_key)
            elif self.backend == "ollama":
                import ollama
                self.client = ollama
            elif self.backend == "anthropic":
                import anthropic
                self.client = anthropic.Anthropic(api_key=self.api_key)
        except ImportError as e:
            print(f"[AI Parser] Warning: {e}")
            print(f"[AI Parser] Falling back to pattern matching")
            self.backend = "pattern"
    
    def _build_prompt(self, natural_text):
        """Build prompt for LLM"""
        return f"""You are an AbuLang code translator. Convert natural language to AbuLang syntax.

AbuLang Commands:
- show/display/print: Display output
- ask/input: Get user input  
- libra: Import library
- if/check: Conditional
- for/loop: For loop
- while/repeat: While loop
- Variable assignment: name = value or name is value

Examples:
"display hello world" → show "hello world"
"get user's name" → name = ask("Enter name")
"if x is bigger than 5" → if x > 5:
"repeat 10 times" → for i in range(10):

Convert this to AbuLang:
{natural_text}

Return ONLY the AbuLang code, no explanations."""
    
    def translate_with_llm(self, natural_text):
        """
        Translate natural language to AbuLang using LLM
        
        Args:
            natural_text: Natural language description
        
        Returns:
            str: AbuLang code
        """
        prompt = self._build_prompt(natural_text)
        
        try:
            if self.backend == "openai":
                response = self.client.chat.completions.create(
                    model=self.model,
                    messages=[{"role": "user", "content": prompt}],
                    temperature=0.3,
                    max_tokens=200
                )
                return response.choices[0].message.content.strip()
            
            elif self.backend == "ollama":
                response = self.client.chat(
                    model=self.model,
                    messages=[{"role": "user", "content": prompt}]
                )
                return response['message']['content'].strip()
            
            elif self.backend == "anthropic":
                response = self.client.messages.create(
                    model=self.model,
                    max_tokens=200,
                    messages=[{"role": "user", "content": prompt}]
                )
                return response.content[0].text.strip()
        
        except Exception as e:
            print(f"[AI Parser] LLM error: {e}")
            return self.translate_with_patterns(natural_text)
    
    def translate_with_patterns(self, natural_text):
        """
        Fallback pattern-based translation
        
        Args:
            natural_text: Natural language description
        
        Returns:
            str: AbuLang code
        """
        text = natural_text.lower().strip()
        
        # Display/output patterns
        if any(word in text for word in ["display", "print", "output", "say", "tell"]):
            # Extract what to display
            for word in ["display", "print", "output", "say", "tell"]:
                if word in text:
                    content = text.split(word, 1)[1].strip()
                    # Remove common words
                    content = content.replace("the message", "").replace("the text", "")
                    content = content.strip()
                    if content:
                        return f'show "{content}"'
        
        # Input patterns
        if any(word in text for word in ["ask", "get", "input", "request", "prompt"]):
            # Extract variable name if present
            var_match = re.search(r"(?:for|get|ask)\s+(?:the\s+)?(\w+)", text)
            if var_match:
                var_name = var_match.group(1)
                return f'{var_name} = ask("Enter {var_name}")'
            return 'user_input = ask("Enter value")'
        
        # Loop patterns
        if "repeat" in text or "loop" in text:
            # Extract number
            num_match = re.search(r"(\d+)\s+times", text)
            if num_match:
                count = num_match.group(1)
                return f"for i in range({count}):"
            return "for i in range(10):"
        
        # Conditional patterns
        if text.startswith("if ") or text.startswith("check if"):
            condition = text.replace("check if", "").replace("if", "").strip()
            # Convert natural comparisons
            condition = condition.replace("is greater than", ">")
            condition = condition.replace("is less than", "<")
            condition = condition.replace("equals", "==")
            condition = condition.replace("is equal to", "==")
            return f"if {condition}:"
        
        # Variable assignment
        if " is " in text or " equals " in text:
            parts = re.split(r"\s+(?:is|equals)\s+", text, 1)
            if len(parts) == 2:
                var, value = parts
                var = var.strip().replace(" ", "_")
                value = value.strip()
                # Try to parse value as number
                try:
                    float(value)
                    return f"{var} = {value}"
                except:
                    return f'{var} = "{value}"'
        
        # Import patterns
        if "import" in text or "use" in text:
            lib_match = re.search(r"(?:import|use)\s+(\w+)", text)
            if lib_match:
                lib = lib_match.group(1)
                return f"libra {lib}"
        
        # If no pattern matches, return as comment
        return f"# {natural_text}"
    
    def parse(self, natural_text):
        """
        Main parsing method - tries LLM first, falls back to patterns
        
        Args:
            natural_text: Natural language description
        
        Returns:
            str: AbuLang code
        """
        if self.backend == "pattern":
            return self.translate_with_patterns(natural_text)
        else:
            return self.translate_with_llm(natural_text)
    
    def is_natural_language(self, text):
        """
        Detect if text is natural language vs AbuLang code
        
        Returns:
            bool: True if likely natural language
        """
        text = text.strip().lower()
        
        # Check for natural language indicators
        natural_indicators = [
            text.startswith("please"),
            text.startswith("can you"),
            text.startswith("i want to"),
            text.startswith("i need to"),
            " the " in text,
            " a " in text,
            text.endswith("?"),
        ]
        
        # Check for code indicators
        code_indicators = [
            text.startswith("show "),
            text.startswith("ask "),
            text.startswith("libra "),
            text.startswith("if "),
            text.startswith("for "),
            text.startswith("while "),
            "=" in text and not " is " in text,
        ]
        
        natural_score = sum(natural_indicators)
        code_score = sum(code_indicators)
        
        return natural_score > code_score
