"""
Abstract base renderer interface for the NEXUS AUTOPARTS console application.

Every renderer (curses VT220, Textual/Rich, etc.) must subclass
:class:`BaseRenderer` and implement all of its methods.  Screens call
these methods without knowing which backend is active.
"""


class BaseRenderer:
    """Abstract interface that all renderers must implement.

    Methods raise :exc:`NotImplementedError` so that missing overrides
    are caught immediately at runtime.
    """

    # ── Lifecycle ────────────────────────────────────────────────────

    def init_screen(self):
        """Initialise the terminal / display backend."""
        raise NotImplementedError

    def cleanup(self):
        """Restore the terminal to its original state."""
        raise NotImplementedError

    # ── Screen queries ───────────────────────────────────────────────

    def get_size(self) -> tuple:
        """Return ``(height, width)`` of the usable display area."""
        raise NotImplementedError

    # ── Primitive operations ─────────────────────────────────────────

    def clear(self):
        """Clear the entire screen buffer."""
        raise NotImplementedError

    def refresh(self):
        """Flush the screen buffer to the terminal."""
        raise NotImplementedError

    def get_key(self) -> int:
        """Block until a key is pressed and return its key code."""
        raise NotImplementedError

    # ── High-level widgets ───────────────────────────────────────────

    def draw_header(self, title, subtitle=''):
        """Draw the application header bar on the top two rows.

        *title* is left-aligned; *subtitle* is right-aligned.
        Row 1 is a horizontal separator.
        """
        raise NotImplementedError

    def draw_footer(self, key_labels):
        """Draw the footer bar on the bottom two rows.

        *key_labels* is a list of ``(key, description)`` tuples,
        e.g. ``[("F1", "Ayuda"), ("ESC", "Atras")]``.
        """
        raise NotImplementedError

    def draw_menu(self, items, selected_index=0, title=''):
        """Draw a numbered menu list starting at row 3.

        *items* is a list of ``(number, label)`` tuples.
        Separator items have ``number == '---'``.
        The item at *selected_index* is highlighted.
        """
        raise NotImplementedError

    def draw_table(self, headers, rows, widths, page_info=None,
                   selected_row=-1):
        """Draw a columnar data table.

        *headers*: list of column header strings.
        *rows*: list of row tuples (each tuple matches *headers*).
        *widths*: list of int column widths.
        *page_info*: optional dict ``{page, total_pages, total_rows}``.
        *selected_row*: index of the highlighted row (-1 = none).
        """
        raise NotImplementedError

    def draw_detail(self, fields, title=''):
        """Draw a detail view with label-value pairs.

        *fields* is a list of ``(label, value)`` tuples displayed as
        ``Label........: Value``.
        """
        raise NotImplementedError

    def draw_form(self, fields, focused_index=0, title=''):
        """Draw an editable form.

        *fields* is a list of dicts with keys:
        ``label``, ``value``, ``width``, ``type``, ``hint``.
        The field at *focused_index* uses the active style.
        """
        raise NotImplementedError

    def draw_filter_list(self, items, filter_text, selected_index,
                         title=''):
        """Draw a filterable list with a text input at the top.

        *items*: list of ``(number, label)`` tuples.
        *filter_text*: current filter string.
        *selected_index*: highlighted item index.
        """
        raise NotImplementedError

    def draw_comparison(self, columns, title=''):
        """Draw a side-by-side comparison view.

        *columns* is a list of dicts, each with:
        ``header`` (str) and ``rows`` (list of ``(label, value)``).
        """
        raise NotImplementedError

    # ── Low-level drawing ────────────────────────────────────────────

    def draw_text(self, row, col, text, style='normal'):
        """Draw *text* at ``(row, col)`` using the named *style*."""
        raise NotImplementedError

    def draw_box(self, top, left, height, width, title=''):
        """Draw a box with Unicode line-drawing characters.

        Optional *title* is rendered in the top border.
        """
        raise NotImplementedError

    # ── Dialogs ──────────────────────────────────────────────────────

    def show_message(self, text, msg_type='info') -> bool:
        """Show a centred message box.

        *msg_type* is one of ``'info'``, ``'error'``, or ``'confirm'``.
        For ``'confirm'`` the user must press S (si) or N (no);
        returns ``True`` for S, ``False`` for N.
        For other types, waits for any key and returns ``True``.
        """
        raise NotImplementedError

    def show_input(self, prompt, max_len=40):
        """Show a centred input dialog.

        Returns the entered string, or ``None`` if the user pressed
        Escape to cancel.
        """
        raise NotImplementedError
