from typing import Optional
"""
Usage-reference summary commands with consistent interface.
"""

from pathlib import Path

import polars as pl
import typer

from ..common import BaseCommand, display_summary_table

app = typer.Typer(help="Usage-reference data summary")


class UsageReferenceSummaryCommand(BaseCommand):
    """Usage-reference summary with same interface as reference summary."""

    def summarize_usage_reference(
        self,
        cloud_provider: Optional[str] = None,
        service: Optional[str] = None,
        usage_family: Optional[str] = None,
        resource_type: Optional[str] = None,
        operation: Optional[str] = None,
        usage_type: Optional[str] = None,
        pricing_unit: Optional[str] = None,
        limit: int = 100,
        export_csv: Optional[str] = None,
        file_path: str = "data/usage_reference/usage_standards.parquet",
    ):
        """
        Summarize usage-reference data with optional drilldown filters.
        Uses same progressive drilldown pattern as reference summary.
        """
        try:
            file_path_obj = Path(file_path)
            if not file_path_obj.exists():
                self.console.print(
                    f"[red]Usage-reference file not found: {file_path_obj}[/red]"
                )
                return

            df = pl.read_parquet(file_path_obj)

            # Handle global summary case
            if not any(
                [
                    cloud_provider,
                    service,
                    usage_family,
                    resource_type,
                    operation,
                    usage_type,
                    pricing_unit,
                ]
            ):
                self._show_global_summary(df)
                return

            # Apply progressive filters
            filtered_df = self._apply_filters(
                df,
                {
                    "cloud_provider": cloud_provider,
                    "service": service,
                    "usage_family": usage_family,
                    "resource_type": resource_type,
                    "operation": operation,
                    "usage_type": usage_type,
                    "pricing_unit": pricing_unit,
                },
            )

            if filtered_df.is_empty():
                self.console.print("[yellow]No matching entries found.[/yellow]")
                return

            # Determine grouping level for progressive drilldown
            group_cols = self._determine_group_columns(
                {
                    "cloud_provider": cloud_provider,
                    "service": service,
                    "usage_family": usage_family,
                    "resource_type": resource_type,
                    "operation": operation,
                    "usage_type": usage_type,
                    "pricing_unit": pricing_unit,
                }
            )

            # Group and display
            grouped_result = self._group_data(filtered_df, group_cols)
            result = grouped_result.head(limit)

            self._display_results(result, group_cols)

            # Show truncation warning
            if grouped_result.height > limit:
                self.console.print(
                    f"\n[yellow]⚠️ Showing first {limit} rows out of {grouped_result.height} total matches. Use --limit to see more.[/yellow]"
                )

            # Export if requested
            if export_csv:
                result.write_csv(export_csv)
                self.console.print(f"[green]Results exported to {export_csv}[/green]")

        except Exception as e:
            self.handle_exception(e, "usage-reference summary")

    def _apply_filters(self, df: pl.DataFrame, filters: dict) -> pl.DataFrame:
        """Apply progressive filters to the dataframe."""
        for column, value in filters.items():
            if value and column in df.columns:
                df = df.filter(pl.col(column).str.contains(value))
        return df

    def _determine_group_columns(self, filters: dict) -> list:
        """Determine grouping columns based on applied filters (progressive drilldown)."""
        if filters["pricing_unit"]:
            return [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
                "usage_type",
                "pricing_unit",
            ]
        elif filters["usage_type"]:
            return [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
                "usage_type",
            ]
        elif filters["operation"]:
            return [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
            ]
        elif filters["resource_type"]:
            return ["cloud_provider", "service", "usage_family", "resource_type"]
        elif filters["usage_family"]:
            return ["cloud_provider", "service", "usage_family"]
        elif filters["service"]:
            return ["cloud_provider", "service"]
        else:
            return ["cloud_provider"]

    def _group_data(self, df: pl.DataFrame, group_cols: list) -> pl.DataFrame:
        """Group data for display."""
        available_cols = [col for col in group_cols if col in df.columns]

        if not available_cols:
            return pl.DataFrame()

        return (
            df.group_by(available_cols).agg(pl.len().alias("rows")).sort(available_cols)
        )

    def _show_global_summary(self, df: pl.DataFrame):
        """Show global summary with quality statistics."""
        missing_fields = df.select(
            [
                (
                    pl.col("cloud_provider").is_null()
                    | (pl.col("cloud_provider") == "")
                ).alias("cloud_provider"),
                (pl.col("service").is_null() | (pl.col("service") == "")).alias(
                    "service"
                ),
                (
                    pl.col("usage_family").is_null() | (pl.col("usage_family") == "")
                ).alias("usage_family"),
                (
                    pl.col("resource_type").is_null() | (pl.col("resource_type") == "")
                ).alias("resource_type"),
                (pl.col("operation").is_null() | (pl.col("operation") == "")).alias(
                    "operation"
                ),
                (pl.col("usage_type").is_null() | (pl.col("usage_type") == "")).alias(
                    "usage_type"
                ),
                (
                    pl.col("pricing_unit").is_null() | (pl.col("pricing_unit") == "")
                ).alias("pricing_unit"),
            ]
        )

        missing_counts = missing_fields.sum()
        total_rows = df.height
        service_usage_count = df.filter(
            pl.col("resource_type") == "service-usage"
        ).height

        # Calculate pricing statistics
        cost_stats = {}
        if "total_cost" in df.columns and "total_usage" in df.columns:
            cost_stats = {
                "total_cost_sum": df.select(pl.col("total_cost").sum()).item(),
                "total_usage_sum": df.select(pl.col("total_usage").sum()).item(),
                "avg_cost_per_unit": df.select(pl.col("cost_per_unit").mean()).item()
                if "cost_per_unit" in df.columns
                else None,
            }

        self.console.print("\n[green]Usage-Reference Data Quality Summary:[/green]")
        self.console.print(f"Total records: {total_rows}")
        self.console.print(f"Service-usage entries: {service_usage_count}")

        if cost_stats:
            self.console.print(
                f"Total cost represented: ${cost_stats['total_cost_sum']:,.2f}"
                if cost_stats["total_cost_sum"]
                else ""
            )
            self.console.print(
                f"Average cost per unit: ${cost_stats['avg_cost_per_unit']:.4f}"
                if cost_stats["avg_cost_per_unit"]
                else ""
            )

        self.console.print("\nMissing Values by Column:")
        print(missing_counts)

    def _display_results(self, result: pl.DataFrame, group_cols: list):
        """Display results."""
        if result.is_empty():
            self.console.print("[yellow]No data found.[/yellow]")
            return

        result_dict = result.to_dicts()
        display_cols = [col for col in group_cols if col in result.columns] + ["rows"]

        display_summary_table(
            self.console, "Usage-Reference Data", result_dict, display_cols
        )


# Create command instance
summary_cmd = UsageReferenceSummaryCommand()


@app.command()
def data(
    cloud_provider: Optional[str] = typer.Option(
        None, "--cloud-provider", help="Filter by cloud provider"
    ),
    service: Optional[str] = typer.Option(None, "--service", help="Filter by service"),
    usage_family: Optional[str] = typer.Option(
        None, "--usage-family", help="Filter by usage family"
    ),
    resource_type: Optional[str] = typer.Option(
        None, "--resource-type", help="Filter by resource type"
    ),
    operation: Optional[str] = typer.Option(
        None, "--operation", help="Filter by operation"
    ),
    usage_type: Optional[str] = typer.Option(
        None, "--usage-type", help="Filter by usage type"
    ),
    pricing_unit: Optional[str] = typer.Option(
        None, "--pricing-unit", help="Filter by pricing unit"
    ),
    limit: int = typer.Option(100, "--limit", help="Limit number of rows displayed"),
    export_csv: Optional[str] = typer.Option(
        None, "--export", help="Export results to CSV"
    ),
    file_path: str = typer.Option(
        "data/usage_reference/usage_standards.parquet",
        "--file",
        help="Usage-reference file path",
    ),
):
    """Summarize usage-reference data with progressive drilldown."""
    summary_cmd.summarize_usage_reference(
        cloud_provider,
        service,
        usage_family,
        resource_type,
        operation,
        usage_type,
        pricing_unit,
        limit,
        export_csv,
        file_path,
    )
