from typing import Any

from rich.console import Console

from cli.infrastructure.console import get_console
from cli.infrastructure.formatters.base import (
    ColumnMeta,
    Formatter,
    render_psql_records,
    render_psql_result,
)


COMPACT_LABEL_MIN_WIDTH = 11


class CompactFormatter(Formatter):
    def __init__(self, console: Console | None = None):
        self.console = console or get_console()

    def format_entity(self, data: dict[str, Any], title: str | None = None) -> str:
        del title
        return render_psql_records([_pad_labels(data)])

    def format_list(
        self,
        items: list[dict[str, Any]],
        title: str | None = None,
        columns: list[ColumnMeta] | None = None,
    ) -> str:
        del title
        labels = [column.label for column in columns] if columns else None
        return render_psql_records([_pad_labels(item, labels) for item in items])

    def format_success(self, message: str) -> str:
        """Format success message with checkmark.

        Args:
            message: Success message text

        Returns:
            Rich markup string
        """
        return f"✓ {message}"

    def format_info(self, message: str) -> str:
        """Format info message with info icon.

        Args:
            message: Info message text

        Returns:
            Rich markup string
        """
        return f"ℹ {message}"

    def format_warning(self, message: str) -> str:
        """Format warning message with warning icon.

        Args:
            message: Warning message text

        Returns:
            Rich markup string
        """
        return f"⚠ {message}"

    def format_result(
        self,
        action: str,
        resource: str,
        status: str = "success",
        identifier: str | None = None,
        name: str | None = None,
        extra_fields: dict[str, Any] | None = None,
    ) -> str:
        return render_psql_result(
            action=action,
            resource=resource,
            status=status,
            identifier=identifier,
            name=name,
            extra_fields=extra_fields,
        )


def _pad_labels(
    data: dict[str, Any], labels: list[str] | None = None
) -> dict[str, Any]:
    ordered_labels = labels or list(data.keys())
    label_width = max(
        COMPACT_LABEL_MIN_WIDTH, *(len(label) for label in ordered_labels)
    )
    return {label.ljust(label_width): data.get(label) for label in ordered_labels}
