#!/usr/bin/env python3
"""
Autonomous Skill Generator

Automatically generates Claude skills from high-value insights
extracted from YouTube videos.

Generated skills follow the Claude Code skill format:
- SKILL.md with YAML frontmatter
- Optional scripts/ directory for executable components
- Registration in .claude/skills/registry.json

Usage:
    generator = SkillGenerator()
    skill_path = generator.generate(skill_proposal)

Author: Genesis System
Version: 1.0.0
"""

import re
import json
import logging
from datetime import datetime
from pathlib import Path
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, asdict
import sys

sys.path.insert(0, '/mnt/e/genesis-system')

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

GENESIS_ROOT = Path("/mnt/e/genesis-system")
SKILLS_DIR = GENESIS_ROOT / ".claude" / "skills"
REGISTRY_PATH = SKILLS_DIR / "registry.json"


@dataclass
class GeneratedSkill:
    """A generated skill."""
    name: str
    path: Path
    skill_type: str
    source_video_id: str
    created_at: str
    files_created: List[str]


class SkillGenerator:
    """Generates Claude skills from skill proposals."""

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

allowed-tools:
  - Bash
  - Read
  - Write
  - Grep
  - Glob
---

# {title}

## Purpose

{purpose}

## Source

Generated from YouTube video analysis.
- **Video ID**: {video_id}
- **Generated**: {generated_at}
- **Score**: {score}

## When to Use

{when_to_use}

## Usage

{usage}

## Key Concepts

{key_concepts}

## Example

{example}

## References

- Source video: https://youtube.com/watch?v={video_id}
- Generated by: Genesis YouTube Knowledge Pipeline
'''

    def __init__(self, skills_dir: Optional[Path] = None):
        self.skills_dir = skills_dir or SKILLS_DIR
        self.skills_dir.mkdir(parents=True, exist_ok=True)

    def generate(self, proposal: Any) -> Optional[GeneratedSkill]:
        """
        Generate a skill from a proposal.

        Args:
            proposal: SkillProposal from value assessor

        Returns:
            GeneratedSkill with path and metadata
        """
        name = self._sanitize_name(proposal.name)
        skill_dir = self.skills_dir / name

        # Check if already exists
        if skill_dir.exists():
            logger.warning(f"Skill {name} already exists, skipping")
            return None

        try:
            # Create skill directory
            skill_dir.mkdir(parents=True, exist_ok=True)

            # Generate SKILL.md content
            skill_content = self._generate_skill_content(proposal, name)

            # Write SKILL.md
            skill_md = skill_dir / "SKILL.md"
            skill_md.write_text(skill_content)

            files_created = [str(skill_md)]

            # Create scripts directory if needed
            if proposal.skill_type in ['workflow', 'technique']:
                scripts_dir = skill_dir / "scripts"
                scripts_dir.mkdir(exist_ok=True)

                # Generate a placeholder script
                script_path = scripts_dir / "example.py"
                script_content = self._generate_script(proposal, name)
                script_path.write_text(script_content)
                files_created.append(str(script_path))

            # Update registry
            self._update_registry(name, proposal)

            generated = GeneratedSkill(
                name=name,
                path=skill_dir,
                skill_type=proposal.skill_type,
                source_video_id=proposal.source_video_id,
                created_at=datetime.utcnow().isoformat() + "Z",
                files_created=files_created
            )

            logger.info(f"Generated skill: {name}")
            return generated

        except Exception as e:
            logger.error(f"Failed to generate skill {name}: {e}")
            # Cleanup on failure
            if skill_dir.exists():
                import shutil
                shutil.rmtree(skill_dir)
            return None

    def _sanitize_name(self, name: str) -> str:
        """Sanitize skill name for filesystem."""
        # Convert to lowercase, replace spaces with hyphens
        name = name.lower().replace(' ', '-')
        # Remove invalid characters
        name = re.sub(r'[^a-z0-9-]', '', name)
        # Remove multiple hyphens
        name = re.sub(r'-+', '-', name)
        # Ensure it starts with a letter
        if name and not name[0].isalpha():
            name = 'skill-' + name
        # Limit length
        return name[:50] or 'unnamed-skill'

    def _generate_skill_content(self, proposal: Any, name: str) -> str:
        """Generate SKILL.md content."""
        # Generate title
        title = ' '.join(word.capitalize() for word in name.split('-'))

        # Generate purpose from description
        purpose = proposal.description or proposal.source_content[:200]

        # Generate when to use
        when_to_use = self._generate_when_to_use(proposal)

        # Generate usage section
        usage = self._generate_usage(proposal, name)

        # Generate key concepts
        key_concepts = self._generate_key_concepts(proposal)

        # Generate example
        example = self._generate_example(proposal)

        return self.SKILL_TEMPLATE.format(
            name=name,
            description=purpose[:300],
            title=title,
            purpose=purpose,
            video_id=proposal.source_video_id,
            generated_at=datetime.utcnow().strftime("%Y-%m-%d"),
            score=f"{proposal.score:.2f}",
            when_to_use=when_to_use,
            usage=usage,
            key_concepts=key_concepts,
            example=example
        )

    def _generate_when_to_use(self, proposal: Any) -> str:
        """Generate 'when to use' section."""
        triggers = []

        # Based on skill type
        if proposal.skill_type == 'technique':
            triggers.append("- When implementing similar functionality")
            triggers.append("- When following this pattern improves code quality")
        elif proposal.skill_type == 'workflow':
            triggers.append("- When setting up a similar workflow")
            triggers.append("- When automating related tasks")
        elif proposal.skill_type == 'pattern':
            triggers.append("- When this pattern applies to your problem")
            triggers.append("- When you need a proven approach")

        # Based on tags
        for tag in proposal.tags[:3]:
            triggers.append(f"- When working with {tag}")

        return '\n'.join(triggers) or "- When this knowledge is applicable to your task"

    def _generate_usage(self, proposal: Any, name: str) -> str:
        """Generate usage section."""
        usage_lines = []

        usage_lines.append("### Invoke the Skill")
        usage_lines.append("")
        usage_lines.append(f"Reference this skill when working on related tasks.")
        usage_lines.append("")

        if proposal.skill_type in ['workflow', 'technique']:
            usage_lines.append("### Run the Script")
            usage_lines.append("")
            usage_lines.append("```bash")
            usage_lines.append(f"python ~/.claude/skills/{name}/scripts/example.py")
            usage_lines.append("```")

        return '\n'.join(usage_lines)

    def _generate_key_concepts(self, proposal: Any) -> str:
        """Generate key concepts section."""
        concepts = []

        # Extract from source content
        content = proposal.source_content.lower()

        # Look for concept patterns
        concept_patterns = [
            (r'the key (?:is|thing) ([^.!?]+)', 'Key insight'),
            (r'important(?:ly)? ([^.!?]+)', 'Important point'),
            (r'remember (?:that |to )?([^.!?]+)', 'Remember'),
        ]

        for pattern, label in concept_patterns:
            matches = re.findall(pattern, content)
            for match in matches[:1]:
                concepts.append(f"- **{label}**: {match.strip().capitalize()}")

        # Add tags as concepts
        for tag in proposal.tags[:3]:
            concepts.append(f"- **{tag.capitalize()}**: Core technology/concept")

        return '\n'.join(concepts) or "- Core concepts from the source video"

    def _generate_example(self, proposal: Any) -> str:
        """Generate example section."""
        if proposal.skill_type == 'technique':
            return '''```python
# Example implementation based on this technique
# Adapt to your specific use case

def apply_technique():
    """Apply the technique from this skill."""
    # Implementation here
    pass
```'''
        elif proposal.skill_type == 'workflow':
            return '''```yaml
# Example workflow configuration
workflow:
  name: example-workflow
  steps:
    - name: step-1
      action: apply-pattern
    - name: step-2
      action: validate-results
```'''
        else:
            return "See the source video for detailed examples and walkthroughs."

    def _generate_script(self, proposal: Any, name: str) -> str:
        """Generate a placeholder script."""
        skill_type = proposal.skill_type
        video_id = proposal.source_video_id
        return f'''#!/usr/bin/env python3
"""
{name.replace('-', ' ').title()} Script

Auto-generated from YouTube video analysis.
Source: {video_id}

Customize this script for your specific use case.
"""

import sys
sys.path.insert(0, '/mnt/e/genesis-system')


def main():
    """Main entry point."""
    print("Skill: {name}")
    print("Type: {skill_type}")
    print()
    print("This is a placeholder script.")
    print("Implement your custom logic here based on the skill content.")


if __name__ == "__main__":
    main()
'''

    def _update_registry(self, name: str, proposal: Any):
        """Update skills registry."""
        registry = {"skills": [], "version": "1.1.0"}

        if REGISTRY_PATH.exists():
            try:
                with open(REGISTRY_PATH) as f:
                    registry = json.load(f)
            except Exception:
                registry = {"skills": [], "version": "1.1.0"}

        # Ensure skills is a list
        if 'skills' not in registry:
            registry['skills'] = []

        # Convert dict to list if needed (backwards compat)
        if isinstance(registry['skills'], dict):
            registry['skills'] = list(registry['skills'].values())

        # Check if skill already exists
        existing_names = {s.get('name') for s in registry['skills'] if isinstance(s, dict)}
        if name in existing_names:
            logger.info(f"Skill {name} already in registry")
            return

        # Add new skill entry
        new_skill = {
            "name": name,
            "description": proposal.description[:200] if proposal.description else "",
            "category": "youtube_knowledge",
            "triggers": proposal.tags[:5] if proposal.tags else [],
            "source": "youtube_pipeline",
            "source_video": proposal.source_video_id,
            "score": proposal.score
        }

        registry['skills'].append(new_skill)
        registry['updated_at'] = datetime.utcnow().isoformat() + "Z"
        registry['skills_count'] = len(registry['skills'])

        with open(REGISTRY_PATH, 'w') as f:
            json.dump(registry, f, indent=2)

        logger.info(f"Updated registry with skill: {name}")

    def generate_batch(
        self,
        proposals: List[Any],
        max_skills: int = 10
    ) -> List[GeneratedSkill]:
        """Generate multiple skills from proposals."""
        generated = []

        # Sort by score and take top N
        sorted_proposals = sorted(
            proposals,
            key=lambda p: p.score,
            reverse=True
        )[:max_skills]

        for proposal in sorted_proposals:
            skill = self.generate(proposal)
            if skill:
                generated.append(skill)

        logger.info(f"Generated {len(generated)} skills from {len(proposals)} proposals")
        return generated


def main():
    """CLI for skill generation."""
    import argparse
    from core.skills.value_assessor import SkillProposal

    parser = argparse.ArgumentParser(description="Generate skills from proposals")
    parser.add_argument("--demo", action="store_true", help="Generate demo skill")
    parser.add_argument("--name", default="demo-ai-agent-pattern", help="Skill name")

    args = parser.parse_args()

    if args.demo:
        # Create mock proposal
        proposal = SkillProposal(
            name=args.name,
            description="Pattern for building reliable AI agents with proper error handling and structured outputs.",
            source_video_id="demo123",
            source_content="Use structured outputs when building AI agents for better reliability. Always validate inputs and handle errors gracefully. The agent loop pattern is fundamental.",
            score=0.85,
            scores_breakdown={
                'actionability': 0.8,
                'relevance': 0.9,
                'uniqueness': 0.7,
                'specificity': 0.8
            },
            skill_type="technique",
            tags=["ai", "agent", "automation", "llm"]
        )

        generator = SkillGenerator()
        result = generator.generate(proposal)

        if result:
            print(f"\n{'='*60}")
            print(f"Skill Generated Successfully")
            print(f"{'='*60}")
            print(f"Name: {result.name}")
            print(f"Path: {result.path}")
            print(f"Type: {result.skill_type}")
            print(f"Files:")
            for f in result.files_created:
                print(f"  - {f}")
        else:
            print("Skill generation failed or skill already exists")


if __name__ == "__main__":
    main()
