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

"""
UI component utilities for consistent interface elements.

This module provides factory classes and utilities for creating consistent
Rich-based UI components across the application, including:
- Tables with standard styling
- Panels for headers and sections
- Progress bars with spinners
- Health status indicators
"""

from typing import Any

from rich.console import Console
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.table import Table, box
from rich.text import Text


class TableFactory:
    """Factory for creating consistent Rich tables."""

    @staticmethod
    def create_standard_table(
        title: str,
        columns: list[tuple[str, dict[str, Any]]],
        width: int | None = None,
        show_header: bool = True,
        box_style: Any = box.ROUNDED,
        title_style: str = "cyan",
        header_style: str = "bright_white",
    ) -> Table:
        """
        Create a standard table with common settings.

        Args:
            title: Table title
            columns: List of (name, kwargs) tuples for columns
            width: Optional table width
            show_header: Whether to show column headers
            box_style: Rich box style
            title_style: Style for title
            header_style: Style for headers

        Returns:
            Configured Rich Table
        """
        table = Table(
            title=title,
            title_justify="left",
            box=box_style,
            title_style=title_style,
            show_header=show_header,
            header_style=header_style,
            width=width,
        )

        for col_name, col_kwargs in columns:
            table.add_column(col_name, **col_kwargs)

        return table

    @staticmethod
    def create_grid_table(padding: int = 1, width: int | None = None) -> Table:
        """
        Create a grid-style table without borders.

        Args:
            padding: Cell padding
            width: Optional table width (not supported by Table.grid)

        Returns:
            Configured Rich Table grid
        """
        # Note: Table.grid doesn't support width parameter
        return Table.grid(padding=padding)

    @staticmethod
    def create_summary_table(
        title: str,
        key_style: str = "cyan",
        value_style: str = "bright_white",
        width: int | None = None,
    ) -> Table:
        """
        Create a key-value summary table.

        Args:
            title: Table title
            key_style: Style for keys
            value_style: Style for values
            width: Optional table width

        Returns:
            Configured Rich Table for summaries
        """
        table = Table(
            title=title,
            title_justify="left",
            box=box.ROUNDED,
            title_style="cyan",
            show_header=False,
            width=width,
        )

        table.add_column("Key", style=key_style, justify="right")
        table.add_column("Value", style=value_style, justify="left")

        return table

    @staticmethod
    def create_connections_table(
        title: str,
        columns: list[tuple[str, dict[str, Any]]],
        width: int | None = None,
    ) -> Table:
        """
        Create a connections table with standard styling.

        Args:
            title: Table title
            columns: List of (name, kwargs) tuples for columns
            width: Optional table width

        Returns:
            Configured Rich Table for connections
        """
        table = Table(
            title=title,
            title_justify="left",
            title_style="bold cyan",
            show_header=True,
            box=box.ROUNDED,
            header_style="bold white",
            width=width,
            row_styles=["", "dim"],
        )

        for col_name, col_kwargs in columns:
            table.add_column(col_name, **col_kwargs)

        return table

    @staticmethod
    def create_organizations_table(
        title: str = "CloudZero Organizations",
        width: int | None = None,
    ) -> Table:
        """
        Create an organizations table with standard styling.

        Args:
            title: Table title
            width: Optional table width

        Returns:
            Configured Rich Table for organizations
        """
        return Table(
            title=title,
            title_justify="left",
            title_style="bold cyan",
            width=width,
            show_header=True,
            box=box.ROUNDED,
            header_style="bright_white",
            row_styles=["bright_white", "white"],
        )


class PanelFactory:
    """Factory for creating consistent Rich panels."""

    @staticmethod
    def create_header_panel(
        content: Any,
        title: str,
        width: int | None = None,
        border_style: str = "cyan",
        padding: tuple[int, int] = (1, 2),
    ) -> Panel:
        """
        Create a standard header panel.

        Args:
            content: Panel content
            title: Panel title
            width: Optional panel width
            border_style: Border color/style
            padding: Vertical and horizontal padding

        Returns:
            Configured Rich Panel
        """
        return Panel(
            content,
            title=title,
            title_align="left",
            border_style=border_style,
            padding=padding,
            width=width,
        )

    @staticmethod
    def create_info_panel(
        content: str,
        title: str | None = None,
        style: str = "blue",
        width: int | None = None,
    ) -> Panel:
        """
        Create an informational panel.

        Args:
            content: Panel content
            title: Optional panel title
            style: Panel style
            width: Optional panel width

        Returns:
            Configured Rich Panel
        """
        return Panel(
            content,
            title=title,
            title_align="left" if title else None,
            border_style=style,
            padding=(1, 2),
            width=width,
        )

    @staticmethod
    def create_welcome_panel(
        description: str,
        title: str = "CloudZero CLI",
        style: str = "green",
    ) -> Panel:
        """
        Create a welcome panel for CLI commands.

        Args:
            description: Welcome message description
            title: Panel title
            style: Panel border style

        Returns:
            Configured Rich Panel
        """
        return Panel(
            description,
            title=title,
            title_align="left",
            border_style=style,
        )

    @staticmethod
    def create_organization_header_panel(
        org_name: str,
        org_id: str,
        org_stage: str = "",
        org_enabled: bool = True,
    ) -> Panel:
        """
        Create an organization header panel.

        Args:
            org_name: Organization name
            org_id: Organization ID
            org_stage: Organization stage
            org_enabled: Whether organization is enabled

        Returns:
            Configured Rich Panel
        """
        from rich.text import Text

        # Format org status text with appropriate color
        status_text = "Enabled" if org_enabled else "Disabled"
        status_style = "green" if org_enabled else "red"

        header_text = Text()
        header_text.append(f"{org_name} ", style="bold white")
        header_text.append(f"({org_id}) ", style="cyan")
        if org_stage:
            header_text.append(f"Stage: {org_stage} | ", style="blue")
        header_text.append(f"Status: {status_text}", style=status_style)

        return Panel(
            header_text,
            title="Organization",
            title_align="left",
            border_style="cyan",
            padding=(0, 1),
        )


class ProgressFactory:
    """Factory for creating consistent progress indicators."""

    @staticmethod
    def create_spinner_progress(
        description: str,
        total: int | None = None,
        console: Console | None = None,
    ) -> Progress:
        """
        Create a progress bar with spinner.

        Args:
            description: Progress description
            total: Total number of items (optional)
            console: Console instance to use

        Returns:
            Configured Rich Progress
        """
        if total is not None:
            return Progress(
                SpinnerColumn(),
                TextColumn(f"[cyan]{description} [bright_white]{{task.completed}}/{{task.total}}[/]"),
                console=console,
            )
        else:
            return Progress(
                SpinnerColumn(),
                TextColumn(f"[cyan]{description}[/]"),
                console=console,
            )

    @staticmethod
    def create_export_progress() -> Progress:
        """
        Create a progress bar for export operations.

        Returns:
            Configured Rich Progress for exports
        """
        return Progress()

    @staticmethod
    def create_processing_progress(description: str = "Processing") -> Progress:
        """
        Create a progress bar for processing operations.

        Args:
            description: Processing description

        Returns:
            Configured Rich Progress for processing
        """
        return Progress(
            SpinnerColumn(),
            TextColumn(f"[bold blue]{description}... [cyan]{{task.completed}}/{{task.total}}[/cyan]"),
        )

    @staticmethod
    def create_fetch_progress(description: str = "Fetching data") -> Progress:
        """
        Create a progress bar for data fetching operations.

        Args:
            description: Fetch description

        Returns:
            Configured Rich Progress for fetching
        """
        return Progress(
            SpinnerColumn(),
            TextColumn(f"[bold blue]{description}..."),
            TextColumn("[cyan]{task.fields[status]}", justify="left"),
        )


class HealthStatus:
    """Utilities for health status display."""

    @staticmethod
    def get_icon(is_healthy: bool) -> str:
        """
        Get health status icon.

        Args:
            is_healthy: Health status boolean

        Returns:
            Emoji icon for status
        """
        return "🟢" if is_healthy else "🔴"

    @staticmethod
    def get_status_text(is_healthy: bool) -> Text:
        """
        Get colored status text.

        Args:
            is_healthy: Health status boolean

        Returns:
            Rich Text object with colored status
        """
        if is_healthy:
            return Text("Healthy", style="green")
        else:
            return Text("Unhealthy", style="red")

    @staticmethod
    def get_connection_type_info(connection: dict[str, Any]) -> tuple[str, str, str]:
        """
        Get connection type information.

        Args:
            connection: Connection dictionary

        Returns:
            Tuple of (type_name, description, icon)
        """
        is_cost_connection = connection.get("is_cost_connection", False)

        if is_cost_connection:
            return ("Payer", "Cost and usage data for this account and its linked accounts", "💰")
        else:
            return ("Resource", "Resource-only account with no billing data", "🔧")

    @staticmethod
    def get_connection_status_icon(connection: dict[str, Any]) -> str:
        """
        Get status icon for a connection.

        Args:
            connection: Connection dictionary

        Returns:
            Status icon string
        """
        if not connection.get("is_connected"):
            return "🔴"
        elif connection.get("permission_errors"):
            return "🟡"
        else:
            return "🟢"

    @staticmethod
    def determine_overall_health_icon(healthy_count: int, unhealthy_count: int, total_count: int) -> str:
        """
        Determine overall health icon based on counts.

        Args:
            healthy_count: Number of healthy connections
            unhealthy_count: Number of unhealthy connections
            total_count: Total number of connections

        Returns:
            Health icon string
        """
        if healthy_count + unhealthy_count == 0:
            return "⚪"  # No connections
        elif healthy_count == total_count:
            return "🟢"  # All healthy
        elif healthy_count == 0:
            return "🔴"  # None healthy
        else:
            return "🟡"  # Partial health
