# Copyright (c) 2025 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
#

import json

from rich import box
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.tree import Tree

from src.api.v4_connections import get_connection, get_connection_raw, get_connections, get_connections_for_org
from src.constants import NO_ACCOUNT_NAME, NO_ORG_NAME
from src.features.organizations import get_organization_data
from src.utils.console import eprint, format_account_stage
from src.utils.data import looks_like_a_connection_id

console = Console(width=160, highlight=False)


# Removed duplicated __format_account_stage function - now using the centralized version in utils.interface


def display_organization_summary(org_id: str, org_details: dict, connections: list[dict] | None = None) -> None:
    """
    Display organization summary information (reusable across commands).

    This function displays the organization header and details table showing
    org metadata, connection counts, providers, spending, and capabilities.

    Args:
        org_id: Organization ID
        org_details: Dictionary or Pydantic model containing organization details from V4 API
        connections: Optional list of per-connection dicts to enrich summary with health/autolink detail
    """
    # Handle both Pydantic models and dicts
    if hasattr(org_details, "model_dump"):
        org_details = org_details.model_dump()

    org_name = org_details.get("cz_organization_name", NO_ORG_NAME)

    # Create header
    header = Panel(
        f"[bold cyan]{org_name}[/] ([cyan]{org_id}[/])",
        title="Organization Info",
        title_align="left",
        border_style="cyan",
    )
    console.print(header)

    # Create details table
    details_table = Table(box=box.ROUNDED, show_header=False, padding=(0, 2), width=None)
    details_table.add_column("Property", style="bold blue", justify="right")
    details_table.add_column("Value", style="white")

    # Add organization details using exact V4 API field names
    details_table.add_row("ID", org_details.get("cz_organization_id"))
    details_table.add_row("Name", org_details.get("cz_organization_name"))
    details_table.add_row(
        "Status", "[green]Enabled[/]" if org_details.get("organization_enabled") else "[red]Disabled[/]"
    )
    details_table.add_row("Stage", format_account_stage(org_details.get("organization_stage")))
    details_table.add_row("Website", org_details.get("website") or "N/A")
    details_table.add_row("Created", org_details.get("created") or "Unknown")

    # Use connections_summary data (new simplified schema)
    connections_summary = org_details.get("connections_summary", {})

    # Connection counts
    if total_connections := connections_summary.get("total_connections"):
        details_table.add_row("Total Connections", str(total_connections))

    if enabled_connections := connections_summary.get("total_enabled_connections"):
        if str(enabled_connections) != str(total_connections):
            details_table.add_row("Enabled Connections", str(enabled_connections))

    # Provider information
    if enabled_providers := connections_summary.get("enabled_providers"):
        details_table.add_row("Active Providers", ", ".join(enabled_providers))

    if all_providers := connections_summary.get("all_providers"):
        if all_providers != enabled_providers:
            details_table.add_row("All Providers", ", ".join(all_providers))

    # Spending information
    if total_spend := connections_summary.get("total_billed_spend_30_days"):
        try:
            spend_value = float(total_spend) if total_spend else 0.0
            if spend_value > 0:
                details_table.add_row("30-Day AWS Spend", f"${spend_value:,.2f}")
        except (ValueError, TypeError):
            pass

    # Connection type breakdown from aggregate counts
    if type_counts := connections_summary.get("type_counts"):
        if isinstance(type_counts, dict) and type_counts:
            type_parts = [f"{k}: {v}" for k, v in sorted(type_counts.items())]
            details_table.add_row("Connection Types", ", ".join(type_parts))

    # Per-connection intelligence (when caller provides connection detail)
    if connections:
        healthy_count = sum(1 for c in connections if c.get("is_healthy"))
        details_table.add_row("Healthy Connections", f"{healthy_count} of {len(connections)}")

        # Provider breakdown
        provider_counts: dict[str, int] = {}
        for c in connections:
            provider = c.get("provider", "Unknown")
            provider_counts[provider] = provider_counts.get(provider, 0) + 1
        for provider, count in sorted(provider_counts.items()):
            if provider != "Unknown":
                details_table.add_row(f"{provider} Connections", str(count))

        # Auto-link status from per-connection detail (auto_link_enabled is a root-level field)
        auto_link_enabled = any(c.get("auto_link_enabled", False) for c in connections)
        details_table.add_row("Autolink", "[green]Yes[/]" if auto_link_enabled else "[red]No[/]")
    else:
        # Fall back to aggregate auto_link_enabled from connections_summary
        if connections_summary.get("auto_link_enabled"):
            details_table.add_row("Autolink", "[green]Yes[/]")

    # Show metadata
    if last_updated := org_details.get("last_updated"):
        details_table.add_row("Last Updated", last_updated)

    if first_seen := org_details.get("first_seen"):
        details_table.add_row("First Seen", first_seen)

    if record_sources := org_details.get("record_sources"):
        if record_sources and isinstance(record_sources, list):
            details_table.add_row("Data Sources", ", ".join(record_sources))

    console.print(details_table)


def display_organization_info(arguments, organization_data):
    """Display detailed information about a single organization."""
    # Check if raw JSON output is requested (actual API response) - must be first
    # because raw mode returns full API response structure, not org_id -> org dict
    if arguments.get("--raw"):
        import json

        # organization_data is the full API response when --raw is used
        print(json.dumps(organization_data, indent=2, default=str))
        return

    if len(organization_data.keys()) > 1:
        print("Found multiple organizations matching your query. Please refine your search.")
        for org_id, org_details in organization_data.items():
            # Handle both Pydantic models and dicts
            if hasattr(org_details, "model_dump"):
                org_name = org_details.cz_organization_name or NO_ORG_NAME
            else:
                org_name = org_details.get("cz_organization_name", NO_ORG_NAME)
            print(f"  - {org_name} ({org_id})")
        return

    # Check if formatted dict output is requested
    if arguments.get("--json"):
        from rich.pretty import pprint

        for org_id, org_details in organization_data.items():
            if hasattr(org_details, "model_dump"):
                pprint(org_details.model_dump())
            else:
                pprint(org_details)
        return

    for org_id, org_details in organization_data.items():
        # Fetch per-connection data via dedicated API
        from src.features.connections.list import display_connections_for_organization

        connections_list = get_connections_for_org(org_id, debug=arguments.get("--debug", False))

        # Build connection dicts for display
        connection_dicts = []
        connection_data = {}
        if connections_list:
            for conn in connections_list:
                conn_dict = conn.model_dump() if hasattr(conn, "model_dump") else conn
                conn_dict["is_connected"] = conn_dict.get("enabled", True) and conn_dict.get("is_healthy", True)
                connection_dicts.append(conn_dict)
                connection_data[conn_dict.get("connection_id", "")] = conn_dict

        # Display organization summary with per-connection intelligence
        display_organization_summary(org_id, org_details, connections=connection_dicts or None)

        if connection_data:
            display_connections_for_organization(org_id, organization_data, connection_data, show_header=False)

        # Add link to web UI
        console.print(
            f"\n[cyan]Web Console:[/] [link=https://app.cloudzero.com?organization_id={org_id}]https://app.cloudzero.com?organization_id={org_id}[/link]\n"
        )


def display_connection_info(arguments, connection_id, organization_data=None):
    """Display detailed information about a single connection."""
    # Variables to track connection discovery
    connection_data = None
    found = False
    org_id = None
    org_name = NO_ORG_NAME

    # Debug output
    debug_mode = arguments.get("--debug", False)
    if debug_mode:
        eprint(f"DEBUG: Looking up connection info for ID or name '{connection_id}'")

    # Handle --raw: fetch and display the unmodified API response body
    if arguments.get("--raw"):
        try:
            with console.status("[cyan]Fetching raw connection data..."):
                raw_data = get_connection_raw(connection_id, debug=debug_mode)
            print(json.dumps(raw_data, indent=2, default=str))
        except ValueError as e:
            console.print(f"[red]Error:[/] {e}")
        except Exception as e:
            console.print(f"[red]Error:[/] Failed to fetch connection: {e}")
        return

    # Direct lookup of connection using get_connection API
    with console.status("[cyan]Finding connection info..."):
        # First try direct connection lookup by ID - this is the efficient way
        if debug_mode:
            eprint("DEBUG: Fetching connection data directly with get_connection")
        try:
            connection_v4 = get_connection(connection_id, debug=debug_mode)
            if connection_v4:
                # Successfully retrieved connection directly
                found = True
                org_id = connection_v4.cz_organization_id
                # Store the actual connection data for later use
                connection_data = {"direct_connection": connection_v4.model_dump()}

                if debug_mode:
                    eprint(f"DEBUG: Successfully retrieved connection {connection_id}")
                    eprint("DEBUG: Connection found directly using get_connection API")
                    eprint(f"DEBUG: Organization ID: {org_id}")

                # If we have organization data, try to get the org name
                if organization_data and org_id and org_id in organization_data:
                    org_name = organization_data[org_id].get("cz_organization_name", NO_ORG_NAME)
            else:
                connection_data = None
                if debug_mode:
                    eprint("DEBUG: get_connection returned None - connection not found or no access")
        except Exception as e:
            connection_data = None
            if debug_mode:
                eprint(f"DEBUG: Exception in get_connection: {e}")

        # Fallback: Try name-based search using get_connections if direct lookup failed
        if not found:
            if debug_mode:
                eprint(
                    f"DEBUG: Direct lookup failed, trying name-based search with get_connections(name='{connection_id}')"
                )

            try:
                matching_connections = get_connections(name=connection_id, enabled_only=False, debug=debug_mode)

                if debug_mode:
                    eprint(f"DEBUG: Name search returned {len(matching_connections)} results")

                if len(matching_connections) == 1:
                    # Exactly one match - display it
                    connection_v4 = matching_connections[0]
                    found = True
                    org_id = connection_v4.cz_organization_id
                    connection_data = {"direct_connection": connection_v4.model_dump()}

                    if debug_mode:
                        eprint(f"DEBUG: Found single matching connection: {connection_v4.connection_id}")

                    # If we have organization data, try to get the org name
                    if organization_data and org_id and org_id in organization_data:
                        org_name = organization_data[org_id].get("cz_organization_name", NO_ORG_NAME)

                elif len(matching_connections) > 1:
                    # Multiple matches - show list and ask user to be more specific
                    console.print(f"\n[yellow]Multiple connections found matching '[cyan]{connection_id}[/cyan]'[/]\n")
                    console.print(
                        f"Found [bold]{len(matching_connections)}[/] connections. Please specify the exact connection ID:\n"
                    )

                    # Create a table to display matches
                    table = Table(show_header=True, header_style="bold cyan", box=None, padding=(0, 2))
                    table.add_column("Connection ID", style="yellow")
                    table.add_column("Name", style="bright_white")
                    table.add_column("Provider", style="cyan")
                    table.add_column("Organization ID", style="dim")

                    for conn in matching_connections:
                        conn_dict = conn.model_dump()
                        table.add_row(
                            conn_dict.get("connection_id", "Unknown"),
                            conn_dict.get("connection_name") or NO_ACCOUNT_NAME,
                            conn_dict.get("provider", "Unknown"),
                            conn_dict.get("cz_organization_id", "Unknown"),
                        )

                    console.print(table)
                    console.print("\n[cyan]💡 To view a specific connection:[/]")
                    console.print("  [white]czops connection info <CONNECTION_ID>[/]\n")
                    return
                else:
                    # No matches at all
                    if debug_mode:
                        eprint("DEBUG: Name search returned no results")

            except Exception as search_error:
                if debug_mode:
                    eprint(f"DEBUG: Exception during name-based search: {search_error}")

        # Fallback: try to find the organization that owns this connection if direct lookup failed
        if not found and (all_orgs := organization_data):
            if debug_mode:
                eprint("DEBUG: Direct lookup failed, falling back to search through organizations")

            for o_id, org_details in all_orgs.items():
                # Check if this connection belongs to this organization
                if connection_id in org_details.get("connections", []):
                    org_id = o_id
                    org_name = org_details.get("cz_organization_name", NO_ORG_NAME)

                    if debug_mode:
                        eprint(f"DEBUG: Found connection in organization {org_id}")

                    # Get detailed connection data using the found organization
                    try:
                        connections_list = get_connections_for_org(org_id, debug=debug_mode)
                        # Convert to legacy format
                        connection_data = {"data": {org_id: {conn["connection_id"]: conn for conn in connections_list}}}
                        if connection_id in connection_data.get("data", {}).get(org_id, {}):
                            found = True
                            break
                    except Exception as e:
                        # Continue searching if this organization fails
                        if debug_mode:
                            eprint(f"[yellow]DEBUG: Failed to get org {org_id}: {e}[/]")
                        continue

        # Last resort: try to fetch all orgs if we don't have them and haven't found the connection yet
        if not found and not organization_data:
            if debug_mode:
                eprint("DEBUG: No organization data provided, fetching all organizations")

            # Only fetch if we don't already have the data
            org_args = {"--all": True}
            all_orgs = get_organization_data(None, org_args)

            if all_orgs:
                for o_id, org_details in all_orgs.items():
                    # Check if this connection belongs to this organization
                    if connection_id in org_details.get("connections", []):
                        org_id = o_id
                        org_name = org_details.get("cz_organization_name", NO_ORG_NAME)

                        if debug_mode:
                            eprint(f"DEBUG: Found connection in organization {org_id}")

                        # Get detailed connection data
                        try:
                            connections_list = get_connections_for_org(org_id, debug=debug_mode)
                            # Convert to legacy format
                            connection_data = {
                                "data": {org_id: {conn["connection_id"]: conn for conn in connections_list}}
                            }
                            if connection_id in connection_data.get("data", {}).get(org_id, {}):
                                found = True
                                break
                        except Exception as e:
                            # Continue searching if this organization fails
                            if debug_mode:
                                eprint(f"[yellow]DEBUG: Failed to get org {org_id}: {e}[/]")
                            continue

    if not found or not connection_data:
        console.print(f"[red]Error:[/] Connection '{connection_id}' not found or you don't have access to it.")
        return

    # Get the connection details - handle both direct connection format and legacy format
    connection = None

    # First, check if we have a direct connection (from get_connection API)
    if "direct_connection" in connection_data:
        connection = connection_data["direct_connection"]
        if debug_mode:
            eprint("DEBUG: Using direct connection data")
    # Fallback: check legacy format
    elif org_id and "data" in connection_data:
        connection = connection_data.get("data", {}).get(org_id, {}).get(connection_id)
        if debug_mode:
            eprint("DEBUG: Using legacy format connection data from org-specific lookup")
    # Last fallback: try to find in any organization (there should only be one)
    elif "data" in connection_data:
        for org_data in connection_data.get("data", {}).values():
            if connection_id in org_data:
                connection = org_data[connection_id]
                if debug_mode:
                    eprint("DEBUG: Found connection in legacy format from fallback search")
                break

    if not connection:
        console.print("[red]Error:[/] Connection info not available.")
        if debug_mode:
            eprint(f"DEBUG: Connection data structure: {connection_data}")
            eprint(f"DEBUG: Could not find connection {connection_id} in any format")
        return

    # Get org info - fetch organization data if not provided
    if organization_data is None and org_id:
        # Fetch organization data using the org_id from connection
        try:
            organization_data = get_organization_data(org_id, {"info": True})
        except Exception:
            organization_data = None

    org_name = (
        NO_ORG_NAME
        if organization_data is None
        else organization_data.get(org_id, {}).get("cz_organization_name", NO_ORG_NAME)
    )

    # --raw is handled at the top of this function (bypasses all lookup logic)

    # Check if formatted JSON output is requested (human-readable)
    if arguments.get("--json"):
        connection_with_org = {"organization_id": org_id, "cz_organization_name": org_name, "connection": connection}
        print(json.dumps(connection_with_org, indent=2))
        return

    # --- Data Extraction ---
    # Per-type config (new schema: types.COST, types.RESOURCE, etc.)
    types_config = connection.get("types") or {}

    # Legacy flat dict (fallback when types not available)
    conn_details = connection.get("connection_details") or {}

    # Build conn_details from types dict if connection_details is empty
    if not conn_details and types_config:
        merged: dict = {}
        for type_name in ["COST", "RESOURCE", "METRICS", "DATA"]:
            tc = types_config.get(type_name, {})
            type_data = tc.get("data", {})
            type_method = tc.get("connection_method", {})
            for k, v in type_data.items():
                if k not in merged and v is not None:
                    merged[k] = v
            for k, v in type_method.items():
                if k not in merged and v is not None:
                    merged[k] = v
        conn_details = merged

    def get_field(key, default=None):
        """Get field from connection_details first, then top-level."""
        val = conn_details.get(key)
        if val is not None:
            return val
        val = connection.get(key)
        if val is not None:
            return val
        return default

    def fmt(val):
        """Format a value for display."""
        if val is None or val == "":
            return "[dim]--[/]"
        if isinstance(val, bool):
            return "[green]Yes[/]" if val else "[red]No[/]"
        if isinstance(val, list):
            if not val:
                return "[dim]--[/]"
            if len(val) <= 5:
                return ", ".join(str(item) for item in val)
            return f"{len(val)} items"
        return str(val)

    def fmt_status(val, true_text, false_text):
        """Format a boolean as a colored status label."""
        return f"[green]{true_text}[/]" if val else f"[red]{false_text}[/]"

    def fmt_ts(val):
        """Format an ISO timestamp to shorter readable form."""
        if not val:
            return "[dim]--[/]"
        s = str(val)
        if "T" in s:
            date_part = s.split("T")[0]
            time_part = s.split("T")[1].split(".")[0].split("+")[0]
            return f"{date_part} {time_part} UTC"
        return s

    def make_panel(title: str, rows: list[tuple[str, str]], border: str = "dim") -> Panel:
        """Create a titled panel with key-value rows."""
        tbl = Table(box=None, show_header=False, padding=(0, 1), expand=True)
        tbl.add_column("K", style="bold blue", justify="right", no_wrap=True, width=18)
        tbl.add_column("V", style="white", overflow="fold", no_wrap=False)
        for label, value in rows:
            tbl.add_row(label, value)
        return Panel(tbl, title=f"[bold]{title}[/]", title_align="left", border_style=border, expand=True)

    def two_column_row(left: Panel, right: Panel):
        """Print two panels side by side."""
        grid = Table.grid(expand=True)
        grid.add_column(ratio=1)
        grid.add_column(ratio=1)
        grid.add_row(left, right)
        console.print(grid)

    # --- Header ---
    conn_name = connection.get("connection_name", NO_ACCOUNT_NAME)
    actual_conn_id = connection.get("connection_id", connection_id)

    # Build coalesced type description from connection_types[]
    conn_types = connection.get("connection_types", [])
    conn_type_display = ", ".join(conn_types) if conn_types else "Unknown"

    console.print(
        Panel(
            f"[bold cyan]{conn_name}[/] ([cyan]{actual_conn_id}[/]) in [bold blue]{org_name}[/]",
            title="Connection Info",
            title_align="left",
            border_style="cyan",
        )
    )

    # =====================================================================
    # Row 1: Overview + Status
    # =====================================================================
    home_region = get_field("connection_region")
    active_regions = connection.get("active_regions") or []

    overview_rows = [
        ("Connection ID", actual_conn_id),
        ("Name", conn_name),
        ("Organization", org_name),
        ("Org ID", str(org_id) if org_id else "[dim]--[/]"),
        ("Provider", connection.get("provider", "Unknown")),
        ("Types", conn_type_display),
        ("Region", fmt(home_region)),
        ("Active Regions", fmt(active_regions)),
        ("Inactive Regions", fmt(connection.get("inactive_regions"))),
        ("Provisioning", fmt(get_field("provisioning_process"))),
        ("Record Sources", fmt(connection.get("record_sources"))),
    ]

    status_rows = [
        ("Connected", fmt_status(connection.get("is_connected", False), "Yes", "No")),
        ("Enabled", fmt_status(connection.get("enabled", True), "Yes", "No")),
        ("Healthy", fmt_status(connection.get("is_healthy", False), "Yes", "No")),
        ("Cost Connection", fmt_status("COST" in conn_types, "Yes", "No")),
        ("Resource Connection", fmt_status("RESOURCE" in conn_types, "Yes", "No")),
        ("Billing", fmt_status(connection.get("billing_enabled", False), "Yes", "No")),
        ("Metrics", fmt_status(connection.get("metrics_enabled", False), "Yes", "No")),
        ("Resources", fmt_status(connection.get("resources_enabled", False), "Yes", "No")),
        ("Auto-Link", fmt_status(connection.get("auto_link_enabled", False), "Enabled", "Disabled")),
    ]

    two_column_row(make_panel("Overview", overview_rows), make_panel("Status", status_rows))

    # =====================================================================
    # Connection Types Detail (per-type breakdown from types dict)
    # =====================================================================
    if types_config:
        type_table = Table(
            box=box.SIMPLE_HEAVY,
            show_header=True,
            header_style="bold cyan",
            expand=True,
            padding=(0, 1),
        )
        type_table.add_column("Type", style="bold white", width=12)
        type_table.add_column("Enabled", width=10)
        type_table.add_column("Healthy", width=10)
        type_table.add_column("Role ARN", style="dim", overflow="fold")
        type_table.add_column("Sources", style="dim")

        for type_name in ["COST", "RESOURCE", "METRICS", "DATA"]:
            if type_name not in types_config:
                continue
            tc = types_config[type_name]
            method = tc.get("connection_method") or {}
            sources = tc.get("record_sources") or []

            type_table.add_row(
                type_name,
                fmt_status(tc.get("enabled", False), "Yes", "No"),
                fmt_status(tc.get("healthy", True), "Healthy", "Unhealthy"),
                method.get("role_arn", "[dim]--[/]"),
                ", ".join(sources) if sources else "[dim]--[/]",
            )

        console.print(
            Panel(type_table, title="[bold]Connection Types[/]", title_align="left", border_style="dim", expand=True)
        )

    # =====================================================================
    # Row 2: Billing & Cost + Auto-Link
    # =====================================================================
    cur_data_obj = conn_details.get("cur_data")
    role_arn = conn_details.get("role_arn")
    external_id = conn_details.get("external_id")
    cur_configs = conn_details.get("cur_configurations") or {}

    billing_rows = []
    if role_arn:
        billing_rows.append(("Role ARN", str(role_arn)))
    if external_id:
        billing_rows.append(("External ID", str(external_id)))
    if cur_data_obj and isinstance(cur_data_obj, dict):
        if report_name := cur_data_obj.get("report_name"):
            billing_rows.append(("Active CUR", report_name))
        if bucket_name := cur_data_obj.get("bucket_name"):
            bucket_path = cur_data_obj.get("bucket_path", "")
            billing_rows.append(("CUR Bucket", f"s3://{bucket_name}/{bucket_path}" if bucket_path else bucket_name))
    if cur_configs:
        billing_rows.append(("Total CURs", f"{len(cur_configs)} configured"))

    auto_link_config = conn_details.get("auto_link") or {}
    # auto_link_enabled is at root of types.COST.data, not inside the auto_link dict
    auto_link_enabled = conn_details.get("auto_link_enabled", False) or connection.get("auto_link_enabled", False)

    al_rows = [("Status", fmt_status(auto_link_enabled, "Enabled", "Disabled"))]
    if auto_link_config:
        if al_role := auto_link_config.get("role_name"):
            al_rows.append(("Role Name", al_role))
        if al_updated := auto_link_config.get("updated_at"):
            al_rows.append(("Last Updated", fmt_ts(al_updated)))
        linked = auto_link_config.get("linked") or []
        failures = auto_link_config.get("link_failure") or []
        ignored = auto_link_config.get("ignore") or []
        al_rows.append(("Linked", f"[green]{len(linked)}[/] accounts"))
        al_rows.append(("Failures", f"[red]{len(failures)}[/] accounts" if failures else "[green]0[/]"))
        al_rows.append(("Ignored", f"{len(ignored)} accounts"))

    has_billing = bool(billing_rows)
    has_autolink = len(al_rows) > 1 or auto_link_enabled  # more than just the status row

    if has_billing and has_autolink:
        two_column_row(make_panel("Billing & Cost", billing_rows), make_panel("Auto-Link", al_rows))
    elif has_billing:
        console.print(make_panel("Billing & Cost", billing_rows))
    elif has_autolink:
        console.print(make_panel("Auto-Link", al_rows))

    # =====================================================================
    # Health Checks (full width table)
    # =====================================================================
    link_health = conn_details.get("link_health") or {}
    active_checks = {k: v for k, v in link_health.items() if v is not None}

    if active_checks:
        health_table = Table(
            box=box.SIMPLE_HEAVY,
            show_header=True,
            header_style="bold cyan",
            expand=True,
            padding=(0, 1),
        )
        health_table.add_column("Component", style="white", width=20)
        health_table.add_column("Status", width=10)
        health_table.add_column("Details", style="dim")
        health_table.add_column("Last Checked", style="dim", width=22)

        for check_name, check_data in active_checks.items():
            label = check_name.replace("_", " ").title()
            is_healthy = check_data.get("is_healthy", False)
            status_text = fmt_status(is_healthy, "Healthy", "Unhealthy")
            messages = check_data.get("messages") or {}
            details = "; ".join(messages.values()) if messages else "[dim]--[/]"
            timestamp = fmt_ts(check_data.get("timestamp"))
            health_table.add_row(label, status_text, details, timestamp)

        console.print(
            Panel(health_table, title="[bold]Health Checks[/]", title_align="left", border_style="dim", expand=True)
        )

    # =====================================================================
    # Access Verification
    # =====================================================================
    access_rows = []
    if access_status := connection.get("access_check_status"):
        status_color = "green" if access_status == "success" else "red" if access_status == "failed" else "yellow"
        access_rows.append(("Status", f"[{status_color}]{access_status.title()}[/{status_color}]"))
    if last_check := connection.get("last_access_check"):
        access_rows.append(("Last Check", fmt_ts(last_check)))
    if last_success := connection.get("last_successful_access"):
        access_rows.append(("Last Success", fmt_ts(last_success)))
    if access_error := connection.get("access_check_error"):
        access_rows.append(("Error", f"[red]{access_error}[/]"))

    if access_rows:
        console.print(make_panel("Access Verification", access_rows))

    # =====================================================================
    # CUR Configurations (full width table, only if multiple CURs)
    # =====================================================================
    if cur_configs and len(cur_configs) > 1:
        active_cur_name = cur_data_obj.get("report_name") if cur_data_obj and isinstance(cur_data_obj, dict) else None

        cur_table = Table(
            box=box.SIMPLE_HEAVY,
            show_header=True,
            header_style="bold cyan",
            expand=True,
            padding=(0, 1),
        )
        cur_table.add_column("Report Name", style="white")
        cur_table.add_column("Format")
        cur_table.add_column("Compression")
        cur_table.add_column("S3 Bucket")
        cur_table.add_column("Time Unit")
        cur_table.add_column("Active", width=8)

        for cur_name, cur_cfg in cur_configs.items():
            is_active = cur_name == active_cur_name
            cur_table.add_row(
                f"[bold]{cur_name}[/]" if is_active else cur_name,
                cur_cfg.get("Format", "?"),
                cur_cfg.get("Compression", "?"),
                cur_cfg.get("S3Bucket", "?"),
                cur_cfg.get("TimeUnit", "?"),
                "[green]Yes[/]" if is_active else "[dim]No[/]",
            )

        console.print(
            Panel(cur_table, title="[bold]CUR Configurations[/]", title_align="left", border_style="dim", expand=True)
        )

    # =====================================================================
    # AWS Organization Tree (full width, only for COST connections with metadata)
    # =====================================================================
    metadata = connection.get("connection_metadata")
    if metadata:
        plugins = metadata.get("plugins") or {}
        org_plugin = plugins.get("organization_connections") or {}

        if org_plugin.get("status") == "success":
            plugin_data = org_plugin.get("data") or {}
            root_data = plugin_data.get("root") or {}
            summary = plugin_data.get("summary") or {}
            org_info = plugin_data.get("organization") or {}

            if root_data:
                # Build tree header from AWS Organization metadata
                tree_label = "AWS Organization"
                if org_info:
                    org_id_aws = org_info.get("id", "")
                    feature_set = org_info.get("feature_set", "")
                    master_email = org_info.get("master_account_email", "")
                    parts = [p for p in [org_id_aws, feature_set] if p]
                    if parts:
                        tree_label += f": {' / '.join(parts)}"
                    if master_email:
                        tree_label += f"  [dim]({master_email})[/]"

                tree = Tree(f"[bold]{tree_label}[/]")

                def _count_recursive(node):
                    """Count total accounts in an OU and all children."""
                    total = len(node.get("accounts") or [])
                    for child in node.get("organizational_units") or []:
                        total += _count_recursive(child)
                    return total

                def _build_tree(parent_branch, node):
                    """Recursively build Rich Tree from OU hierarchy."""
                    ous = node.get("organizational_units") or []
                    direct_accounts = node.get("accounts") or []

                    for ou in ous:
                        ou_name = ou.get("name", "Unknown OU")
                        total_accts = _count_recursive(ou)

                        label = f"[bold]{ou_name}[/]  [cyan]{total_accts}[/] accounts"
                        # Show contact email from OU accounts if available
                        for acct in ou.get("accounts") or []:
                            if email := acct.get("email"):
                                label += f"  [dim]({email})[/]"
                                break

                        branch = parent_branch.add(label)
                        _build_tree(branch, ou)

                    # Show direct (root-level) accounts when OUs also exist
                    if direct_accounts and ous:
                        connected_direct = sum(1 for a in direct_accounts if a.get("is_connected"))
                        parent_branch.add(
                            f"[dim]{len(direct_accounts)} direct accounts ({connected_direct} connected)[/]"
                        )

                _build_tree(tree, root_data)

                # Summary line (API returns these as strings, so cast to numeric)
                total = int(summary.get("total_accounts", 0))
                connected = int(summary.get("connected", summary.get("connected_count", 0)))
                unconnected = int(summary.get("unconnected", summary.get("unconnected_count", 0)))
                rate = float(summary.get("connection_rate_pct", summary.get("connection_rate_percent", 0)))
                ou_count = int(summary.get("organizational_units", 0))

                summary_line = (
                    f"\n[bold]{total}[/] accounts  |  "
                    f"[green]{connected} connected[/]  |  "
                    f"[red]{unconnected} unconnected[/]  ({rate:.0f}%)  |  "
                    f"{ou_count} OUs"
                )

                org_content = Table.grid(expand=True)
                org_content.add_column()
                org_content.add_row(tree)
                org_content.add_row(summary_line)

                console.print(
                    Panel(
                        org_content,
                        title="[bold]AWS Organization[/]",
                        title_align="left",
                        border_style="dim",
                        expand=True,
                    )
                )

    # =====================================================================
    # Footer: Timestamps + Web Console
    # =====================================================================
    console.print(
        f"\n[dim]First Seen:[/] {fmt_ts(connection.get('first_seen'))}  "
        f"[dim]Last Seen:[/] {fmt_ts(connection.get('last_seen'))}  "
        f"[dim]Last Updated:[/] {fmt_ts(connection.get('last_updated'))}"
    )
    console.print(
        f"[cyan]Web Console:[/] https://app.cloudzero.com?organization_id={org_id}&connection_id={actual_conn_id}\n"
    )


def handle_info_command(arguments, organization_data=None):
    """Main handler for the info command."""
    entity_type = "org" if arguments.get("org") else "connection"
    id_or_name = arguments.get("<ID-or-NAME>")

    # Check if we're dealing with a connection ID
    if entity_type == "connection" or looks_like_a_connection_id(id_or_name):
        if entity_type == "org" and looks_like_a_connection_id(id_or_name):
            console.print(
                "[yellow]Warning:[/] The ID you provided looks like a connection ID, but you used the 'org' command. Switching to connection info."
            )
            entity_type = "connection"

        if entity_type == "connection":
            # Display connection info
            display_connection_info(arguments, id_or_name, organization_data)

    else:
        # If organization_data is not already provided, get it now
        if not organization_data:
            # Only fetch if we don't already have the data
            organization_data = get_organization_data(id_or_name, arguments)

        if not organization_data:
            # Show friendly message about organization not found with data freshness info
            console.print("\n[yellow]Organization Not Found[/]")
            console.print(f"No organization found with ID or name '[cyan]{id_or_name}[/]'")

            # Get data freshness information
            try:
                from src.api.v4_system import get_materialization_stats

                stats = get_materialization_stats(debug=arguments.get("--debug", False))
                if stats:
                    # Show when data was last refreshed
                    if timestamp := stats.get("completed_at") or stats.get("last_updated"):
                        console.print(
                            f"\n[dim]CloudZero is working with the latest data (last refresh: {timestamp})[/]"
                        )

                    # Show how many organizations are available
                    if org_count := stats.get("organizations_with_summaries"):
                        console.print(f"[dim]There are currently {org_count} organizations in the system[/]")
                    elif org_written := stats.get("organizations_written"):
                        # Handle array format - sum if it's a list
                        if isinstance(org_written, list):
                            total_orgs = sum(int(x) for x in org_written if str(x).isdigit())
                            console.print(f"[dim]There are currently {total_orgs} organizations in the system[/]")
                        else:
                            console.print(f"[dim]There are currently {org_written} organizations in the system[/]")

            except Exception:
                # Don't break if stats call fails
                console.print("\n[dim]CloudZero is working with the latest available data[/]")

            console.print("\n[cyan]💡 Try:[/]")
            console.print("  • [white]czops org list[/] - to see all available organizations")
            console.print(f"  • [white]czops org list {id_or_name}[/] - to search by partial name")
            console.print("  • Check the spelling of the organization name or ID")
            return

        # Display organization info
        display_organization_info(arguments, organization_data)
