"""Generate SKILL.md from documentation."""

import re
from pathlib import Path
from typing import Optional
from dataclasses import dataclass

from jinja2 import Environment, BaseLoader


@dataclass
class ExtractedInfo:
    """Information extracted from documentation."""
    title: str
    description: str
    auth_info: str
    endpoints: list[dict]
    examples: list[dict]
    sections: list[dict]


SKILL_TEMPLATE = '''---
name: {{ name }}
description: {{ description }}
---

# {{ name }} Documentation

## When to Use This Skill

Use this skill when you need to:
- Work with {{ name }} API integration
- Implement authentication for {{ name }}
- Find API endpoints and their parameters
- Look up code examples for {{ name }}

## Quick Reference

### Documentation Paths

- **Full Reference**: [reference.md](file://{{ reference_path }})
- **Code Examples**: [examples.md](file://{{ examples_path }})
- **Raw Documentation**: [{{ docs_dir }}](file://{{ docs_path }})

{% if auth_info %}
### Authentication

{{ auth_info }}
{% endif %}

{% if top_endpoints %}
### Common Endpoints

{% for ep in top_endpoints %}
- **{{ ep.method }}** `{{ ep.path }}` - {{ ep.summary }}
{% endfor %}
{% endif %}

## Search Strategy

When looking for specific {{ name }} information:

1. **Quick lookup**: Check this overview for common patterns
2. **API details**: Search `reference.md` for endpoint specifications
3. **Working code**: Review `examples.md` for implementation examples
4. **Edge cases**: Grep through `{{ docs_dir }}` for detailed documentation

## Usage Examples

{% for example in examples[:3] %}
### {{ example.title }}

```{{ example.language }}
{{ example.code }}
```
{% endfor %}
'''


class SkillGenerator:
    """Generate skill files from documentation."""
    
    def __init__(
        self,
        docs_dir: Path,
        skill_name: str,
        output_dir: Path,
        max_skill_lines: int = 500
    ):
        self.docs_dir = Path(docs_dir)
        self.skill_name = skill_name
        self.output_dir = Path(output_dir)
        self.max_skill_lines = max_skill_lines
        
        self.env = Environment(loader=BaseLoader())
        self.template = self.env.from_string(SKILL_TEMPLATE)
    
    def generate(self) -> dict:
        """Generate skill files from documentation."""
        self.output_dir.mkdir(parents=True, exist_ok=True)
        
        # Analyze documentation
        info = self._analyze_docs()
        
        # Generate reference.md (full API reference)
        reference_path = self._generate_reference(info)
        
        # Generate examples.md
        examples_path = self._generate_examples(info)
        
        # Generate SKILL.md
        skill_path = self._generate_skill_md(info, reference_path, examples_path)
        
        return {
            "skill_md": str(skill_path),
            "reference_md": str(reference_path),
            "examples_md": str(examples_path),
            "docs_dir": str(self.docs_dir)
        }
    
    def _analyze_docs(self) -> ExtractedInfo:
        """Analyze documentation files and extract key information."""
        all_content = []
        endpoints = []
        examples = []
        auth_info = ""
        
        # Read all markdown files
        for md_file in self.docs_dir.rglob("*.md"):
            try:
                content = md_file.read_text(encoding="utf-8")
                all_content.append({
                    "path": str(md_file),
                    "content": content
                })
                
                # Extract endpoints (common patterns)
                endpoints.extend(self._extract_endpoints(content))
                
                # Extract code examples
                examples.extend(self._extract_examples(content))
                
                # Extract authentication info
                if not auth_info:
                    auth_info = self._extract_auth_info(content)
                    
            except Exception as e:
                print(f"Error reading {md_file}: {e}")
        
        # Deduplicate endpoints
        seen = set()
        unique_endpoints = []
        for ep in endpoints:
            key = f"{ep['method']}:{ep['path']}"
            if key not in seen:
                seen.add(key)
                unique_endpoints.append(ep)
        
        # Build sections list
        sections = self._extract_sections(all_content)
        
        return ExtractedInfo(
            title=self.skill_name,
            description=f"API documentation and reference for {self.skill_name}",
            auth_info=auth_info,
            endpoints=unique_endpoints[:50],  # Limit
            examples=examples[:20],
            sections=sections
        )
    
    def _extract_endpoints(self, content: str) -> list[dict]:
        """Extract API endpoints from content."""
        endpoints = []
        
        # Pattern: GET /api/path or POST /path/to/endpoint
        pattern = r'\b(GET|POST|PUT|PATCH|DELETE)\s+[`"]?(/[\w/\-{}:]+)[`"]?'
        
        for match in re.finditer(pattern, content):
            method = match.group(1)
            path = match.group(2)
            
            # Try to find description nearby
            start = max(0, match.start() - 200)
            end = min(len(content), match.end() + 200)
            context = content[start:end]
            
            # Look for summary in headings
            summary = ""
            heading_match = re.search(r'#+\s*(.+)', context)
            if heading_match:
                summary = heading_match.group(1).strip()
            
            endpoints.append({
                "method": method,
                "path": path,
                "summary": summary[:100] if summary else path
            })
        
        return endpoints
    
    def _extract_examples(self, content: str) -> list[dict]:
        """Extract code examples from content."""
        examples = []
        
        # Find code blocks
        pattern = r'```(\w*)\n([\s\S]*?)```'
        
        for match in re.finditer(pattern, content):
            language = match.group(1) or "text"
            code = match.group(2).strip()
            
            # Skip very short or config-like blocks
            if len(code) < 20:
                continue
            if language in ["yaml", "json", "toml", "ini", "env"]:
                continue
            
            # Try to find title from nearby heading
            start = max(0, match.start() - 300)
            context = content[start:match.start()]
            
            title = "Example"
            heading_match = re.search(r'#+\s*(.+)', context)
            if heading_match:
                title = heading_match.group(1).strip()
            
            examples.append({
                "title": title[:80],
                "language": language,
                "code": code[:500]  # Limit size
            })
        
        return examples
    
    def _extract_auth_info(self, content: str) -> str:
        """Extract authentication information."""
        # Look for auth-related sections
        auth_patterns = [
            r'(?:#+\s*)?(?:Authentication|Authorization|Auth|API Key)[:\s]*\n([\s\S]{50,500}?)(?=\n#|\Z)',
            r'(?:Bearer|API[- ]?key|token|Authorization)[:\s]+[`"]?[\w\-]+[`"]?',
        ]
        
        for pattern in auth_patterns:
            match = re.search(pattern, content, re.IGNORECASE)
            if match:
                text = match.group(0).strip()
                # Clean up
                text = re.sub(r'\n{3,}', '\n\n', text)
                return text[:500]
        
        return ""
    
    def _extract_sections(self, all_content: list[dict]) -> list[dict]:
        """Extract main sections from documentation."""
        sections = []
        
        for doc in all_content:
            content = doc["content"]
            
            # Find h1 and h2 headings
            for match in re.finditer(r'^(#{1,2})\s+(.+)', content, re.MULTILINE):
                level = len(match.group(1))
                title = match.group(2).strip()
                
                sections.append({
                    "level": level,
                    "title": title,
                    "path": doc["path"]
                })
        
        return sections[:100]
    
    def _generate_reference(self, info: ExtractedInfo) -> Path:
        """Generate reference.md with full API documentation."""
        lines = [
            "---",
            f"title: {self.skill_name} API Reference",
            "---",
            "",
            f"# {self.skill_name} API Reference",
            "",
        ]
        
        if info.auth_info:
            lines.extend([
                "## Authentication",
                "",
                info.auth_info,
                "",
            ])
        
        if info.endpoints:
            lines.extend([
                "## Endpoints",
                "",
                "| Method | Path | Description |",
                "|--------|------|-------------|",
            ])
            
            for ep in info.endpoints:
                lines.append(f"| {ep['method']} | `{ep['path']}` | {ep['summary']} |")
            
            lines.append("")
        
        # Add sections index
        if info.sections:
            lines.extend([
                "## Documentation Sections",
                "",
            ])
            
            current_level = 0
            for section in info.sections:
                indent = "  " * (section["level"] - 1)
                lines.append(f"{indent}- {section['title']}")
            
            lines.append("")
        
        reference_path = self.output_dir / "reference.md"
        reference_path.write_text("\n".join(lines), encoding="utf-8")
        return reference_path
    
    def _generate_examples(self, info: ExtractedInfo) -> Path:
        """Generate examples.md with code examples."""
        lines = [
            "---",
            f"title: {self.skill_name} Code Examples",
            "---",
            "",
            f"# {self.skill_name} Code Examples",
            "",
        ]
        
        for i, example in enumerate(info.examples, 1):
            lines.extend([
                f"## {i}. {example['title']}",
                "",
                f"```{example['language']}",
                example['code'],
                "```",
                "",
            ])
        
        if not info.examples:
            lines.extend([
                "*No code examples found in documentation.*",
                "",
                "Check the raw documentation files for examples.",
                "",
            ])
        
        examples_path = self.output_dir / "examples.md"
        examples_path.write_text("\n".join(lines), encoding="utf-8")
        return examples_path
    
    def _generate_skill_md(
        self,
        info: ExtractedInfo,
        reference_path: Path,
        examples_path: Path
    ) -> Path:
        """Generate main SKILL.md file."""
        # Prepare template data
        data = {
            "name": self.skill_name,
            "description": info.description,
            "reference_path": str(reference_path.absolute()),
            "examples_path": str(examples_path.absolute()),
            "docs_dir": self.docs_dir.name,
            "docs_path": str(self.docs_dir.absolute()),
            "auth_info": info.auth_info,
            "top_endpoints": info.endpoints[:10],
            "examples": info.examples[:3],
        }
        
        # Render template
        content = self.template.render(**data)
        
        # Ensure it's not too long
        lines = content.split("\n")
        if len(lines) > self.max_skill_lines:
            lines = lines[:self.max_skill_lines]
            lines.append("\n*... truncated. See reference.md for full documentation.*")
            content = "\n".join(lines)
        
        skill_path = self.output_dir / "SKILL.md"
        skill_path.write_text(content, encoding="utf-8")
        return skill_path
