# 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
#

"""
Formatting utilities for consistent data presentation.

This module contains reusable functions for formatting various data types:
- Date and time formatting
- Status indicators and health checks
- Organization and connection data formatting
"""

from src.utils.organization_status import (
    format_organization_status_consolidated,
    is_organization_enabled,
    normalize_organization_data,
)
from src.utils.time import pretty_datetime_local


def format_date(date_str: str, nice: bool = False, default: str = "N/A") -> str:
    """
    Format a date string for display.

    Args:
        date_str: The date string to format
        nice: If True, use pretty formatting with relative time
        default: Default value if date is None or invalid

    Returns:
        Formatted date string
    """
    if not date_str or date_str.startswith("1970"):
        return default
    elif nice:
        return pretty_datetime_local(date_str)
    else:
        # For org list, show only the date part (YYYY-MM-DD)
        if "T" in date_str:
            return date_str.split("T")[0]
        return date_str


def format_organization_spend(spend_amount: float | int | str | None) -> str:
    """
    Format organization spend amount for display.

    Args:
        spend_amount: The spend amount to format

    Returns:
        Formatted spend string with currency symbol
    """
    if spend_amount is None:
        return "N/A"
    elif isinstance(spend_amount, int | float):
        return f"${spend_amount:,.2f}"
    else:
        return str(spend_amount)


def get_consolidated_health_status(
    is_connected: bool,
    is_healthy: bool,
    payer_healthy: bool,
    resource_healthy: bool,
) -> str:
    """
    Generate a consolidated health status indicator based on connection health indicators.

    This function combines multiple health indicators into a single, hierarchical status
    that preserves critical information without duplication.

    Args:
        is_connected: Whether the connection is established
        is_healthy: Overall health status of the connection
        payer_healthy: Health status of the payer account role
        resource_healthy: Health status of the resource account role

    Returns:
        Rich-formatted consolidated health status with emoji and description
    """
    # Define status hierarchy (from worst to best)
    if not is_connected:
        return "🔴 [red]Disconnected[/]"
    elif not is_healthy:
        return "🔴 [red]Unhealthy[/]"
    elif not payer_healthy and not resource_healthy:
        return "🔴 [red]Role Issues[/]"
    elif not payer_healthy:
        return "🟠 [orange3]Payer Issue[/]"
    elif not resource_healthy:
        return "🟠 [orange3]Resource Issue[/]"
    else:
        return "🟢 [green]Healthy[/]"


def format_enabled_status(is_enabled: bool, use_emoji: bool = True) -> str:
    """
    Format enabled/disabled status for display.

    Args:
        is_enabled: Boolean indicating if entity is enabled
        use_emoji: If True, use emoji; otherwise use text

    Returns:
        Formatted status string
    """
    if use_emoji:
        return ":white_check_mark:" if is_enabled else ":x:"
    else:
        return "Yes" if is_enabled else "No"


def format_organization_status(is_enabled: bool, billing_enabled: bool = True, plain_text: bool = False) -> str:
    """
    Format organization status for display in CLI table.

    Args:
        is_enabled: Boolean indicating if organization is enabled (based on organization_enabled field)
        billing_enabled: Boolean indicating if billing is enabled (unused for simplified status)
        plain_text: If True, return plain text; otherwise use rich formatting

    Returns:
        Formatted status string: "Enabled" or "Disabled"
    """
    if is_enabled:
        if plain_text:
            return "Enabled"
        else:
            return "[green]Enabled[/green]"
    else:
        if plain_text:
            return "Disabled"
        else:
            return "[red]Disabled[/red]"


def format_connection_type(connection: dict) -> str:
    """
    Determine and format the connection type from connection data.

    Args:
        connection: Connection dictionary containing type information

    Returns:
        Formatted connection type string
    """
    conn_type = None
    if (
        connection.get("is_cost_connection", False)
        or connection.get("account_type") == "payer"
        or connection.get("master_payer_role_arn")
    ):
        conn_type = "payer"
    elif (
        connection.get("is_resource_connection", False)
        or connection.get("account_type") == "resource"
        or connection.get("resource_owner_role_arn")
    ):
        conn_type = "resource"

    return conn_type or "unknown"


def format_spend_with_color(spend_value: str) -> str:
    """
    Format spend value with color for rich console display.

    Args:
        spend_value: The spend value string to format

    Returns:
        Color-formatted spend string
    """
    if spend_value != "N/A":
        return f"[green]{spend_value}[/]"
    return spend_value


def format_disabled_date_with_color(disabled_date: str, is_disabled: bool) -> str:
    """
    Format disabled date with color for rich console display.

    Args:
        disabled_date: The date string to format
        is_disabled: Whether the entity is currently disabled

    Returns:
        Color-formatted date string
    """
    if disabled_date != "N/A" and is_disabled:
        return f"[red]{disabled_date}[/]"
    return disabled_date


def format_org_data_into_list(
    org_data: dict,
    sort: bool = True,
    nice_dates: bool = False,
    plain_text: bool = False,
    sort_by: str = "name",
    show_disabled_date: bool = False,
    show_autolink: bool = False,
    debug_mode: bool = False,
) -> list[dict]:
    """
    Format organization data into a list suitable for display.

    Args:
        org_data: Dictionary of organization data
        sort: Whether to sort the results
        nice_dates: Use pretty date formatting
        plain_text: Generate plain text output (no colors/emojis)
        sort_by: Sort field ('name', 'date', 'stage')
        show_disabled_date: Include disabled date column
        show_autolink: Include autolink enabled column

    Returns:
        List of formatted organization dictionaries
    """
    from datetime import UTC, datetime

    from src.utils.console import format_account_stage
    from src.utils.time import utc_datetime_from_anything

    data = []
    for k, v in org_data.items():
        # Normalize organization data to handle field name variations
        normalized_org = normalize_organization_data(v)

        # Get disabled date - check for disabled_datetime, disabled_date, or modified fields
        disabled_date = "N/A"
        if show_disabled_date and not is_organization_enabled(normalized_org):
            # Try several possible field names for the disabled date
            for date_field in ["disabled_date", "disabled_datetime", "disabled_at", "last_updated"]:
                if date_field in v and v[date_field]:
                    disabled_date = format_date(v[date_field], nice_dates)
                    break

        # Get 30-day spend if available
        spend_value = "N/A"
        if "spend_amount" in v:
            # Use pre-calculated value if available
            spend_value = format_organization_spend(v.get("spend_amount"))
        elif debug_mode:
            print(f"DEBUG: No precalculated spend for organization {k}")
        # Get autolink status (new schema: derived from connections_summary)
        autolink_value = "N/A"
        if show_autolink:
            connections_summary = v.get("connections_summary", {})
            if connections := connections_summary.get("connections"):
                # Auto-link enabled if any connection has auto-link enabled
                auto_link_enabled = any(
                    conn.get("auto_link", {}).get("enabled", False) for conn in connections.values()
                )
                autolink_value = "Yes" if auto_link_enabled else "No"
            else:
                autolink_value = "No"

        # Plain text version (for CSV export) has no formatting, colors, or emojis
        # Use V4 API connection data - prioritize connections_summary
        if connections_summary := v.get("connections_summary"):
            connection_count = connections_summary.get("total_connections", 0)
            if isinstance(connection_count, str):
                try:
                    connection_count = int(connection_count)
                except (ValueError, TypeError):
                    connection_count = 0

            # Use enabled_providers for connection types
            connection_types = connections_summary.get("enabled_providers", [])
        else:
            # Fallback to basic fields
            connection_count = v.get("connection_count", 0)
            connection_types = v.get("connection_types", [])

        row_data = {
            "Status": format_organization_status_consolidated(normalized_org, plain_text=True),
            "Organization ID": k,
            "Name": v.get("cz_organization_name") or "Unknown",
            "Site": v.get("website") or "N/A",
            "Stage": v.get("organization_stage") or "Unknown",
            "Connections": ", ".join(connection_types) if connection_types else "None",
            "#": str(connection_count),
            "Created": format_date(v.get("created_at"), nice_dates),
        }

        # Add Disabled Date column if showing disabled dates
        if show_disabled_date:
            row_data["Disabled"] = disabled_date

        # Add 30-day spend column if spend data is available
        if spend_value != "N/A":
            row_data["30-Day AWS Spend"] = spend_value

        # Add autolink enabled column if showing autolink
        if show_autolink:
            row_data["Autolink"] = autolink_value

        if plain_text:
            data.append(row_data)
        else:
            # Rich formatted version for display
            rich_row = {
                "Status": format_organization_status_consolidated(normalized_org, plain_text=False),
                "Organization ID": f"[link=https://app.cloudzero.com?organization_id=]{k}[/link]",
                "Name": v.get("cz_organization_name") or "Unknown",
                "Site": v.get("website") or "N/A",
                "Stage": format_account_stage(v.get("organization_stage")) or "Unknown",
                "Connections": ", ".join(connection_types) if connection_types else "None",
                "#": str(connection_count),
                "Created": format_date(v.get("created_at"), nice_dates),
            }

            # Add Disabled Date column if showing disabled dates
            if show_disabled_date:
                rich_row["Disabled"] = format_disabled_date_with_color(
                    disabled_date, not is_organization_enabled(normalized_org)
                )

            # Add 30-day spend column if spend data is available
            if spend_value != "N/A":
                rich_row["30-Day AWS Spend"] = format_spend_with_color(spend_value)

            # Add autolink enabled column if showing autolink
            if show_autolink:
                # Color code autolink status - green for Yes, red for No
                if autolink_value == "Yes":
                    rich_row["Autolink"] = f"[green]{autolink_value}[/]"
                elif autolink_value == "No":
                    rich_row["Autolink"] = f"[red]{autolink_value}[/]"
                else:
                    rich_row["Autolink"] = autolink_value

            data.append(rich_row)

    if sort:
        if sort_by.lower() == "name":
            data = sorted(data, key=lambda x: x["Name"].lower() if x["Name"] else "")
        elif sort_by.lower() == "date":
            # Sort by date with error handling for unparseable dates
            def safe_date_sort_key(item):
                try:
                    date_val = item["Created"]
                    if not date_val or date_val == "N/A":
                        # Use earliest possible date for None/empty/N/A values
                        return datetime.min.replace(tzinfo=UTC)
                    return utc_datetime_from_anything(date_val)
                except ValueError:
                    # For unparseable dates, sort to the beginning
                    return datetime.min.replace(tzinfo=UTC)

            data = sorted(data, key=safe_date_sort_key)
        elif sort_by.lower() == "stage":
            data = sorted(data, key=lambda x: x["Stage"] if x["Stage"] else "")
        else:
            # Default to name if sort_by is not recognized
            data = sorted(data, key=lambda x: x["Name"].lower() if x["Name"] else "")
    else:
        data = org_data
    return data
