# Copyright (c) CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com

"""Clean, compact healthcheck display for V4 API responses."""

from typing import Any

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text

console = Console()


def get_status_icon(status: str) -> tuple[str, str]:
    """Get icon and color for a status."""
    if status == "healthy":
        return "✅", "green"
    elif status == "degraded":
        return "⚠️", "yellow"
    elif status == "unhealthy":
        return "❌", "red"
    return "❓", "dim"


def format_duration(ms: float) -> str:
    """Format duration in ms to human readable."""
    if ms < 1000:
        return f"{ms:.0f}ms"
    return f"{ms / 1000:.1f}s"


def create_header_panel(data: dict[str, Any]) -> Panel:
    """Create compact header with connection info and overall status."""
    metadata = data.get("metadata", {})
    if not isinstance(metadata, dict):
        metadata = {}

    # Overall status with large icon
    status = data.get("status", "unknown")
    score = data.get("overall_score", 0)
    if score is None:
        score = 0

    icon, color = get_status_icon(status)

    status_text = Text()
    status_text.append(f"{icon} ", style=f"bold {color}")
    status_text.append(f"{status.upper()} ", style=f"bold {color}")
    status_text.append(f"({score:.0f}%)", style=color)

    # Create two-column layout
    table = Table.grid(padding=(0, 2))
    table.add_column(ratio=2)
    table.add_column(ratio=1)

    # Left side - connection info
    left = Table.grid(padding=0)
    left.add_column(style="cyan", justify="right", width=15)
    left.add_column(style="white")

    conn_id = data.get("connection_id", "N/A")
    org_id = metadata.get("cz_organization_id", "N/A") if isinstance(metadata, dict) else "N/A"
    provider = metadata.get("cloud_provider", "N/A") if isinstance(metadata, dict) else "N/A"
    conn_types = metadata.get("connection_types", []) if isinstance(metadata, dict) else []

    left.add_row("Connection:", conn_id)
    left.add_row("Organization:", org_id)
    left.add_row("Provider:", str(provider).upper() if provider else "N/A")
    left.add_row("Types:", ", ".join(conn_types) if isinstance(conn_types, list) else str(conn_types))

    # Right side - status
    right = Panel(status_text, border_style=color, padding=(1, 2))

    table.add_row(left, right)

    return Panel(table, title="[bold]Connection Healthcheck[/]", border_style="blue")


def create_summary_panel(data: dict[str, Any]) -> Panel:
    """Create compact summary of all checks."""
    summary = data.get("summary", {})
    if not isinstance(summary, dict):
        summary = {}

    checks = data.get("checks", [])
    if not isinstance(checks, list):
        checks = []

    table = Table(show_header=False, box=None, padding=(0, 2))
    table.add_column(width=30)
    table.add_column(width=12, justify="center")
    table.add_column(width=10, justify="right")

    for check in checks:
        if not isinstance(check, dict):
            continue

        name = check.get("name", "unknown")
        name = name.replace("_", " ").title() if isinstance(name, str) else str(name)

        status = check.get("status", "unknown")
        duration = check.get("duration_ms", 0)
        if duration is None:
            duration = 0

        icon, color = get_status_icon(status)

        name_text = Text(name, style="white")
        status_text = Text(f"{icon} {status}", style=color)
        duration_text = Text(format_duration(float(duration)), style="dim")

        table.add_row(name_text, status_text, duration_text)

    # Add summary line
    table.add_row("", "", "")
    summary_text = Text()
    summary_text.append(f"✅ {summary.get('healthy_count', 0) or 0} ", style="green")
    if (summary.get("degraded_count", 0) or 0) > 0:
        summary_text.append(f"⚠️ {summary.get('degraded_count', 0)} ", style="yellow")
    if (summary.get("unhealthy_count", 0) or 0) > 0:
        summary_text.append(f"❌ {summary.get('unhealthy_count', 0)} ", style="red")

    table.add_row(Text(f"{summary.get('total_checks', 0) or 0} Total Checks", style="bold"), summary_text, "")

    return Panel(table, title="[cyan]Check Summary[/]", border_style="cyan")


def create_connectivity_panel(check: dict[str, Any]) -> Panel:
    """Create compact provider connectivity panel."""
    details = check.get("details", {})
    if not isinstance(details, dict):
        details = {}

    final_id = details.get("final_identity", {})
    if not isinstance(final_id, dict):
        final_id = {}

    table = Table.grid(padding=0)
    table.add_column(style="dim", width=13)
    table.add_column(style="white", no_wrap=False, overflow="fold")

    table.add_row("Account:", final_id.get("account_id", "N/A"))
    table.add_row("Region:", details.get("region", "N/A"))

    # Role chain summary
    role_chain = details.get("role_chain", {})
    if isinstance(role_chain, dict) and role_chain:
        table.add_row("", "")
        table.add_row("Chain:", f"{role_chain.get('initial_account')} → {role_chain.get('reactor_account')} → {role_chain.get('customer_account')}")
        if role_chain.get("external_id_used"):
            table.add_row("External ID:", Text("✅ Used", style="green"))

        # Show complete customer role ARN
        customer_role_arn = role_chain.get("customer_role_arn")
        if customer_role_arn:
            table.add_row("Customer Role:", Text(customer_role_arn, no_wrap=False, overflow="fold"))

    icon, color = get_status_icon(check.get("status", "unknown"))
    return Panel(table, title=f"[{color}]{icon} Provider Connectivity[/]", border_style=color)


def create_permissions_panel(check: dict[str, Any]) -> Panel:
    """Create compact permissions panel."""
    details = check.get("details", {})
    if not isinstance(details, dict):
        details = {}

    required = details.get("required_permissions", [])
    if not isinstance(required, list):
        required = []

    verified = details.get("verified_permissions", [])
    if not isinstance(verified, list):
        verified = []

    missing_req = details.get("missing_required_permissions", [])
    if not isinstance(missing_req, list):
        missing_req = []

    missing_opt = details.get("missing_optional_permissions", [])
    if not isinstance(missing_opt, list):
        missing_opt = []

    table = Table.grid(padding=0)
    table.add_column(style="dim", width=12)
    table.add_column(no_wrap=False, overflow="fold")

    # Required permissions status
    if missing_req:
        table.add_row("Required:", Text(f"❌ {len(missing_req)} missing", style="red"))
        for perm in missing_req[:3]:
            table.add_row("", Text(f"• {perm}", style="dim red"))
        if len(missing_req) > 3:
            table.add_row("", Text(f"  ... +{len(missing_req) - 3} more", style="dim"))
    else:
        table.add_row("Required:", Text(f"✅ {len(required)} verified", style="green"))
        for perm in required[:3]:
            table.add_row("", Text(f"• {perm}", style="dim green"))
        if len(required) > 3:
            table.add_row("", Text(f"  ... +{len(required) - 3} more", style="dim"))

    # Optional permissions
    if missing_opt:
        table.add_row("Optional:", Text(f"⚠️ {len(missing_opt)} missing", style="yellow"))
        for perm in missing_opt[:3]:
            table.add_row("", Text(f"• {perm}", style="dim yellow"))
        if len(missing_opt) > 3:
            table.add_row("", Text(f"  ... +{len(missing_opt) - 3} more", style="dim"))

    icon, color = get_status_icon(check.get("status", "unknown"))
    return Panel(table, title=f"[{color}]{icon} Permissions[/]", border_style=color)


def create_cur_and_data_collection_panel(check: dict[str, Any]) -> Panel:
    """Create CUR health panel showing up to 3 CURs side by side with row titles."""
    details = check.get("details", {})
    if not isinstance(details, dict):
        details = {}

    visible_curs = details.get("visible_curs", [])
    if not isinstance(visible_curs, list):
        visible_curs = []

    total_curs = details.get("total_curs_found", 0)
    healthy_curs = details.get("healthy_curs_count", 0)

    if not visible_curs:
        return Panel(Text("No CURs found", style="dim"), title="[cyan]CUR Health[/]", border_style="cyan")

    # Sort CURs to show healthy ones first
    sorted_curs = sorted(visible_curs, key=lambda cur: (not cur.get("is_healthy", False), cur.get("name", "")))

    # Process CURs in groups of 3 for side-by-side display
    all_rows = []

    for row_start in range(0, len(sorted_curs), 3):
        row_curs = sorted_curs[row_start : row_start + 3]

        # Create table with row titles + data columns
        row_table = Table.grid(padding=(0, 0))
        row_table.add_column(style="cyan", width=18)  # Row titles

        # Add columns for each CUR (value + separator)
        for _ in range(len(row_curs)):
            row_table.add_column(style="white", no_wrap=False, overflow="fold")
            row_table.add_column(width=1)  # Separator

        # Collect data for each CUR in this row
        cur_data_list = []
        for cur in row_curs:
            if not isinstance(cur, dict):
                continue

            name = cur.get("name", "Unknown")
            is_active = cur.get("is_active", False)
            is_healthy = cur.get("is_healthy", False)
            is_accessible = cur.get("is_accessible", False)
            status = cur.get("status", "unknown")

            raw_config = cur.get("raw_config", {})
            health_details = cur.get("health_details", {})

            status_icon, status_color = get_status_icon(status)

            cur_data_list.append(
                {
                    "report_name": (f"{name} ★" if is_active else name, "bold yellow" if is_active else "bold white"),
                    "status": (f"{status_icon} {status}", status_color),
                    "usable": ("✅" if is_accessible and is_healthy else "❌", "green" if is_accessible and is_healthy else "red"),
                    "healthy": ("✅" if is_healthy else "❌", "green" if is_healthy else "red"),
                    "reason": health_details.get("reason", "—"),
                    "time_unit": raw_config.get("TimeUnit", "—"),
                    "format": raw_config.get("Format", "—"),
                    "compression": raw_config.get("Compression", "—"),
                    "s3_bucket": raw_config.get("S3Bucket", "—"),
                    "s3_prefix": raw_config.get("S3Prefix", "—"),
                    "s3_region": raw_config.get("S3Region", "—"),
                    "bucket_ok": ("✅" if is_accessible else "❌", "green" if is_accessible else "red"),
                    "schema": ", ".join(raw_config.get("AdditionalSchemaElements", [])) or "—",
                    "artifacts": ", ".join(raw_config.get("AdditionalArtifacts", [])) or "—",
                    "refresh": "Yes" if raw_config.get("RefreshClosedReports") else "No",
                    "versioning": (
                        "NEW"
                        if raw_config.get("ReportVersioning") == "CREATE_NEW_REPORT"
                        else "OVERWRITE"
                        if raw_config.get("ReportVersioning") == "OVERWRITE_REPORT"
                        else raw_config.get("ReportVersioning", "—")
                    ),
                    "view_arn": raw_config.get("BillingViewArn", "—"),
                }
            )

        # Define all rows
        rows = [
            ("Report Name:", "report_name"),
            ("Status:", "status"),
            ("Usable:", "usable"),
            ("Healthy:", "healthy"),
            ("Reason:", "reason"),
            ("Time Unit:", "time_unit"),
            ("Format:", "format"),
            ("Compression:", "compression"),
            ("S3 Bucket:", "s3_bucket"),
            ("S3 Prefix:", "s3_prefix"),
            ("S3 Region:", "s3_region"),
            ("Bucket OK:", "bucket_ok"),
            ("Schema:", "schema"),
            ("Artifacts:", "artifacts"),
            ("Refresh:", "refresh"),
            ("Versioning:", "versioning"),
            ("View ARN:", "view_arn"),
        ]

        # Build each row
        for row_label, row_key in rows:
            row_cells = [Text(row_label, style="cyan")]

            for cur_data in cur_data_list:
                value = cur_data.get(row_key)

                if value == "—" or value is None:
                    cell_text = Text("—", style="dim")
                elif isinstance(value, tuple):
                    text, style = value
                    cell_text = Text(text, style=style, no_wrap=False, overflow="fold")
                else:
                    cell_text = Text(str(value), no_wrap=False, overflow="fold")

                row_cells.append(cell_text)
                row_cells.append(Text("│", style="dim"))

            row_table.add_row(*row_cells)

        all_rows.append(row_table)

    # Combine all row groups
    if len(all_rows) == 1:
        final_content = all_rows[0]
    else:
        combined = Table.grid(padding=0)
        combined.add_column()
        for i, row in enumerate(all_rows):
            combined.add_row(row)
            if i < len(all_rows) - 1:
                combined.add_row(Text(""))
        final_content = combined

    icon, color = get_status_icon(check.get("status", "unknown"))
    title = f"[{color}]{icon} CUR Health ({healthy_curs}/{total_curs} usable)[/]"
    return Panel(final_content, title=title, border_style=color)


def create_data_collection_panel(check: dict[str, Any]) -> Panel:
    """Create data collection panel showing metrics from active CUR."""
    details = check.get("details", {})
    if not isinstance(details, dict):
        details = {}

    # Find the active CUR
    visible_curs = details.get("visible_curs", [])
    if not isinstance(visible_curs, list):
        visible_curs = []

    active_cur_data = None
    for cur in visible_curs:
        if isinstance(cur, dict) and cur.get("is_active"):
            active_cur_data = cur
            break

    if not active_cur_data:
        return Panel(Text("No active CUR data available", style="dim"), title="[cyan]Data Collection[/]", border_style="cyan")

    # Create two-column layout
    main_layout = Table.grid(padding=(0, 3))
    main_layout.add_column()
    main_layout.add_column()

    # Left column - Collection details
    left_table = Table.grid(padding=0)
    left_table.add_column(style="cyan", width=20)
    left_table.add_column(style="white", no_wrap=False, overflow="fold")

    left_table.add_row(Text("Collection Details:", style="bold"), "")

    data_collection = active_cur_data.get("data_collection", {})
    if isinstance(data_collection, dict):
        left_table.add_row("Bucket:", active_cur_data.get("raw_config", {}).get("S3Bucket", "N/A"))
        left_table.add_row("Report:", active_cur_data.get("name", "N/A"))

        # Access test details
        access_test = active_cur_data.get("access_test_details", {})
        if isinstance(access_test, dict):
            manifest_read = access_test.get("manifest_read", {})
            if isinstance(manifest_read, dict):
                manifest_status = manifest_read.get("status", "unknown")
                manifest_icon = "✅" if manifest_status == "success" else "❌"
                left_table.add_row("Manifest Found:", Text(manifest_icon, style="green" if manifest_status == "success" else "red"))

        report_count = data_collection.get("report_count", 0)
        left_table.add_row("Recent File Count:", f"{report_count:,}")

        from datetime import datetime

        last_collection = data_collection.get("last_collection_time")
        if last_collection:
            try:
                dt = datetime.fromisoformat(last_collection.replace("Z", "+00:00"))
                left_table.add_row("Last Collection:", dt.strftime("%Y-%m-%d %H:%M"))
            except Exception:
                left_table.add_row("Last Collection:", last_collection)

        # Latest file
        latest_file = data_collection.get("latest_file_path")
        if latest_file:
            left_table.add_row("Latest File:", Text(latest_file, no_wrap=False, overflow="fold"))

    # Right column - CUR Statistics
    right_table = Table.grid(padding=0)
    right_table.add_column(style="cyan", width=22)
    right_table.add_column(style="white", no_wrap=False, overflow="fold")

    cur_stats = active_cur_data.get("cur_stats", {})
    if isinstance(cur_stats, dict) and cur_stats:
        right_table.add_row(Text("CUR Statistics:", style="bold"), "")

        cur_manifest = cur_stats.get("cur_current_manifest")
        if cur_manifest:
            right_table.add_row("Current Manifest:", Text(cur_manifest, no_wrap=False, overflow="fold"))

        from datetime import datetime

        cur_drop = cur_stats.get("cur_drop_datetime")
        if cur_drop:
            try:
                dt = datetime.fromisoformat(cur_drop.replace("Z", "+00:00"))
                right_table.add_row("CUR Drop Time:", dt.strftime("%Y-%m-%d %H:%M"))
            except Exception:
                right_table.add_row("CUR Drop Time:", cur_drop)

        report_count = cur_stats.get("cur_report_count")
        if report_count is not None:
            right_table.add_row("Report Count:", f"{report_count:,}")

        ingest_time = cur_stats.get("cur_ingest_datetime")
        if ingest_time:
            try:
                dt = datetime.fromisoformat(ingest_time.replace("Z", "+00:00"))
                right_table.add_row("Ingest Time:", dt.strftime("%Y-%m-%d %H:%M"))
            except Exception:
                right_table.add_row("Ingest Time:", ingest_time)
        elif ingest_time is None and "cur_ingest_datetime" in cur_stats:
            right_table.add_row("Ingest Time:", Text("Not yet ingested", style="dim"))

        avg_current = cur_stats.get("avg_cur_drop_time_current")
        if avg_current:
            right_table.add_row("Avg Drop (current):", f"{avg_current:.2f}h")

        avg_previous = cur_stats.get("avg_cur_drop_time_previous")
        if avg_previous:
            right_table.add_row("Avg Drop (previous):", f"{avg_previous:.2f}h")

        manifest_dt = cur_stats.get("manifest_datetime")
        if manifest_dt:
            try:
                dt = datetime.fromisoformat(manifest_dt.replace("Z", "+00:00"))
                right_table.add_row("Manifest Updated:", dt.strftime("%Y-%m-%d %H:%M"))
            except Exception:
                right_table.add_row("Manifest Updated:", manifest_dt)
    else:
        right_table.add_row(Text("CUR Statistics:", style="bold"), "")
        right_table.add_row("", Text("No statistics available", style="dim"))

    main_layout.add_row(left_table, right_table)

    icon, color = get_status_icon(check.get("status", "unknown"))
    return Panel(main_layout, title=f"[{color}]{icon} Data Collection[/]", border_style=color)


def display_healthcheck(data: dict[str, Any]) -> None:
    """Display healthcheck in compact, multi-panel layout."""
    console.print()

    # Header spans full width
    console.print(create_header_panel(data))
    console.print()

    # Get all checks
    checks_list = data.get("checks", [])
    checks = {}
    for check in checks_list:
        if isinstance(check, dict) and "name" in check:
            checks[check["name"]] = check

    # Row 1: Summary + Provider Connectivity
    layout1 = Table.grid(padding=(0, 2))
    layout1.add_column(ratio=1)
    layout1.add_column(ratio=1)

    layout1.add_row(create_summary_panel(data), create_connectivity_panel(checks.get("provider_connectivity", {})))
    console.print(layout1)
    console.print()

    # Row 2: Permissions + Data Collection
    layout2 = Table.grid(padding=(0, 2))
    layout2.add_column(ratio=1)
    layout2.add_column(ratio=1)

    layout2.add_row(
        create_permissions_panel(checks.get("permissions_check", {})), create_data_collection_panel(checks.get("cur_and_data_collection", {}))
    )
    console.print(layout2)
    console.print()

    # Row 3: CUR Health (full width)
    console.print(create_cur_and_data_collection_panel(checks.get("cur_and_data_collection", {})))
    console.print()
