from typing import List, Optional
"""Allocation telemetry CLI commands."""

import typer
from rich.table import Table

from ..telemetry.allocation import AllocationGenerator, AllocationsConfig
from .common.base import BaseCommand

app = typer.Typer(help="Allocation telemetry generation commands")


class AllocationCommand(BaseCommand):
    """Allocation telemetry command with service integration."""

    def __init__(self):
        super().__init__()

    def load_telemetry_config(
        self, org_name: str, config_file: Optional[str] = None
    ) -> dict:
        """Load telemetry configuration using ConfigurationService."""
        from src.services.configuration import ConfigurationService

        org_dir = self.get_org_directory(org_name)
        config_service = ConfigurationService(org_dir)

        # Load telemetry config - using "allocation" as the config type
        return config_service.load_telemetry_config("allocation")


allocation_cmd = AllocationCommand()


@app.command()
def generate(
    org: str = typer.Argument(..., help="Organization name"),
    config_file: Optional[str] = typer.Option(
        None, "--config", "-c", help="Custom allocation config file path"
    ),
    output_dir: Optional[str] = typer.Option(
        None, "--output", "-o", help="Custom output directory path"
    ),
    verbose: bool = typer.Option(
        False, "--verbose", "-v", help="Enable verbose output"
    ),
):
    """Generate allocation telemetry data for an organization."""

    try:
        # Load telemetry configuration using services
        try:
            config_data = allocation_cmd.load_telemetry_config(org, config_file)
            config_source = f"telemetry/configs/{config_file or 'allocation'}.yaml"
        except FileNotFoundError as e:
            allocation_cmd.console.print(f"[red]Telemetry config not found: {e}[/red]")
            allocation_cmd.console.print(
                "[yellow]Expected location: telemetry/configs/allocation.yaml[/yellow]"
            )
            raise typer.Exit(1)

        # Load configuration
        if verbose:
            allocation_cmd.console.print(
                f"[blue]Loading configuration from: {config_source}[/blue]"
            )

        config = AllocationsConfig.from_dict(config_data)
        config.validate()

        # Determine output directory using BaseCommand
        output_path = allocation_cmd.determine_output_directory(
            org_name=org,
            output_dir=output_dir,
            subdir="allocation",
            run_type="telemetry",
        )

        # Generate allocations
        allocation_cmd.console.print(
            f"[green]Generating {len(config.allocations)} allocation datasets...[/green]"
        )

        all_created_files = []

        with allocation_cmd.create_progress_context() as progress:
            for allocation_config in config.allocations:
                task = progress.add_task(
                    f"Generating {allocation_config.name}...", total=None
                )

                # Generate allocation data
                generator = AllocationGenerator(allocation_config)
                df = generator.generate()

                # Save to CSV
                output_file = output_path / f"{allocation_config.name}.csv"
                df.write_csv(output_file)
                all_created_files.append(output_file)

                if verbose:
                    allocation_cmd.console.print(
                        f"[blue]Generated {len(df)} records for {allocation_config.name}[/blue]"
                    )
                    allocation_cmd.console.print(
                        f"[blue]Saved to: {output_file}[/blue]"
                    )

                progress.remove_task(task)

        # Display summary
        _display_summary(config.allocations, all_created_files, output_path)

    except Exception as e:
        allocation_cmd.console.print(
            f"[red]Error generating allocation data: {str(e)}[/red]"
        )
        if verbose:
            allocation_cmd.console.print_exception()
        raise typer.Exit(1)


@app.command()
def validate(
    org: str = typer.Argument(..., help="Organization name"),
    config_file: Optional[str] = typer.Option(
        None, "--config", "-c", help="Custom allocation config file path"
    ),
):
    """Validate allocation configuration file."""

    try:
        # Load telemetry configuration using services
        try:
            config_data = allocation_cmd.load_telemetry_config(org, config_file)
            config_source = f"telemetry/configs/{config_file or 'allocation'}.yaml"
        except FileNotFoundError as e:
            allocation_cmd.console.print(f"[red]Telemetry config not found: {e}[/red]")
            raise typer.Exit(1)

        # Load and validate configuration
        allocation_cmd.console.print(
            f"[blue]Validating configuration: {config_source}[/blue]"
        )
        config = AllocationsConfig.from_dict(config_data)
        config.validate()

        allocation_cmd.console.print("[green]✓ Configuration is valid![/green]")
        allocation_cmd.console.print(
            f"[blue]Found {len(config.allocations)} allocation(s) defined[/blue]"
        )

        # Display allocation summary
        table = Table(title="Defined Allocations")
        table.add_column("Name", style="cyan")
        table.add_column("Scale", style="magenta")
        table.add_column("Frequency", style="green")
        table.add_column("Elements", style="yellow")
        table.add_column("Date Range", style="blue")

        for allocation in config.allocations:
            date_range = f"{allocation.start_date} to {allocation.end_date}"

            # Element info
            if allocation.elements.type == "generated":
                element_info = f"{allocation.elements.count} generated"
            else:
                element_info = f"{len(allocation.elements.list)} provided"

            table.add_row(
                allocation.name,
                allocation.scale.name,
                allocation.frequency,
                element_info,
                date_range,
            )

        allocation_cmd.console.print(table)

        # Display element details for each allocation
        for allocation in config.allocations:
            allocation_cmd.console.print(
                f"\n[cyan]Elements for '{allocation.name}':[/cyan]"
            )
            if allocation.elements.type == "generated":
                allocation_cmd.console.print(
                    f"  Type: Generated ({allocation.elements.count} elements)"
                )
                allocation_cmd.console.print(f"  Prefix: {allocation.elements.prefix}")
                allocation_cmd.console.print(
                    f"  Pattern: {allocation.elements.naming_pattern}"
                )
                # Show first few element examples
                elements = []
                for i in range(1, min(4, allocation.elements.count + 1)):
                    element_id = f"{allocation.elements.prefix}_{allocation.elements.naming_pattern.format(i)}"
                    elements.append(element_id)
                if allocation.elements.count > 3:
                    elements.append("...")
                allocation_cmd.console.print(f"  Examples: {', '.join(elements)}")
            else:
                allocation_cmd.console.print(
                    f"  Type: Provided ({len(allocation.elements.list)} elements)"
                )
                elements = allocation.elements.List[:5]  # Show first 5
                if len(allocation.elements.list) > 5:
                    elements.append("...")
                allocation_cmd.console.print(f"  Elements: {', '.join(elements)}")

    except Exception as e:
        allocation_cmd.console.print(f"[red]Validation failed: {str(e)}[/red]")
        raise typer.Exit(1)


def _display_summary(allocations, created_files, output_path):
    """Display generation summary."""
    allocation_cmd.console.print("\n[green]✓ Allocation generation completed![/green]")
    allocation_cmd.console.print(f"[blue]Output directory: {output_path}[/blue]")
    allocation_cmd.console.print(
        f"[blue]Total files created: {len(created_files)}[/blue]"
    )

    # Display file summary table
    table = Table(title="Generated Files")
    table.add_column("Allocation", style="cyan")
    table.add_column("File", style="magenta")
    table.add_column("Records", style="green")

    for i, (allocation, file_path) in enumerate(
        zip(allocations, created_files, strict=False)
    ):
        # Get record count from file
        try:
            import polars as pl

            df = pl.read_csv(file_path)
            record_count = len(df)
        except Exception:
            record_count = "Unknown"

        table.add_row(allocation.name, file_path.name, str(record_count))

    allocation_cmd.console.print(table)
