"""
HeyAPI TypeScript Generator for Django Revolution

Generates TypeScript clients using @hey-api/openapi-ts.
"""

from pathlib import Path
from typing import Dict, Optional, Any

from ..config import DjangoRevolutionSettings, GenerationResult
from ..utils import Logger, run_command, check_dependency, ensure_directories


class HeyAPITypeScriptGenerator:
    """TypeScript client generator using @hey-api/openapi-ts."""
    
    def __init__(self, config: DjangoRevolutionSettings, logger: Optional[Logger] = None):
        """
        Initialize TypeScript generator.
        
        Args:
            config: Django Revolution settings
            logger: Optional logger instance
        """
        self.config = config
        self.logger = logger or Logger("heyapi_ts_generator")
        self.output_dir = Path(config.generators.typescript.output_directory)
        
    def is_available(self) -> bool:
        """
        Check if @hey-api/openapi-ts is available.
        
        Returns:
            bool: True if available
        """
        return check_dependency(['npx', '@hey-api/openapi-ts', '--version'])
    
    def generate_client(self, zone_name: str, schema_path: Path) -> GenerationResult:
        """
        Generate TypeScript client for a single zone.
        
        Args:
            zone_name: Name of the zone
            schema_path: Path to OpenAPI schema file
            
        Returns:
            GenerationResult with operation details
        """
        self.logger.info(f"Generating TypeScript client for zone: {zone_name}")
        
        # Validate schema file
        if not schema_path.exists():
            error_msg = f"Schema file not found: {schema_path}"
            self.logger.error(error_msg)
            return GenerationResult(
                success=False,
                zone_name=zone_name,
                output_path=Path(),
                files_generated=0,
                error_message=error_msg
            )
        
        # Setup output directory
        zone_output_dir = self.output_dir / zone_name
        ensure_directories(zone_output_dir)
        
        try:
            # Generate TypeScript client using @hey-api/openapi-ts
            cmd = [
                'npx', '@hey-api/openapi-ts',
                '--input', str(schema_path),
                '--output', str(zone_output_dir)
            ]
            
            # Add output format option if specified
            # Note: --format option is not supported in hey-api
            pass
            
            # Add test generation if enabled
            # Note: --tests option is not supported in hey-api
            pass
            
            success, output = run_command(' '.join(cmd), timeout=120)
            
            if success:
                # Count generated files
                files_generated = self._count_generated_files(zone_output_dir)
                
                # Generate files using templates
                self._generate_from_templates(zone_name, zone_output_dir)
                
                self.logger.success(f"TypeScript client generated for {zone_name}: {files_generated} files")
                
                return GenerationResult(
                    success=True,
                    zone_name=zone_name,
                    output_path=zone_output_dir,
                    files_generated=files_generated,
                    error_message=""
                )
            else:
                error_msg = f"TypeScript generation failed: {output}"
                self.logger.error(error_msg)
                
                return GenerationResult(
                    success=False,
                    zone_name=zone_name,
                    output_path=zone_output_dir,
                    files_generated=0,
                    error_message=error_msg
                )
                
        except Exception as e:
            error_msg = f"TypeScript generation exception: {str(e)}"
            self.logger.error(error_msg)
            
            return GenerationResult(
                success=False,
                zone_name=zone_name,
                output_path=zone_output_dir,
                files_generated=0,
                error_message=error_msg
            )
    
    def generate_all(self, schemas: Dict[str, Path]) -> Dict[str, GenerationResult]:
        """
        Generate TypeScript clients for all provided schemas.
        
        Args:
            schemas: Dictionary mapping zone names to schema paths
            
        Returns:
            Dictionary mapping zone names to generation results
        """
        if not schemas:
            self.logger.warning("No schemas provided for TypeScript generation")
            return {}
        
        self.logger.info(f"Generating TypeScript clients for {len(schemas)} zones")
        
        results = {}
        
        for zone_name, schema_path in schemas.items():
            result = self.generate_client(zone_name, schema_path)
            results[zone_name] = result
        
        successful = sum(1 for r in results.values() if r.success)
        self.logger.info(f"TypeScript generation completed: {successful}/{len(results)} successful")
        
        return results
    
    def _count_generated_files(self, directory: Path) -> int:
        """
        Count the number of generated files in a directory.
        
        Args:
            directory: Directory to count files in
            
        Returns:
            Number of files generated
        """
        if not directory.exists():
            return 0
        
        count = 0
        for file_path in directory.rglob('*'):
            if file_path.is_file():
                count += 1
        
        return count
    
    def _generate_from_templates(self, zone_name: str, output_dir: Path):
        """
        Generate files using Jinja2 templates.
        
        Args:
            zone_name: Name of the zone
            output_dir: Output directory for the client
        """
        try:
            import jinja2
            from datetime import datetime
            
            # Setup Jinja2 environment
            templates_dir = Path(__file__).parent / 'templates'
            env = jinja2.Environment(
                loader=jinja2.FileSystemLoader(str(templates_dir)),
                trim_blocks=True,
                lstrip_blocks=True
            )
            
            # Get zone info from config
            zones = self.config.zones
            zone_info = zones.get(zone_name, {})
            
            # Prepare context for templates
            context = {
                'zone_name': zone_name,
                'title': zone_info.get('title', f'{zone_name.title()} API'),
                'description': zone_info.get('description', f'TypeScript client for {zone_name} zone'),
                'apps': zone_info.get('apps', []),
                'generation_time': datetime.now().isoformat(),
            }
            
            # Generate index.ts
            index_template = env.get_template('index.ts.j2')
            index_content = index_template.render(**context)
            with open(output_dir / 'index.ts', 'w', encoding='utf-8') as f:
                f.write(index_content)
            
            # Generate package.json
            package_template = env.get_template('package.json.j2')
            package_content = package_template.render(**context)
            with open(output_dir / 'package.json', 'w', encoding='utf-8') as f:
                f.write(package_content)
            
            self.logger.debug(f"Generated template files for {zone_name}")
            
        except ImportError:
            self.logger.warning("Jinja2 not available, skipping template generation")
        except Exception as e:
            self.logger.warning(f"Failed to generate template files for {zone_name}: {e}")
    
    def clean_output(self) -> bool:
        """
        Clean TypeScript output directory.
        
        Returns:
            bool: True if cleaning successful
        """
        try:
            if self.output_dir.exists():
                import shutil
                shutil.rmtree(self.output_dir)
            
            ensure_directories(self.output_dir)
            self.logger.success("TypeScript output directory cleaned")
            return True
            
        except Exception as e:
            self.logger.error(f"Failed to clean TypeScript output directory: {e}")
            return False
    
    def get_status(self) -> Dict[str, Any]:
        """
        Get TypeScript generator status.
        
        Returns:
            Status information dictionary
        """
        return {
            'available': self.is_available(),
            'output_directory': str(self.output_dir),
            'enabled': self.config.generators.typescript.enabled,
            'output_format': self.config.generators.typescript.output_format,
            'generate_tests': self.config.generators.typescript.generate_tests,
            'custom_templates': self.config.generators.typescript.custom_templates
        } 