"""Entity renderer for displaying single entity details.

Renders single Pydantic model instances using configured field formatters.
"""

from dataclasses import dataclass
from typing import Any, Callable

from pydantic import BaseModel

from cli.infrastructure.console import get_console
from cli.infrastructure.formatters.base import Formatter


@dataclass
class FieldConfig:
    """Configuration for a single field to render.

    Attributes:
        source_field: Attribute name on the Pydantic model
        display_label: Human-readable label for display
        formatter: Optional function to format the field value
    """

    source_field: str
    display_label: str
    formatter: Callable[[Any], str] | None = None


class EntityRenderer:
    """Renders single entity details using a formatter.

    Extracts data from Pydantic models according to field configurations
    and renders using the provided formatter.
    """

    def __init__(self, formatter: Formatter):
        """Initialize renderer with a formatter.

        Args:
            formatter: Formatter instance (CompactFormatter, JsonFormatter, etc.)
        """
        self.formatter = formatter

    def render(
        self, entity: BaseModel, title: str | None, fields: list[FieldConfig]
    ) -> None:
        """Render entity details to console.

        Args:
            entity: Pydantic model instance to render
            title: Display title for the entity (optional)
            fields: List of field configurations defining what to show
        """
        # Extract data from entity using field configs
        data: dict[str, Any] = {}
        for field_config in fields:
            value = getattr(entity, field_config.source_field, None)

            if field_config.formatter:
                value = field_config.formatter(value)

            data[field_config.display_label] = value

        del title
        output = self.formatter.format_entity(data, None)

        console = get_console()
        if isinstance(output, str):
            console.file.write(f"{output}\n")
            console.file.flush()
            return
        console.print(output)
