"""Base class for form modals with error handling.

Provides common functionality for all form modals:
- Standard cancel/submit bindings
- Error display methods
- Auto-hide error on input change
"""

from typing import Generic, TypeVar

from textual import on
from textual.binding import Binding
from textual.screen import ModalScreen
from textual.widgets import Input, Static, TextArea

T = TypeVar("T")


class BaseFormModal(ModalScreen[T | None], Generic[T]):
    """Abstract base for all form modals with error handling.

    Provides:
    - Standard cancel/submit bindings (escape, ctrl+s)
    - Error display methods (_show_error, _hide_error)
    - Auto-hide error on input/textarea change
    - Standard action_cancel implementation

    Subclasses must:
    - Include Static(id="error-display") in compose()
    - Implement action_submit()

    Usage:
        class MyModal(BaseFormModal[MyResult]):
            def compose(self) -> ComposeResult:
                # ... form fields ...
                yield Static("", id="error-display", classes="error-display")
                # ... buttons ...

            def action_submit(self) -> None:
                try:
                    self._validate()
                    self._hide_error()
                    self._finalize()
                except ValueError as e:
                    self._show_error(str(e))
    """

    BINDINGS = [
        Binding("escape", "cancel", "Cancel", show=True),
        Binding("ctrl+s", "submit", "Submit", show=True, priority=True),
    ]

    def _show_error(self, message: str) -> None:
        """Show an error message."""
        error_display = self.query_one("#error-display", Static)
        error_display.update(f"[red]Error: {message}[/]")
        error_display.add_class("visible")

    def _hide_error(self) -> None:
        """Hide the error display."""
        error_display = self.query_one("#error-display", Static)
        error_display.update("")
        error_display.remove_class("visible")

    def action_cancel(self) -> None:
        """Cancel and dismiss the modal."""
        self.dismiss(None)

    @on(Input.Changed)
    def on_input_changed(self, event: Input.Changed) -> None:
        """Auto-hide error when any input changes."""
        self._hide_error()

    @on(TextArea.Changed)
    def on_textarea_changed(self, event: TextArea.Changed) -> None:
        """Auto-hide error when any textarea changes."""
        self._hide_error()
