"""
Profile listing commands for the generate package.

Provides discovery of variance and anomaly profiles with user-friendly names and descriptions.
"""

from typing import Optional
import typer
from rich.console import Console
from rich.table import Table

from src.cli.common import BaseCommand, display_summary_table
from ..profiles.mapper import VARIANCE_PROFILE_MAPPING, ANOMALY_PROFILE_MAPPING
from profiles.core_profiles import CORE_VARIANCE_PROFILES, CORE_ANOMALY_PROFILES

console = Console()


class GenerateProfilesCommand(BaseCommand):
    """Profile listing commands for the generate package."""

    def get_config_profile_mapping(self):
        """Get mapping from config names to internal names with descriptions."""
        variance_mapping = {}
        for config_name, internal_name in VARIANCE_PROFILE_MAPPING.items():
            if internal_name in CORE_VARIANCE_PROFILES:
                profile = CORE_VARIANCE_PROFILES[internal_name]
                variance_mapping[config_name] = {
                    'internal_name': internal_name,
                    'description': profile.description,
                    'type': 'variance'
                }
        
        anomaly_mapping = {}
        for config_name, internal_name in ANOMALY_PROFILE_MAPPING.items():
            if internal_name in CORE_ANOMALY_PROFILES:
                profile = CORE_ANOMALY_PROFILES[internal_name]
                anomaly_mapping[config_name] = {
                    'internal_name': internal_name,
                    'description': profile.description,
                    'type': 'anomaly'
                }
        
        return {**variance_mapping, **anomaly_mapping}

    def list_profiles(self, profile_type: Optional[str] = None):
        """List available variance and anomaly profiles for generate configs."""
        profile_mapping = self.get_config_profile_mapping()
        
        if profile_type:
            # Filter by type
            filtered_profiles = {
                name: data for name, data in profile_mapping.items() 
                if data['type'] == profile_type
            }
            
            if not filtered_profiles:
                valid_types = set(data['type'] for data in profile_mapping.values())
                console.print(f"[red]Unknown profile type: {profile_type}[/red]")
                console.print(f"[blue]Valid types: {', '.join(sorted(valid_types))}[/blue]")
                return
            
            self._display_profile_table(profile_type, filtered_profiles)
        else:
            # Show both types
            variance_profiles = {
                name: data for name, data in profile_mapping.items() 
                if data['type'] == 'variance'
            }
            anomaly_profiles = {
                name: data for name, data in profile_mapping.items() 
                if data['type'] == 'anomaly'
            }
            
            if variance_profiles:
                self._display_profile_table('variance', variance_profiles)
                console.print()
            
            if anomaly_profiles:
                self._display_profile_table('anomaly', anomaly_profiles)
                
            # Add usage hint
            console.print()
            console.print("💡 [dim]Use these names in your generate config YAML files[/dim]")
            console.print("💡 [dim]Use 'czbillgen generate show-profile <name>' for detailed parameters[/dim]")

    def show_profile(self, profile_name: str):
        """Show detailed information about a specific profile."""
        profile_mapping = self.get_config_profile_mapping()
        
        if profile_name not in profile_mapping:
            available_profiles = sorted(profile_mapping.keys())
            console.print(f"[red]Profile not found: {profile_name}[/red]")
            console.print(f"[blue]Available profiles: {', '.join(available_profiles)}[/blue]")
            return
        
        profile_data = profile_mapping[profile_name]
        profile_type = profile_data['type']
        internal_name = profile_data['internal_name']
        
        # Get the actual profile object
        if profile_type == 'variance':
            profile_obj = CORE_VARIANCE_PROFILES[internal_name]
        else:
            profile_obj = CORE_ANOMALY_PROFILES[internal_name]
        
        # Display profile information
        console.print(f"[bold]{profile_name}[/bold] - {profile_obj.description}")
        
        # Add profile-specific characteristics
        if profile_type == 'variance':
            self._show_variance_characteristics(profile_obj)
        else:
            self._show_anomaly_characteristics(profile_obj)
        
        # Show config usage
        console.print()
        console.print("[bold]Config Usage:[/bold]")
        if profile_type == 'variance':
            console.print(f"  variance_profile: {profile_name}")
        else:
            console.print(f"  anomaly_profile: {profile_name}")

    def _display_profile_table(self, profile_type: str, profiles: dict):
        """Display profiles in a formatted table."""
        title = f"Generate {profile_type.title()} Profiles ({len(profiles)})"
        
        table = Table(title=title, show_header=True, header_style="bold blue")
        table.add_column("Profile Name", style="green", no_wrap=True)
        table.add_column("Description", style="white")
        
        # Sort profiles by name for consistency
        for profile_name in sorted(profiles.keys()):
            profile_data = profiles[profile_name]
            table.add_row(profile_name, profile_data['description'])
        
        console.print(table)

    def _show_variance_characteristics(self, profile_obj):
        """Show variance-specific characteristics."""
        console.print("• Creates natural cost fluctuation patterns over time")
        
        # Show variance levels
        variance_levels = [
            f"hourly (±{int(profile_obj.hourly_variance * 100)}%)",
            f"daily (±{int(profile_obj.daily_variance * 100)}%)",
            f"weekly (±{int(profile_obj.weekly_variance * 100)}%)",
            f"monthly (±{int(profile_obj.monthly_variance * 100)}%)"
        ]
        console.print(f"• Variance levels: {' → '.join(variance_levels)}")
        
        # Show timing pattern
        if profile_obj.timing != "always_on":
            console.print(f"• Timing pattern: {profile_obj.timing}")
        
        # Show seasonal info if applicable
        if hasattr(profile_obj, 'use_seasonal_math') and profile_obj.use_seasonal_math:
            amplitude = int(profile_obj.seasonal_amplitude * 100)
            console.print(f"• Seasonal cycles: {profile_obj.seasonal_period} patterns with {amplitude}% amplitude")
        
        # Show growth info if applicable
        if hasattr(profile_obj, 'growth_type') and profile_obj.growth_type != "none":
            console.print(f"• Growth pattern: {profile_obj.growth_type}")

    def _show_anomaly_characteristics(self, profile_obj):
        """Show anomaly-specific characteristics."""
        console.print("• Creates dramatic cost events and anomalies")
        
        # Show intensity
        if profile_obj.intensity > 10:
            console.print(f"• Event magnitude: {int(profile_obj.intensity)}x normal costs")
        elif profile_obj.intensity < 1:
            console.print(f"• Cost reduction: drops to {int(profile_obj.intensity * 100)}% of normal")
        else:
            console.print(f"• Cost change: {profile_obj.intensity:.1f}x normal costs")
        
        # Show duration
        if profile_obj.duration_hours >= 24:
            days = profile_obj.duration_hours / 24
            if profile_obj.duration_hours >= 999:
                console.print("• Duration: permanent baseline change")
            else:
                console.print(f"• Duration: ~{days:.0f} days average")
        else:
            console.print(f"• Duration: ~{profile_obj.duration_hours:.0f} hours average")
        
        # Show frequency
        if hasattr(profile_obj, 'frequency') and profile_obj.frequency:
            freq_pct = profile_obj.frequency * 100
            if freq_pct >= 1:
                console.print(f"• Frequency: {freq_pct:.0f}% daily probability")
            else:
                console.print(f"• Frequency: {freq_pct:.1f}% daily probability")


# Create command instance
profiles_cmd = GenerateProfilesCommand()