#!/usr/bin/env python3
"""
Pattern Implementation Generator
Generates implementation code from analyzed patterns
"""

import sys
import json
import os
from datetime import datetime

class PatternGenerator:
    def __init__(self, pattern_file, framework='tailwind'):
        self.pattern_file = pattern_file
        self.framework = framework
        self.patterns = None

    def load_patterns(self):
        """Load pattern JSON file"""
        print(f"📖 Loading patterns from: {self.pattern_file}")

        try:
            with open(self.pattern_file, 'r') as f:
                self.patterns = json.load(f)
            print(f"✅ Patterns loaded successfully")
            return True
        except Exception as e:
            print(f"❌ Error loading patterns: {e}")
            return False

    def generate_component_library(self):
        """Generate component library from patterns"""
        print(f"\n🧩 Generating Component Library for {self.framework}...")

        if not self.patterns.get('components'):
            print("⚠️  No components found in patterns")
            return {}

        library = {}

        for comp in self.patterns['components']:
            comp_type = comp['type']
            examples = comp.get('examples', [])

            if not examples:
                continue

            library[comp_type] = {
                'count': comp['count'],
                'implementations': []
            }

            for i, example in enumerate(examples[:2]):  # Max 2 examples
                impl = self._convert_to_framework(comp_type, example)
                if impl:
                    library[comp_type]['implementations'].append(impl)

            print(f"  ✓ Generated {comp_type} component")

        return library

    def _convert_to_framework(self, comp_type, html_snippet):
        """Convert HTML snippet to target framework"""

        # Clean up the snippet
        snippet = html_snippet.strip()

        if self.framework == 'tailwind':
            return self._convert_tailwind(comp_type, snippet)
        elif self.framework == 'react':
            return self._convert_react(comp_type, snippet)
        elif self.framework == 'vue':
            return self._convert_vue(comp_type, snippet)
        else:
            return {'html': snippet}

    def _convert_tailwind(self, comp_type, snippet):
        """Convert to Tailwind HTML"""
        # Extract classes if present
        import re

        classes = re.findall(r'class="([^"]*)"', snippet)
        all_classes = ' '.join(classes) if classes else ''

        return {
            'framework': 'tailwind',
            'html': snippet,
            'classes': all_classes,
            'usage': f'<!-- Copy this HTML for your {comp_type} -->'
        }

    def _convert_react(self, comp_type, snippet):
        """Convert to React component"""
        import re

        # Extract classes
        classes = re.findall(r'class="([^"]*)"', snippet)

        # Convert to JSX
        jsx = snippet
        # Replace class with className
        jsx = re.sub(r'class=', 'className=', jsx)
        # Close self-closing tags
        jsx = re.sub(r'<input([^>]*)>', r'<input\1 />', jsx)

        component_name = ''.join([w.capitalize() for w in comp_type.split('_')])

        return {
            'framework': 'react',
            'component_name': component_name,
            'jsx': jsx,
            'code': f'''export function {component_name}() {{
  return (
{self._indent_jsx(jsx, 4)}
  );
}}'''
        }

    def _convert_vue(self, comp_type, snippet):
        """Convert to Vue component"""
        component_name = ''.join([w.capitalize() for w in comp_type.split('_')])

        return {
            'framework': 'vue',
            'component_name': component_name,
            'template': snippet,
            'code': f'''<template>
{self._indent_jsx(snippet, 2)}
</template>

<script setup>
// {component_name} component
</script>'''
        }

    def _indent_jsx(self, code, spaces):
        """Indent multi-line JSX/Vue code"""
        lines = code.split('\n')
        indent = ' ' * spaces
        return '\n'.join([indent + line if line.strip() else line for line in lines])

    def generate_design_system(self):
        """Generate design system from tokens"""
        print(f"\n🎨 Generating Design System...")

        if not self.patterns.get('design_tokens'):
            print("⚠️  No design tokens found")
            return {}

        tokens = self.patterns['design_tokens']
        design_system = {}

        # Colors
        if 'colors' in tokens:
            design_system['colors'] = self._generate_color_tokens(tokens['colors'])

        # Typography
        if 'typography' in tokens:
            design_system['typography'] = self._generate_typography_tokens(tokens['typography'])

        # Spacing
        if 'spacing' in tokens:
            design_system['spacing'] = self._generate_spacing_tokens(tokens['spacing'])

        # Effects
        if 'effects' in tokens:
            design_system['effects'] = self._generate_effect_tokens(tokens['effects'])

        return design_system

    def _generate_color_tokens(self, colors):
        """Generate color tokens"""
        tokens = {'tailwind': {}, 'hex': {}}

        if 'tailwind' in colors:
            # Group by color name
            for color_class in colors['tailwind']:
                parts = color_class.split('-')
                if len(parts) >= 3:
                    prop, color, shade = parts[0], parts[1], parts[2]
                    if color not in tokens['tailwind']:
                        tokens['tailwind'][color] = []
                    tokens['tailwind'][color].append(shade)

        if 'hex' in colors:
            tokens['hex'] = colors['hex'][:10]  # Limit to 10

        return tokens

    def _generate_typography_tokens(self, typography):
        """Generate typography tokens"""
        tokens = {}

        if 'fonts' in typography:
            tokens['font_families'] = typography['fonts']

        if 'sizes' in typography:
            tokens['font_sizes'] = typography['sizes']

        if 'tailwind' in typography:
            tokens['tailwind_classes'] = typography['tailwind']

        return tokens

    def _generate_spacing_tokens(self, spacing):
        """Generate spacing tokens"""
        tokens = {}

        if 'tailwind' in spacing:
            # Extract unique spacing values
            values = set()
            for class_name in spacing['tailwind']:
                parts = class_name.split('-')
                if len(parts) >= 2:
                    values.add(parts[-1])
            tokens['tailwind_scale'] = list(values)

        if 'css' in spacing:
            tokens['css_values'] = spacing['css'][:5]

        return tokens

    def _generate_effect_tokens(self, effects):
        """Generate effect tokens"""
        tokens = {}

        if 'shadows' in effects:
            tokens['box_shadows'] = effects['shadows'][:5]

        if 'tailwind_shadows' in effects:
            tokens['tailwind_shadows'] = effects['tailwind_shadows']

        if 'radius' in effects:
            tokens['border_radius'] = effects['radius']

        return tokens

    def generate_implementation_guide(self):
        """Generate implementation guide"""
        print(f"\n📖 Generating Implementation Guide...")

        source = self.patterns.get('source', 'Unknown')
        timestamp = self.patterns.get('timestamp', datetime.now().isoformat())

        guide = f'''# Design Pattern Implementation Guide

**Source:** {source}
**Analyzed:** {timestamp}
**Framework:** {self.framework}

## Quick Start

1. Review the design tokens below
2. Copy component code for your needs
3. Integrate into your project
4. Customize as needed

---

## Design System

### Colors
{self._format_colors()}

### Typography
{self._format_typography()}

### Spacing
{self._format_spacing()}

### Effects
{self._format_effects()}

---

## Components

{self._format_components()}

---

## Usage Examples

### Applying Design Tokens

```{self.framework}
<!-- Example with design tokens -->
<div class="bg-primary-500 text-white p-4 rounded-lg shadow-lg">
  Content here
</div>
```

### Using Components

Copy any component from the Components section above and adapt to your needs.

---

## Customization

### Modify Colors
Update your Tailwind config or CSS variables to match the design tokens.

### Adjust Spacing
Scale spacing values up or down based on your design system.

### Add Effects
Apply the shadow and radius patterns to other components.

---

## Attribution

This implementation is based on design patterns from: {source}

Please respect the original source's license and attribution requirements.

---

**Generated by:** Design Pattern Learner v1.0
**Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
'''

        return guide

    def _format_colors(self):
        """Format colors for guide"""
        if not self.patterns.get('design_tokens', {}).get('colors'):
            return 'No color patterns found'

        colors = self.patterns['design_tokens']['colors']
        lines = []

        if 'tailwind' in colors:
            lines.append('\n**Tailwind Colors:**')
            for color in list(colors['tailwind'])[:10]:
                lines.append(f'- `{color}`')

        if 'hex' in colors:
            lines.append('\n**Hex Colors:**')
            for hex_color in colors['hex'][:10]:
                lines.append(f'- `{hex_color}`')

        return '\n'.join(lines)

    def _format_typography(self):
        """Format typography for guide"""
        if not self.patterns.get('design_tokens', {}).get('typography'):
            return 'No typography patterns found'

        typo = self.patterns['design_tokens']['typography']
        lines = []

        if 'fonts' in typo:
            lines.append('\n**Font Families:**')
            for font in typo['fonts'][:5]:
                lines.append(f'- `{font}`')

        if 'tailwind' in typo:
            lines.append('\n**Tailwind Text Classes:**')
            for cls in typo['tailwind'][:10]:
                lines.append(f'- `{cls}`')

        return '\n'.join(lines)

    def _format_spacing(self):
        """Format spacing for guide"""
        if not self.patterns.get('design_tokens', {}).get('spacing'):
            return 'No spacing patterns found'

        spacing = self.patterns['design_tokens']['spacing']
        lines = []

        if 'tailwind' in spacing:
            lines.append('\n**Tailwind Spacing:**')
            for cls in list(spacing['tailwind'])[:10]:
                lines.append(f'- `{cls}`')

        return '\n'.join(lines)

    def _format_effects(self):
        """Format effects for guide"""
        if not self.patterns.get('design_tokens', {}).get('effects'):
            return 'No effect patterns found'

        effects = self.patterns['design_tokens']['effects']
        lines = []

        if 'shadows' in effects:
            lines.append('\n**Box Shadows:**')
            for shadow in effects['shadows'][:5]:
                lines.append(f'- `{shadow}`')

        return '\n'.join(lines)

    def _format_components(self):
        """Format components for guide"""
        if not self.patterns.get('components'):
            return 'No components found'

        library = self.generate_component_library()
        lines = []

        for comp_name, comp_data in library.items():
            lines.append(f'\n### {comp_name.capitalize()}')
            lines.append(f'\nFound: {comp_data["count"]} instance(s)')

            for impl in comp_data.get('implementations', [])[:2]:
                if self.framework == 'tailwind':
                    lines.append(f'\n```html')
                    lines.append(impl.get('html', ''))
                    lines.append('```')
                elif self.framework == 'react':
                    lines.append(f'\n```jsx')
                    lines.append(impl.get('code', ''))
                    lines.append('```')
                elif self.framework == 'vue':
                    lines.append(f'\n```vue')
                    lines.append(impl.get('code', ''))
                    lines.append('```')

        return '\n'.join(lines)

    def save_outputs(self, library, design_system, guide):
        """Save generated outputs"""
        output_dir = os.path.expanduser('~/.claude/skills/design-pattern-learner/data/outputs')
        os.makedirs(output_dir, exist_ok=True)

        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

        # Save component library
        library_file = os.path.join(output_dir, f'library_{self.framework}_{timestamp}.json')
        with open(library_file, 'w') as f:
            json.dump(library, f, indent=2)
        print(f'\n💾 Component library: {library_file}')

        # Save design system
        system_file = os.path.join(output_dir, f'design-system_{self.framework}_{timestamp}.json')
        with open(system_file, 'w') as f:
            json.dump(design_system, f, indent=2)
        print(f'💾 Design system: {system_file}')

        # Save implementation guide
        guide_file = os.path.join(output_dir, f'implementation-guide_{self.framework}_{timestamp}.md')
        with open(guide_file, 'w') as f:
            f.write(guide)
        print(f'💾 Implementation guide: {guide_file}')

        return library_file, system_file, guide_file

def main():
    if len(sys.argv) < 3:
        print("Usage: python3 generate.py --source <pattern_file> --framework <tailwind|react|vue>")
        print("Example: python3 generate.py --source patterns.json --framework tailwind")
        sys.exit(1)

    pattern_file = None
    framework = 'tailwind'

    args = sys.argv[1:]
    i = 0
    while i < len(args):
        if args[i] == '--source' and i + 1 < len(args):
            pattern_file = args[i + 1]
            i += 2
        elif args[i] == '--framework' and i + 1 < len(args):
            framework = args[i + 1].lower()
            i += 2
        else:
            i += 1

    if not pattern_file:
        print("❌ Error: --source parameter is required")
        sys.exit(1)

    if framework not in ['tailwind', 'react', 'vue']:
        print(f"⚠️  Warning: Unknown framework '{framework}', using 'tailwind'")
        framework = 'tailwind'

    generator = PatternGenerator(pattern_file, framework)

    if not generator.load_patterns():
        sys.exit(1)

    print(f"\n{'='*60}")
    print(f"🚀 GENERATING IMPLEMENTATION FOR {framework.upper()}")
    print(f"{'='*60}")

    # Generate outputs
    library = generator.generate_component_library()
    design_system = generator.generate_design_system()
    guide = generator.generate_implementation_guide()

    # Save outputs
    generator.save_outputs(library, design_system, guide)

    print(f"\n{'='*60}")
    print("✅ GENERATION COMPLETE!")
    print(f"{'='*60}")

if __name__ == '__main__':
    main()
