"""
Show reference dataset status and summary information.
"""

import typer
from pathlib import Path
from typing import Optional
import polars as pl
from rich.console import Console
from rich.table import Table

from ..common import BaseCommand, display_summary_table
from .reference_loader import load_reference_data, ensure_reference_data_available
from src.services.environment_service import env_service
from src.services.s3_data_service import S3DataService
from src.services.versioning.local_cache_manager import LocalCacheManager
from src.services.versioning.version_manager import VersionManager
from src.services.versioning.sync_manager import SyncManager

console = Console()
app = typer.Typer(help="Reference dataset status and statistics")


class DataStatusCommand(BaseCommand):
    """Show reference dataset status with version information."""

    def __init__(self):
        """Initialize with versioning support."""
        super().__init__()
        self.s3_service = S3DataService()
        self.cache_manager = LocalCacheManager()
        self.version_manager = VersionManager(self.s3_service)
        self.sync_manager = SyncManager(self.cache_manager, self.version_manager, self.s3_service)

    def show_status(
        self,
        verbose: bool = False
    ):
        """Show dataset health, growth, and summary statistics with version info."""
        try:
            # Load reference data from S3 only
            df = load_reference_data()

            if df is None:
                if not ensure_reference_data_available():
                    return

            if verbose:
                console.print(f"[blue]Loaded reference data: {df.height:,} rows[/blue]")

            # Display sync status first
            self._display_sync_status()
            console.print()

            # Display version information
            self._display_version_status()
            console.print()

            # Display overall status
            self._display_overall_status(df)

            # Display provider summary
            self._display_provider_summary(df)

            # Display coverage details
            self._display_coverage_details(df)

            # Display top combinations
            self._display_top_combinations(df)

        except Exception as e:
            self.handle_exception(e, "showing dataset status", verbose)

    def _display_sync_status(self):
        """Display sync status between local and S3."""
        try:
            sync_status = self.sync_manager.get_sync_status()
            cache_info = self.cache_manager.get_cache_info()

            console.print("🔄 [bold]Sync Status[/bold]")
            console.print("=============")

            # Overall status
            if sync_status.is_synced:
                status_icon = "✅ Synced"
                status_style = "green"
            elif sync_status.local_ahead:
                status_icon = "⬆️  Local ahead"
                status_style = "yellow"
            elif sync_status.remote_ahead:
                status_icon = "⬇️  Remote ahead"
                status_style = "blue"
            else:
                status_icon = "❓ Unknown"
                status_style = "dim"

            console.print(f"📊 Status: [{status_style}]{status_icon}[/{status_style}]")
            console.print(f"💡 Recommendation: {sync_status.recommendation.title()}")

            # Local cache info
            if cache_info:
                console.print(f"💾 Local cache: {cache_info.record_count:,} combinations ({cache_info.file_size_mb:.1f} MB)")
                console.print(f"📅 Modified: {cache_info.modified_time.strftime('%Y-%m-%d %H:%M:%S')}")
                console.print(f"🔄 Has changes: {'Yes' if cache_info.has_local_changes else 'No'}")
            else:
                console.print("💾 Local cache: Not found")

            # Show next actions
            if sync_status.recommendation == "upload":
                console.print("📤 Next: Run 'czbg data upload' to sync changes to S3", style="yellow")
            elif sync_status.recommendation == "download":
                console.print("📥 Next: Run 'czbg data download' to get latest S3 data", style="blue")

        except Exception as e:
            console.print(f"⚠️  Could not load sync status: {e}", style="dim yellow")

    def _display_version_status(self):
        """Display version information for the current dataset."""
        try:
            versions = self.version_manager.list_versions()
            manifest = self.version_manager.get_manifest()

            console.print(f"🔄 [bold]Version Information[/bold]")
            console.print(f"====================")

            if manifest:
                console.print(f"📋 Current version: {manifest.current_version}")
                console.print(f"⏰ Last sync: {manifest.last_sync.strftime('%Y-%m-%d %H:%M:%S UTC')}")
                console.print(f"🔄 Last operation: {manifest.last_operation}")
            else:
                console.print(f"📋 Current version: Not yet uploaded to S3")

            console.print(f"📚 Total S3 versions: {len(versions)}")

            if len(versions) > 0:
                oldest = min(versions, key=lambda v: v.created_at)
                newest = max(versions, key=lambda v: v.created_at)
                days_range = (newest.created_at - oldest.created_at).days
                console.print(f"📅 Version history: {days_range} days ({oldest.created_at.strftime('%Y-%m-%d')} to {newest.created_at.strftime('%Y-%m-%d')})")
            else:
                console.print(f"💡 No S3 versions yet - upload data to create first version")

        except Exception as e:
            console.print(f"⚠️  Could not load version information: {e}", style="dim yellow")

    def _display_overall_status(self, df: pl.DataFrame):
        """Display overall dataset status."""
        total_combinations = df.height
        with_pricing = df.filter(pl.col("has_pricing")).height
        coverage_pct = (with_pricing / total_combinations * 100) if total_combinations > 0 else 0
        
        console.print(f"📊 [bold]Reference Dataset Status[/bold]")
        console.print(f"========================")
        console.print(f"📊 Total combinations: {total_combinations:,}")
        console.print(f"💰 With pricing data: {with_pricing:,}")
        console.print(f"📈 Coverage: {coverage_pct:.1f}%")
        console.print(f"💾 Data source: S3 (cached locally)")
    
    def _display_provider_summary(self, df: pl.DataFrame):
        """Display summary by provider."""
        provider_summary = df.group_by("cloud_provider").agg([
            pl.len().alias("total_combinations"),
            pl.col("has_pricing").sum().alias("with_pricing"),
            pl.col("record_count").sum().alias("total_records")
        ]).sort("total_combinations", descending=True)
        
        # Add coverage percentage
        provider_summary = provider_summary.with_columns([
            (pl.col("with_pricing") / pl.col("total_combinations") * 100).round(1).alias("coverage_pct")
        ])
        
        console.print(f"\n🏢 [bold]Top Providers (showing up to 10):[/bold]")
        
        # Convert to list for display
        provider_data = []
        for row in provider_summary.head(10).iter_rows(named=True):
            provider_data.append({
                "provider": row["cloud_provider"],
                "combinations": f"{row['total_combinations']:,}",
                "with_pricing": f"{row['with_pricing']:,}",
                "coverage": f"{row['coverage_pct']:.1f}%",
                "records": f"{row['total_records']:,}"
            })
        
        display_summary_table(
            console,
            "Provider Summary",
            provider_data,
            ["provider", "combinations", "with_pricing", "coverage", "records"]
        )
    
    def _display_coverage_details(self, df: pl.DataFrame):
        """Display coverage analysis."""
        # Coverage by provider type
        major_providers = ["AWS", "GCP", "Azure"]
        major_coverage = df.filter(pl.col("cloud_provider").is_in(major_providers))
        other_coverage = df.filter(~pl.col("cloud_provider").is_in(major_providers))
        
        console.print(f"\n📈 [bold]Coverage Analysis:[/bold]")
        
        if not major_coverage.is_empty():
            major_total = major_coverage.height
            major_with_pricing = major_coverage.filter(pl.col("has_pricing")).height
            major_pct = (major_with_pricing / major_total * 100) if major_total > 0 else 0
            console.print(f"   Major providers (AWS/GCP/Azure): {major_with_pricing:,}/{major_total:,} ({major_pct:.1f}%)")
        
        if not other_coverage.is_empty():
            other_total = other_coverage.height
            other_with_pricing = other_coverage.filter(pl.col("has_pricing")).height
            other_pct = (other_with_pricing / other_total * 100) if other_total > 0 else 0
            console.print(f"   Other providers: {other_with_pricing:,}/{other_total:,} ({other_pct:.1f}%)")
        
        # Service usage vs specific types
        service_usage = df.filter(pl.col("resource_type") == "service-usage")
        specific_types = df.filter(pl.col("resource_type") != "service-usage")
        
        if not service_usage.is_empty():
            su_total = service_usage.height
            su_pct = (su_total / df.height * 100) if df.height > 0 else 0
            console.print(f"   Generic 'service-usage': {su_total:,} ({su_pct:.1f}%)")
        
        if not specific_types.is_empty():
            st_total = specific_types.height
            st_pct = (st_total / df.height * 100) if df.height > 0 else 0
            console.print(f"   Specific resource types: {st_total:,} ({st_pct:.1f}%)")
    
    def _display_top_combinations(self, df: pl.DataFrame):
        """Display top combinations with pricing."""
        # Top combinations by cost
        top_cost = df.filter(pl.col("has_pricing") & pl.col("total_cost").is_not_null()) \
                    .sort("total_cost", descending=True) \
                    .head(5)
        
        if not top_cost.is_empty():
            console.print(f"\n💰 [bold]Top 5 Combinations by Cost:[/bold]")
            for row in top_cost.iter_rows(named=True):
                cost = row["total_cost"]
                console.print(f"   ${cost:,.2f} - {row['cloud_provider']}/{row['service']}/{row['usage_family']}")
        
        # Most common combinations
        top_common = df.sort("record_count", descending=True).head(5)
        
        if not top_common.is_empty():
            console.print(f"\n📊 [bold]Most Common Combinations:[/bold]")
            for row in top_common.iter_rows(named=True):
                count = row["record_count"]
                pricing_indicator = " ✓" if row["has_pricing"] else ""
                console.print(f"   {count} records - {row['cloud_provider']}/{row['service']}/{row['usage_family']}{pricing_indicator}")


@app.command()
def overview(
    verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose output")
):
    """Show dataset health, growth, and summary statistics."""
    try:
        # FAIL FAST: Validate AWS credentials before any work
        env_service.validate_aws_credentials_and_access()

        # Lazy initialization - create instance only when command executes
        DataStatusCommand().show_status(verbose)
    except ValueError as e:
        console.print(f"❌ {str(e)}")
        raise typer.Exit(1)