"""Adapter wrapping Display as a Stage."""

from typing import Any

from engine.pipeline.core import PipelineContext, Stage


class DisplayStage(Stage):
    """Adapter wrapping Display as a Stage."""

    def __init__(self, display, name: str = "terminal", positioning: str = "mixed"):
        self._display = display
        self.name = name
        self.category = "display"
        self.optional = False
        self._initialized = False
        self._init_width = 80
        self._init_height = 24
        self._positioning = positioning

    def save_state(self) -> dict[str, Any]:
        """Save display state for restoration after pipeline rebuild.

        Returns:
            Dictionary containing display state that can be restored
        """
        return {
            "initialized": self._initialized,
            "init_width": self._init_width,
            "init_height": self._init_height,
            "width": getattr(self._display, "width", 80),
            "height": getattr(self._display, "height", 24),
        }

    def restore_state(self, state: dict[str, Any]) -> None:
        """Restore display state from saved state.

        Args:
            state: Dictionary containing display state from save_state()
        """
        self._initialized = state.get("initialized", False)
        self._init_width = state.get("init_width", 80)
        self._init_height = state.get("init_height", 24)

        # Restore display dimensions if the display supports it
        if hasattr(self._display, "width"):
            self._display.width = state.get("width", 80)
        if hasattr(self._display, "height"):
            self._display.height = state.get("height", 24)

    @property
    def capabilities(self) -> set[str]:
        return {"display.output"}

    @property
    def dependencies(self) -> set[str]:
        # Display needs rendered content and camera transformation
        return {"render.output", "camera"}

    @property
    def inlet_types(self) -> set:
        from engine.pipeline.core import DataType

        return {DataType.TEXT_BUFFER}  # Display consumes rendered text

    @property
    def outlet_types(self) -> set:
        from engine.pipeline.core import DataType

        return {DataType.NONE}  # Display is a terminal stage (no output)

    def init(self, ctx: PipelineContext) -> bool:
        w = ctx.params.viewport_width if ctx.params else 80
        h = ctx.params.viewport_height if ctx.params else 24

        # Try to reuse display if already initialized
        reuse = self._initialized
        result = self._display.init(w, h, reuse=reuse)

        # Update initialization state
        if result is not False:
            self._initialized = True
            self._init_width = w
            self._init_height = h

        return result is not False

    def process(self, data: Any, ctx: PipelineContext) -> Any:
        """Output data to display."""
        if data is not None:
            # Check if positioning mode is specified in context params
            positioning = self._positioning
            if ctx and ctx.params and hasattr(ctx.params, "positioning"):
                positioning = ctx.params.positioning

            # Pass positioning to display if supported
            if (
                hasattr(self._display, "show")
                and "positioning" in self._display.show.__code__.co_varnames
            ):
                self._display.show(data, positioning=positioning)
            else:
                # Fallback for displays that don't support positioning parameter
                self._display.show(data)
        return data

    def cleanup(self) -> None:
        self._display.cleanup()
