"""
Progress display for API job execution.

Shows user feedback for job submission, polling, completion, and errors.
Follows CLAUDE.md: Single responsibility, <10 methods, <50 lines/method.
"""

from typing import Dict, Any
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn


class ProgressDisplay:
    """
    Display progress and status updates.

    Single responsibility: User feedback and progress display.
    Dependencies injected: Console.
    """

    def __init__(self, console: Console):
        """
        Initialize progress display.

        Args:
            console: Rich console for output
        """
        self.console = console

    def show_submission(self, job_id: str, job_type: str) -> None:
        """
        Show job submission confirmation.

        Args:
            job_id: Submitted job ID
            job_type: Job type
        """
        self.console.print(f"[green]✓ Job submitted successfully[/green]")
        self.console.print(f"  Job ID: {job_id}")
        self.console.print(f"  Job Type: {job_type}")
        self.console.print()

    def show_polling(self, status_data: Dict[str, Any]) -> None:
        """
        Show polling status update with optional progress tracking.

        Args:
            status_data: Job status dictionary
        """
        status = status_data.get("status", "unknown")
        job_id = status_data.get("job_id", "unknown")

        # Map status to display format
        status_display = {
            "queued": "[yellow]⏳ Queued[/yellow]",
            "running": "[blue]▶ Running[/blue]",
            "completed": "[green]✓ Completed[/green]",
            "failed": "[red]✗ Failed[/red]",
        }.get(status, f"[dim]{status}[/dim]")

        # Build status line
        status_line = f"  Status: {status_display} (Job: {job_id})"

        # Add latest progress if available
        processing_stages = status_data.get("processing_stages", [])
        if processing_stages and status == "running":
            latest_stage = processing_stages[-1]
            progress = latest_stage.get("progress")

            if progress:
                current = progress.get("current", 0)
                total = progress.get("total", 0)
                percent = progress.get("percent", 0)
                stage_name = latest_stage.get("stage", "")

                # Format progress info
                status_line = f"  Status: {status_display} - {stage_name} ({current:,}/{total:,} - {percent:.1f}%)"

        self.console.print(status_line, end="\r")

    def show_completion(self, result: Dict[str, Any]) -> None:
        """
        Show job completion details.

        Args:
            result: Final job status with results
        """
        self.console.print()  # New line after polling
        self.console.print("[green]✓ Job completed successfully[/green]")

        # Show result details if available
        job_result = result.get("result", {})
        if job_result:
            # Highlight dataset name for generate stage
            dataset_name = job_result.get("dataset_name")
            stage = job_result.get("stage")

            if dataset_name and stage == "generate":
                self.console.print()
                self.console.print(f"[bold green]📦 Dataset ID:[/bold green] [cyan]{dataset_name}[/cyan]")
                self.console.print()
                self.console.print("[dim]Next steps:[/dim]")
                self.console.print(f"[dim]  1. Update your k8s config with: dataset_name: \"{dataset_name}\"[/dim]")
                self.console.print(f"[dim]  2. Run: czbg k8s run --config k8s_config.yaml --api[/dim]")
                self.console.print()

            # Show per-month statistics if available
            if "per_month_statistics" in job_result and "peak_month" in job_result:
                self._show_per_month_statistics(job_result)

            self.console.print("[bold]Results:[/bold]")
            for key, value in job_result.items():
                # Skip per-month stats (already displayed above)
                if key in ("per_month_statistics", "peak_month"):
                    continue
                self.console.print(f"  {key}: {value}")

    def _show_per_month_statistics(self, job_result: Dict[str, Any]) -> None:
        """
        Display per-month line item statistics with peak month highlighted.

        Args:
            job_result: Job result containing per_month_statistics and peak_month
        """
        per_month_stats = job_result.get("per_month_statistics", {})
        peak_month = job_result.get("peak_month", {})
        total_records = job_result.get("total_records", 0)

        if not per_month_stats:
            return

        self.console.print()
        self.console.print("[bold]📊 Per-Month Line Item Counts:[/bold]")
        # Convert to int for comma formatting
        self.console.print(f"  [dim]Total across all months: {int(total_records):,} records[/dim]")
        self.console.print()

        # Sort by provider-month key for consistent display
        sorted_months = sorted(per_month_stats.keys())

        for month_key in sorted_months:
            stats = per_month_stats[month_key]
            provider = stats["provider"]
            month = stats["month"]
            # Convert to int for comma formatting
            count = int(stats["record_count"])
            size_mb = stats["file_size_mb"]

            # Highlight peak month
            is_peak = (peak_month.get("key") == month_key)

            if is_peak:
                self.console.print(
                    f"  [bold yellow]⭐ {provider}-{month}:[/bold yellow] "
                    f"[bold yellow]{count:,} records[/bold yellow] "
                    f"[dim]({size_mb} MB)[/dim] "
                    f"[bold yellow]← PEAK MONTH[/bold yellow]"
                )
            else:
                self.console.print(
                    f"  [cyan]{provider}-{month}:[/cyan] "
                    f"{count:,} records [dim]({size_mb} MB)[/dim]"
                )

        # Emphasize peak month for CloudZero billing
        if peak_month:
            self.console.print()
            # Convert to int for comma formatting
            peak_count = int(peak_month.get('record_count', 0))
            self.console.print(
                f"[bold]💡 CloudZero Platform Billing:[/bold] "
                f"Peak month has [yellow]{peak_count:,} line items[/yellow]"
            )
        self.console.print()

    def show_error(self, error: Exception = None, job_id: str = None, error_details: Dict[str, Any] = None) -> None:
        """
        Show error message with optional structured error details.

        Args:
            error: Exception that occurred
            job_id: Optional job ID
            error_details: Optional structured error information
        """
        self.console.print()  # New line

        if error_details:
            self._show_structured_error(error, job_id, error_details)
        else:
            self._show_simple_error(error, job_id)

    def _show_structured_error(self, error: Exception, job_id: str, error_details: Dict[str, Any]) -> None:
        """
        Display structured error with actionable suggestions.

        Args:
            error: Original exception
            job_id: Job identifier
            error_details: Structured error information
        """
        stage = error_details.get("stage", "unknown")
        error_type = error_details.get("error_type", "Error")
        message = error_details.get("message", str(error) if error else "Unknown error")
        field = error_details.get("field")
        suggestion = error_details.get("suggestion")

        # Display error header
        self.console.print(f"[red]✗ {error_type} in {stage} stage[/red]")
        if job_id:
            self.console.print(f"  Job ID: {job_id}")
        self.console.print()

        # Display error message
        self.console.print(f"[bold]Error:[/bold]")
        self.console.print(f"  {message}")
        self.console.print()

        # Display config field if specified
        if field:
            self.console.print(f"[bold]Config Field:[/bold] [yellow]{field}[/yellow]")
            self.console.print()

        # Display suggestion prominently
        if suggestion:
            self.console.print(f"[bold green]💡 How to fix:[/bold green]")
            self.console.print(f"  {suggestion}")
            self.console.print()

        # Hint about full traceback
        self.console.print("[dim]Run with --verbose flag to see full traceback[/dim]")

    def _show_simple_error(self, error: Exception, job_id: str) -> None:
        """
        Display simple error message.

        Args:
            error: Exception that occurred
            job_id: Optional job ID
        """
        error_msg = str(error) if error else "Unknown error"
        self.console.print(f"[red]✗ Error: {error_msg}[/red]")
        if job_id:
            self.console.print(f"  Job ID: {job_id}")
