"""Base renderer class for display modes."""

from abc import ABC, abstractmethod


from ..models import Sheet


class ModeRenderer(ABC):
    """Base renderer for a display mode.

    Each renderer handles a specific display mode (reference, code, etc.)
    and is responsible for converting sheets into Rich renderables for display.

    Renderers are the final stage of the display pipeline, taking parsed sheet
    data and creating the visual layout that users see in their terminal.
    They must handle terminal size constraints and focus management.

    Subclasses must implement:
        - mode: Return the string identifier for this renderer's mode
        - render: Convert sheets to Rich renderables for display
        - accepts_sheet: Determine if a sheet is compatible with this mode
    """

    @property
    @abstractmethod
    def mode(self) -> str:
        """Mode this renderer handles.

        This should return a string identifier that matches the 'mode' field
        in Sheet objects. Used by the pipeline to select the appropriate
        renderer for each sheet.

        Returns:
            str: The mode identifier (e.g., 'reference', 'code')
        """
        pass

    @abstractmethod
    def render(
        self,
        sheets: list[Sheet],
        terminal_size: tuple[int, int],
        focus: str | None = None,
    ) -> list:
        """Render sheets for this mode into Rich renderables.

        Takes a list of sheets and converts them into Rich objects that can
        be displayed in the terminal. Must respect terminal size constraints
        and handle layout decisions like panel sizing and positioning.

        The focus parameter allows prioritizing a specific sheet when space
        is limited - focused sheets should be given preference in display.

        Args:
            sheets: List of Sheet objects to render, all compatible with this mode
            terminal_size: Current terminal dimensions as (width, height) tuple
            focus: Optional sheet name to prioritize in layout decisions

        Returns:
            list: List of Rich renderables (Panels, Tables, etc.) ready for display.
                 Empty list indicates no content to display.

        Raises:
            ValueError: If sheets contain incompatible modes or invalid data
        """
        pass

    @abstractmethod
    def accepts_sheet(self, sheet: Sheet) -> bool:
        """Check if sheet is compatible with this mode.

        Used by the pipeline to filter sheets before passing them to render().
        Should return True only if this renderer can successfully handle the
        given sheet's structure and content type.

        Typically checks the sheet's mode field, but may also validate that
        the sheet's sections are of the expected type (PanelSpec vs CodeSection).

        Args:
            sheet: Sheet object to validate for compatibility

        Returns:
            bool: True if the sheet can be rendered by this mode renderer,
                 False if it should be handled by a different renderer
        """
        pass
