from typing import Optional
"""
Enhanced reference summary with usage-reference availability indicators.
"""

from pathlib import Path

import polars as pl
import typer

from ..common import BaseCommand, display_summary_table

app = typer.Typer(help="Enhanced reference data summary with coverage indicators")


class EnhancedSummaryCommand(BaseCommand):
    """Enhanced summary command with cross-dataset analysis."""

    def summarize_with_coverage(
        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,
        limit: int = 100,
        export_csv: Optional[str] = None,
        reference_file: str = "data/providers.csv",
        usage_reference_file: str = "data/usage_reference/usage_standards.parquet",
        show_coverage_only: bool = False,
    ):
        """
        Enhanced reference summary with usage-reference coverage indicators.
        Uses progressive drilldown like the original but adds coverage information.
        """
        try:
            # Load reference data
            ref_path = Path(reference_file)
            if not ref_path.exists():
                self.console.print(f"[red]Reference file not found: {ref_path}[/red]")
                return

            df = pl.read_csv(ref_path)

            # Load usage-reference data for coverage analysis
            usage_ref_path = Path(usage_reference_file)
            usage_coverage = {}
            if usage_ref_path.exists():
                try:
                    usage_df = pl.read_parquet(usage_ref_path)
                    usage_coverage = self._build_coverage_map(usage_df)
                except Exception as e:
                    self.console.print(
                        f"[yellow]Warning: Could not load usage-reference data: {e}[/yellow]"
                    )

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

            # Apply progressive filters (same logic as original)
            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,
                },
            )

            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,
                }
            )

            # Group and analyze coverage
            grouped_result = self._group_with_coverage(
                filtered_df, group_cols, usage_coverage, show_coverage_only
            )

            # Display results
            result = grouped_result.head(limit)
            self._display_results_with_coverage(
                result, group_cols, usage_coverage is not None
            )

            # 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, "enhanced summary")

    def _build_coverage_map(self, usage_df: pl.DataFrame) -> dict:
        """Build a map of combinations that have usage-reference data."""
        coverage_map = set()

        key_cols = [
            "cloud_provider",
            "service",
            "usage_family",
            "resource_type",
            "operation",
            "usage_type",
        ]
        available_cols = [col for col in key_cols if col in usage_df.columns]

        if available_cols:
            for row in usage_df.select(available_cols).iter_rows(named=True):
                key = tuple(row[col] for col in available_cols)
                coverage_map.add(key)

        return coverage_map

    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)."""
        # Same logic as original summary command
        if filters["operation"] or filters["usage_type"]:
            return [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
                "usage_type",
            ]
        elif filters["resource_type"]:
            return [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
            ]
        elif filters["usage_family"]:
            return ["cloud_provider", "service", "usage_family", "resource_type"]
        elif filters["service"]:
            return ["cloud_provider", "service", "usage_family"]
        elif filters["cloud_provider"]:
            return ["cloud_provider", "service"]
        else:
            return ["cloud_provider"]

    def _group_with_coverage(
        self,
        df: pl.DataFrame,
        group_cols: list,
        usage_coverage: dict,
        coverage_only: bool = False,
    ) -> pl.DataFrame:
        """Group data and add coverage information."""
        available_group_cols = [col for col in group_cols if col in df.columns]

        if not available_group_cols:
            return pl.DataFrame()

        # Group by available columns
        grouped = (
            df.group_by(available_group_cols)
            .agg(pl.len().alias("rows"))
            .sort(available_group_cols)
        )

        # Add coverage information if usage_coverage is available
        if usage_coverage:
            coverage_info = []
            key_cols = [
                "cloud_provider",
                "service",
                "usage_family",
                "resource_type",
                "operation",
                "usage_type",
            ]
            available_key_cols = [col for col in key_cols if col in grouped.columns]

            for row in grouped.iter_rows(named=True):
                key = tuple(row.get(col) for col in available_key_cols)
                has_coverage = key in usage_coverage
                coverage_info.append(has_coverage)

            # Add coverage column
            grouped = grouped.with_columns(pl.Series("has_usage_data", coverage_info))

            # Filter to coverage-only if requested
            if coverage_only:
                grouped = grouped.filter(pl.col("has_usage_data") == True)

        return grouped

    def _show_global_summary(self, df: pl.DataFrame, usage_coverage: dict):
        """Show global summary with coverage 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"
                ),
            ]
        )

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

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

        # Coverage statistics
        if usage_coverage:
            coverage_count = self._calculate_coverage_count(df, usage_coverage)
            coverage_percentage = (
                round((coverage_count / total_rows) * 100, 1) if total_rows > 0 else 0
            )
            self.console.print(
                f"Records with usage-reference data: {coverage_count} ({coverage_percentage}%)"
            )
        else:
            self.console.print(
                "Usage-reference coverage: [yellow]Not available[/yellow]"
            )

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

    def _calculate_coverage_count(self, df: pl.DataFrame, usage_coverage: dict) -> int:
        """Calculate how many reference records have usage-reference coverage."""
        if not usage_coverage:
            return 0

        count = 0
        key_cols = [
            "cloud_provider",
            "service",
            "usage_family",
            "resource_type",
            "operation",
            "usage_type",
        ]
        available_cols = [col for col in key_cols if col in df.columns]

        for row in df.select(available_cols).iter_rows(named=True):
            key = tuple(row[col] for col in available_cols)
            if key in usage_coverage:
                count += 1

        return count

    def _display_results_with_coverage(
        self, result: pl.DataFrame, group_cols: list, has_coverage_data: bool
    ):
        """Display results with coverage indicators."""
        self.console.print("\n[green]Enhanced Exploration Results:[/green]")

        if has_coverage_data and "has_usage_data" in result.columns:
            # Convert to pandas and format for display
            df_dict = result.to_dicts()
            for row in df_dict:
                # Format coverage indicator
                row["usage_data"] = "✓" if row.get("has_usage_data", False) else "✗"
                # Remove the boolean column
                row.pop("has_usage_data", None)

            # Determine display columns
            display_cols = [col for col in group_cols if col in result.columns] + [
                "rows",
                "usage_data",
            ]

            display_summary_table(
                self.console, "Reference Data with Coverage", df_dict, display_cols
            )

            # Show coverage summary
            covered_count = sum(1 for row in df_dict if row["usage_data"] == "✓")
            total_count = len(df_dict)
            self.console.print(
                f"\n[blue]Coverage: {covered_count}/{total_count} combinations have usage-reference data[/blue]"
            )
        else:
            # Standard display without coverage
            df_dict = result.to_dicts()
            display_cols = [col for col in group_cols if col in result.columns] + [
                "rows"
            ]

            display_summary_table(self.console, "Reference Data", df_dict, display_cols)


# Create command instance
summary_cmd = EnhancedSummaryCommand()


@app.command()
def enhanced(
    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"
    ),
    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"
    ),
    reference_file: str = typer.Option(
        "data/providers.csv", "--reference-file", help="Reference data file"
    ),
    usage_reference_file: str = typer.Option(
        "data/usage_reference/usage_standards.parquet",
        "--usage-reference-file",
        help="Usage-reference data file",
    ),
    coverage_only: bool = typer.Option(
        False,
        "--coverage-only",
        help="Show only combinations with usage-reference data",
    ),
):
    """Enhanced reference summary with usage-reference coverage indicators."""
    summary_cmd.summarize_with_coverage(
        cloud_provider,
        service,
        usage_family,
        resource_type,
        operation,
        usage_type,
        limit,
        export_csv,
        reference_file,
        usage_reference_file,
        coverage_only,
    )
