"""SkilarkApp: k9s-style full-screen terminal UI for Skilark."""

import time
from pathlib import Path

from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Container, Horizontal
from textual.screen import ModalScreen
from textual.widgets import Static

from skilark_cli import __version__
from skilark_cli.client import SkilarkClient
from skilark_cli.config_store import ConfigStore

CSS_PATH = Path(__file__).parent / "app.tcss"

TAB_LABELS = ["Drill", "Signals", "Jobs", "Profile"]

# Legacy config values → Textual theme names (for backward compat).
_LEGACY_THEME_MAP = {"dark": "textual-dark", "light": "textual-light"}


class HeaderBar(Static):
    """Top bar with app title and tab labels."""

    def __init__(self, active_index: int = 0) -> None:
        super().__init__(id="header-bar")
        self._active = active_index

    def set_active(self, index: int) -> None:
        self._active = index
        self._refresh_content()

    def on_mount(self) -> None:
        self._refresh_content()

    def _refresh_content(self) -> None:
        parts = [f"Skilark v{__version__}    "]
        for i, label in enumerate(TAB_LABELS):
            if i == self._active:
                parts.append(f"[reverse] [{i + 1}]{label} [/reverse]  ")
            else:
                parts.append(f"[{i + 1}]{label}  ")
        self.update("".join(parts))


_FOOTER_GLOBAL = (
    "[bold]q[/bold] Quit  "
    "[bold]?[/bold] Help  "
    "[bold]^p[/bold] palette"
)


def _bindings_to_text(bindings: list) -> str:
    """Render a list of Binding objects as styled text."""
    parts = []
    for b in bindings:
        if b.show:
            key_display = b.key.replace("ctrl+", "^")
            parts.append(f"[bold]{key_display}[/bold] {b.description}")
    return "  ".join(parts)


class FooterBar(Horizontal):
    """Footer with context-sensitive bindings (left) and global keys (right)."""

    def __init__(self) -> None:
        super().__init__(id="footer-bar")
        self._hint_active = False

    def compose(self) -> ComposeResult:
        yield Static("", id="footer-left")
        yield Static(_FOOTER_GLOBAL, id="footer-right")

    def set_context_bindings(self, bindings: list) -> None:
        """Update left side with bindings from the active pane."""
        if self._hint_active:
            return
        self.query_one("#footer-left", Static).update(_bindings_to_text(bindings))

    def show_hint(self, text: str) -> None:
        """Temporarily replace footer content with a hint message."""
        self._hint_active = True
        self.query_one("#footer-left", Static).update(text)
        self.query_one("#footer-right", Static).update("")

    def reset(self) -> None:
        """Restore footer after hint."""
        self._hint_active = False
        self.query_one("#footer-right", Static).update(_FOOTER_GLOBAL)


class HelpScreen(ModalScreen):
    """Modal help screen that blocks all other input."""

    BINDINGS = [
        Binding("escape", "dismiss", "Close", show=False),
        Binding("question_mark", "dismiss", "Close", show=False),
    ]

    def compose(self) -> ComposeResult:
        yield Container(
            Static(
                "[bold]Keyboard Shortcuts[/bold]\n\n"
                "  [bold]1[/bold]  Drill (daily challenges)\n"
                "  [bold]2[/bold]  Market Signals\n"
                "  [bold]3[/bold]  Find My Fit (job search)\n"
                "  [bold]4[/bold]  Profile & Stats\n\n"
                "  [bold]t[/bold]      Cycle themes\n"
                "  [bold]qq[/bold] Quit (press twice)\n"
                "  [bold]?[/bold]  Toggle this help\n\n"
                "Press [bold]Esc[/bold] or [bold]?[/bold] to close.",
                id="help-panel",
            ),
            id="help-overlay",
        )



class SkilarkApp(App):
    """Root application for the Skilark TUI."""

    TITLE = "Skilark"
    CSS_PATH = CSS_PATH

    BINDINGS = [
        Binding("1", "switch_tab(0)", "Drill", show=False, priority=True),
        Binding("2", "switch_tab(1)", "Signals", show=False, priority=True),
        Binding("3", "switch_tab(2)", "Jobs", show=False, priority=True),
        Binding("4", "switch_tab(3)", "Profile", show=False, priority=True),
        Binding("t", "toggle_theme", "Theme", show=False, priority=True),
        Binding("q", "quit_app", "Quit", show=False, priority=True),
        Binding("question_mark", "toggle_help", "Help", show=False, priority=True),
    ]

    def __init__(
        self,
        client: SkilarkClient | None = None,
        topics: list[str] | None = None,
        coding_language: str | None = None,
        theme: str | None = None,
        config_store: ConfigStore | None = None,
        code_cache_dir: Path | None = None,
        autosave_delay: float | None = None,
        **kwargs,
    ) -> None:
        super().__init__(**kwargs)
        self.client = client
        self.topics = topics or []
        self.coding_language = coding_language
        self._config_store = config_store
        self.code_cache_dir = code_cache_dir
        self.autosave_delay = autosave_delay
        self._active_tab = 0  # Start on Drill
        self._quit_pressed_at: float = 0.0
        self._quit_timeout = 2.0  # seconds to confirm quit
        # Resolve legacy "dark"/"light" to Textual theme names.
        resolved = _LEGACY_THEME_MAP.get(theme, theme) if theme else "textual-dark"
        self.theme = resolved

    def compose(self) -> ComposeResult:
        yield HeaderBar(active_index=self._active_tab)
        yield Container(id="content")
        yield FooterBar()

    async def on_mount(self) -> None:
        await self._switch_screen(self._active_tab)

    async def action_switch_tab(self, index: int) -> None:
        # Block tab switching while help modal is open
        if isinstance(self.screen, HelpScreen):
            return
        if index == self._active_tab:
            return
        self._active_tab = index
        self.query_one(HeaderBar).set_active(index)
        await self._switch_screen(index)

    async def _switch_screen(self, index: int) -> None:
        content = self.query_one("#content")
        await content.remove_children()

        pane = None
        if index == 0:
            from skilark_cli.tui.screens.drill import DrillPane

            pane = DrillPane(
                client=self.client,
                topics=self.topics,
                coding_language=self.coding_language,
                code_cache_dir=self.code_cache_dir,
                autosave_delay=self.autosave_delay,
            )
        elif index == 1:
            from skilark_cli.tui.screens.signals import SignalsPane

            pane = SignalsPane(client=self.client)
        elif index == 2:
            from skilark_cli.tui.screens.jobs import JobsPane

            pane = JobsPane(client=self.client)
        elif index == 3:
            from skilark_cli.tui.screens.profile import ProfilePane

            pane = ProfilePane(client=self.client)

        if pane is not None:
            await content.mount(pane)
            bindings = getattr(pane, "BINDINGS", [])
            self.query_one(FooterBar).set_context_bindings(bindings)
        else:
            label = TAB_LABELS[index]
            await content.mount(
                Static(
                    f"\n\n[bold]{label}[/bold]\n\nComing soon.",
                    classes="placeholder-screen",
                )
            )
            self.query_one(FooterBar).set_context_bindings([])

    def action_quit_app(self) -> None:
        if isinstance(self.screen, HelpScreen):
            return
        now = time.monotonic()
        if now - self._quit_pressed_at <= self._quit_timeout:
            self.exit()
        else:
            self._quit_pressed_at = now
            self._show_quit_hint()

    def _show_quit_hint(self) -> None:
        """Flash 'Press q again to quit' in the footer, then revert."""
        self.query_one(FooterBar).show_hint(
            "[bold reverse] Press q again to quit [/bold reverse]"
        )
        self.set_timer(self._quit_timeout, self._revert_quit_hint)

    def _revert_quit_hint(self) -> None:
        try:
            self.query_one(FooterBar).reset()
        except Exception:
            pass

    def watch_theme(self, theme_name: str) -> None:
        """Persist theme whenever it changes — from t key, palette, or any source."""
        if self._config_store:
            self._config_store.update_theme(theme_name)

    def action_toggle_theme(self) -> None:
        if isinstance(self.screen, HelpScreen):
            return
        themes = sorted(self.available_themes)
        try:
            idx = themes.index(self.theme)
        except ValueError:
            idx = -1
        self.theme = themes[(idx + 1) % len(themes)]

    def action_toggle_help(self) -> None:
        if isinstance(self.screen, HelpScreen):
            self.screen.dismiss()
        else:
            self.push_screen(HelpScreen())
