from typing import Any

from rich import box
from rich.table import Table
from rich.text import Text

from cli.infrastructure.formatters.base import (
    ColumnMeta,
    Formatter,
    format_scalar_value,
)


class TableFormatter(Formatter):
    def format_entity(self, data: dict[str, Any], title: str | None = None) -> Table:
        table = Table(title=title, safe_box=True, box=box.SIMPLE)
        table.add_column("Field")
        table.add_column("Value")

        for label, value in data.items():
            table.add_row(Text(label), Text(format_scalar_value(value)))

        return table

    def format_list(
        self,
        items: list[dict[str, Any]],
        title: str | None = None,
        columns: list[ColumnMeta] | None = None,
    ) -> Table:
        table = Table(title=title, safe_box=True, box=box.SIMPLE)

        resolved_columns = columns or [
            ColumnMeta(label=key) for key in _infer_keys(items)
        ]
        for column in resolved_columns:
            table.add_column(column.label, width=column.width, justify=column.align)

        for item in items:
            table.add_row(
                *[
                    Text(format_scalar_value(item.get(column.label)))
                    for column in resolved_columns
                ]
            )

        return table

    def format_success(self, message: str) -> str:
        return f"✓ {message}"

    def format_info(self, message: str) -> str:
        return f"ℹ {message}"

    def format_warning(self, message: str) -> str:
        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:
        from cli.infrastructure.formatters.base import render_psql_result

        return render_psql_result(
            action=action,
            resource=resource,
            status=status,
            identifier=identifier,
            name=name,
            extra_fields=extra_fields,
        )


def _infer_keys(items: list[dict[str, Any]]) -> list[str]:
    if not items:
        return []
    return list(items[0].keys())
