"""Tui — thin convenience wrapper for haiv command authors.

This class exists purely for ergonomics. It holds pre-loaded dependencies
(client, paths, settings) so command authors can write simple calls like
ctx.tui.mind_launch(mind) without assembling dependencies themselves.

ALL real logic lives in helpers.py. Every method here should be a one-line
passthrough that forwards to a helpers.py function with the appropriate
dependencies. If you're adding a new capability, put the logic in helpers.py
first, then add a passthrough here.

The TUI application (haiv-tui) calls helpers.py functions directly — it does
not use this class. This keeps the app decoupled from the dependency bag.

terminal.py (TerminalManager) encapsulates WezTerm specifics — tab naming
conventions, pane splitting, parking. Helpers may take a TerminalManager as
a dependency but should not leak WezTerm details to their own callers.
"""

from __future__ import annotations

from pathlib import Path
from typing import Callable, TypeVar

from haiv.helpers.sessions import Session
from haiv.helpers.tui import helpers
from haiv.helpers.tui.commands import tui_bounce, tui_restart
from haiv.helpers.tui.TuiClient import TuiClient
from haiv.helpers.tui.TuiModel import TuiModel
from haiv.helpers.tui.terminal import TerminalManager
from haiv.settings import HaivSettings
from haiv.wrappers.git import Git
from haiv.wrappers.wezterm import WezTerm

T = TypeVar("T")


class Tui:
    """Convenience facade for TUI operations.

    Pre-loads dependencies at construction so call sites are simple.
    See module docstring — no logic belongs here.
    """

    def __init__(
        self,
        haiv_root: Path,
        settings: HaivSettings,
        client: TuiClient | None,
        sessions_file: Path,
    ) -> None:
        wezterm = WezTerm(settings.wezterm_command)
        self._terminal = TerminalManager(wezterm, haiv_root, settings.tui_command)
        self._haiv_root = haiv_root
        self._git = Git(haiv_root, quiet=True)
        self._client = client
        self._sessions_file = sessions_file

    def _require_client(self) -> TuiClient:
        if self._client is None:
            raise RuntimeError("Tui client is required but was not provided")
        return self._client

    def try_with_client(self, fn: Callable[[TuiClient], T]) -> T | None:
        """Run fn with the TUI client if the server is reachable.

        Returns the result of fn, or None if the server is unavailable.
        """
        if self._client is None:
            return None
        try:
            return fn(self._client)
        except ConnectionError:
            return None

    def start(self) -> None:
        """Ensure the haiv workspace exists."""
        helpers.workspace_start(self._terminal)

    def read(self) -> TuiModel:
        """Read the current TUI state."""
        return self._require_client().read()

    def sessions_refresh(self) -> None:
        """Read sessions from disk and push into the TUI model.

        No-op if the TUI server is not running.
        """
        self.try_with_client(lambda c: helpers.sessions_refresh(c, self._sessions_file, git=self._git))

    def mind_try_send_text(self, mind_name: str, text: str, *, submit: bool = False) -> bool:
        """Send text to a mind's pane, returning whether it was found."""
        return helpers.mind_try_send_text(self._terminal, mind_name, text, submit=submit)

    def mind_send_text(self, mind_name: str, text: str, *, submit: bool = False) -> None:
        """Send text to a mind's pane, raising if not found."""
        helpers.mind_send_text(self._terminal, mind_name, text, submit=submit)

    def mind_close_pane(self, mind_name: str) -> None:
        """Close a parked mind's pane."""
        helpers.mind_close_pane(self._terminal, mind_name)

    def restart(self) -> None:
        """Send a restart command to the TUI."""
        tui_restart(self._require_client())

    def bounce(self) -> None:
        """Send a bounce command to the TUI."""
        tui_bounce(self._require_client())

    def mind_launch(
        self,
        mind_name: str,
        *,
        task: str | None = None,
        parent_id: str = "",
    ) -> Session:
        """Put a mind in the hud — switching, launching, or restarting as needed."""
        return helpers.mind_launch(
            self._terminal, self._require_client(), self._sessions_file,
            mind_name, self._haiv_root, task=task, parent_id=parent_id,
            git=self._git,
        )

