"""LLM-based skill generator."""

import os
import json
from pathlib import Path
from typing import Any

from openai import OpenAI
from dotenv import load_dotenv

from .skill_generator import SkillGenerator


class LlmSkillGenerator(SkillGenerator):
    """
    Generates SKILL.md using an LLM to analyze documentation.
    
    This overrides the regex-based `_analyze_docs` method to use
    semantic understanding for better extraction of:
    - Endpoints and parameters
    - Authentication methods
    - Contextual "when to use"
    - Complete, working code examples
    """
    
    def __init__(self, docs_dir: Path, skill_name: str, output_dir: Path, api_key: str | None = None):
        super().__init__(docs_dir, skill_name, output_dir)
        load_dotenv() # Load from .env if present
        
        self.api_key = api_key or os.environ.get("OPENAI_API_KEY")
        base_url = os.environ.get("OPENAI_BASE_URL")
        
        if not self.api_key:
            raise ValueError("OPENAI_API_KEY is required for LLM generation")
            
        self.client = OpenAI(
            api_key=self.api_key,
            base_url=base_url
        )
        # Use gpt-4o or claude-3-5-sonnet if available via OpenRouter, otherwise standard
        self.model = os.environ.get("OPENAI_MODEL", "gpt-4o") 

    def _analyze_docs(self) -> dict:
        """
        Analyze docs using LLM.
        Returns a dict that matches the structure expected by _generate_* methods,
        or we might override _generate_* methods to use the LLM output directly.
        """
        # 1. Prepare context (read key files)
        context = self._prepare_context()
        
        # 2. Call LLM
        print("🤖 Asking LLM to analyze documentation (this may take a minute)...")
        response = self._call_llm(context)
        
        return response

    def _prepare_context(self) -> str:
        """Read and condense documentation for the prompt."""
        context_parts = []
        
        # Prioritize README, Guide, Getting Started
        priority_files = ["README.md", "_index.md", "getting-started.md", "index.md"]
        
        docs_files = sorted(list(self.docs_dir.rglob("*.md")))
        
        # Move priority files to front
        for p in priority_files:
            for f in docs_files[:]:
                if f.name.lower() == p.lower():
                    docs_files.remove(f)
                    docs_files.insert(0, f)
        
        total_chars = 0
        limit = 100000 # ~25k tokens context limit safe buffer
        
        for f in docs_files:
            if total_chars >= limit:
                break
                
            try:
                content = f.read_text(encoding="utf-8", errors="ignore")
                # Truncate very long files
                if len(content) > 20000:
                    content = content[:20000] + "\n...[truncated]..."
                
                context_parts.append(f"--- FILE: {f.name} ---\n{content}\n")
                total_chars += len(content)
            except Exception as e:
                print(f"Skipping {f.name}: {e}")
                
        return "\n".join(context_parts)

    def _call_llm(self, context: str) -> dict:
        """Call the LLM with the prompt."""
        
        prompt = f"""
You are an expert developer creating a "Skill" for an AI coding assistant. 
A Skill consists of metadata, reference material, and code examples.

Analyze the following documentation for the library/service "{self.skill_name}".

Output a JSON object with this EXACT structure:
{{
  "description": "Short 1-sentence description of what this service does",
  "when_to_use": [
    "Situation 1 where this is useful",
    "Situation 2..."
  ],
  "auth_info": "Description of how to authenticate (or null if none)",
  "endpoints": [
    {{
      "method": "GET/POST",
      "path": "/api/path",
      "summary": "Short summary of what it does"
    }}
  ],
  "examples": [
    {{
      "title": "Example Title",
      "description": "What this example demonstrates",
      "code": "Full python code..."
    }}
  ],
  "search_notes": "Tips for searching this documentation (e.g. key terms)"
}}

IMPORTANT GUIDELINES:
1. **Examples**: Create 3-5 *high-quality, complete, working* Python examples. Include imports, auth setup, and comments. PREFER full flows over snippets.
2. **Endpoints**: List top 10-20 most important API endpoints if applicable.
3. **Context**: In 'when_to_use', be specific about the problem it solves.

DOCUMENTATION CONTEXT:
{context}
        """

        try:
            completion = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {"role": "system", "content": "You are a helpful expert developer tool."},
                    {"role": "user", "content": prompt}
                ],
                response_format={"type": "json_object"},
                temperature=0.2
            )
            
            content = completion.choices[0].message.content
            return json.loads(content)
            
        except Exception as e:
            print(f"LLM Error: {e}")
            # Fallback to empty structure or raise
            raise RuntimeError(f"Failed to generate skill with LLM: {e}")

    def generate(self) -> dict:
        """Main generation flow override."""
        self.output_dir.mkdir(parents=True, exist_ok=True)
        
        info = self._analyze_docs()
        
        # We need to adapt the LLM JSON output to the format expected by our templates
        # or just write the files directly here using the LLM output.
        
        # Let's map it to an ExtractedInfo-like object or just use dictionary
        
        # 1. Generate SKILL.md
        skill_path = self.output_dir / "SKILL.md"
        self._write_skill_md(info, skill_path)
        
        # 2. Generate reference.md
        ref_path = self.output_dir / "reference.md"
        self._write_reference_md(info, ref_path)
        
        # 3. Generate examples.md
        ex_path = self.output_dir / "examples.md"
        self._write_examples_md(info, ex_path)
        
        return {
            "skill_md": str(skill_path),
            "reference_md": str(ref_path),
            "examples_md": str(ex_path),
            "docs_dir": str(self.docs_dir)
        }

    def _write_skill_md(self, info: dict, path: Path):
        """Write SKILL.md."""
        content = f"""---
name: {self.skill_name}
description: {info['description']}
---

# {self.skill_name} Documentation

## When to Use This Skill

Use this skill when you need to:
{chr(10).join(f'- {item}' for item in info['when_to_use'])}

## Quick Reference

### Documentation Paths

- **Full Reference**: [reference.md](file://{self.output_dir / 'reference.md'})
- **Code Examples**: [examples.md](file://{self.output_dir / 'examples.md'})
- **Raw Documentation**: [{self.docs_dir}](file://{self.docs_dir})

"""
        if info.get('auth_info'):
            content += f"""### Authentication

{info['auth_info']}
"""

        if info.get('endpoints'):
            content += """
### Common Endpoints

"""
            for ep in info['endpoints'][:10]: # Top 10
                content += f"- **{ep.get('method', 'GET')}** `{ep.get('path', '')}` - {ep.get('summary', '')}\n"

        content += f"""
## Search Strategy

{info.get('search_notes', 'Use standard search terms.')}
"""
        path.write_text(content, encoding="utf-8")

    def _write_reference_md(self, info: dict, path: Path):
        """Write reference.md."""
        content = f"# {self.skill_name} API Reference\n\n"
        
        content += f"## Description\n{info['description']}\n\n"
        
        if info.get('endpoints'):
            content += "## Endpoints\n\n"
            for ep in info['endpoints']:
                content += f"### {ep.get('method', 'GET')} {ep.get('path')}\n"
                content += f"{ep.get('summary')}\n\n"
        
        path.write_text(content, encoding="utf-8")

    def _write_examples_md(self, info: dict, path: Path):
        """Write examples.md."""
        content = f"""---
title: {self.skill_name} Code Examples
---

# {self.skill_name} Code Examples

"""
        for i, ex in enumerate(info['examples'], 1):
            content += f"## {i}. {ex['title']}\n\n"
            content += f"{ex['description']}\n\n"
            content += f"```python\n{ex['code']}\n```\n\n"
            
        path.write_text(content, encoding="utf-8")
