"""Lichess settings screen — configure API token and time control."""

from __future__ import annotations

from textual.app import ComposeResult
from textual.screen import Screen
from textual.reactive import reactive
from textual.widgets import Static, Footer, Header, Button
from textual.containers import Vertical

from chess_cli.tui.screens.menu_widgets import MenuOption, TokenInputModal
from chess_cli.settings import load_settings, save_settings

# ── Constants ────────────────────────────────────────────────────────

TIME_CONTROLS = [
    (300, 0, "5+0"),
    (600, 0, "10+0"),
    (600, 5, "10+5"),
    (900, 10, "15+10"),
    (1800, 0, "30+0"),
    (1800, 20, "30+20"),
]

_FOCUSABLE = ["opt-token", "opt-timecontrol", "btn-back"]


# ── LichessSettingsScreen ────────────────────────────────────────────


class LichessSettingsScreen(Screen):
    """Configure Lichess API token and time control preferences."""

    DEFAULT_CSS = """
LichessSettingsScreen {
    align: center middle;
}

#lichess-container {
    width: 60;
    height: auto;
    max-height: 100%;
    border: heavy $primary;
    padding: 2 3;
    background: $surface;
    overflow-y: auto;
}

#lichess-title {
    text-align: center;
    width: 100%;
    margin-bottom: 2;
}

.section-header {
    width: 100%;
    height: 1;
    color: $text-muted;
    margin: 2 0 1 0;
    padding: 0 1;
}

#token-status {
    width: 100%;
    height: 1;
    color: $text-muted;
    padding: 0 1 0 17;
}

#btn-back {
    width: 100%;
    margin-top: 1;
}
"""

    BINDINGS = [
        ("up", "focus_prev", "Up"),
        ("down", "focus_next", "Down"),
        ("left", "cycle_left", "◀"),
        ("right", "cycle_right", "▶"),
        ("enter", "select", "Select"),
        ("escape", "back", "Back"),
        ("q", "back", "Back"),
    ]

    time_control_index: reactive[int] = reactive(1)
    focus_index: reactive[int] = reactive(0)

    def compose(self) -> ComposeResult:
        yield Header(show_clock=False)
        with Vertical(id="lichess-container"):
            yield Static("🌐  Lichess Settings", id="lichess-title")
            yield Static("── API Token ──────────────────────────", classes="section-header")
            yield Static("", id="token-status")
            yield MenuOption("API Token", "opt-token")
            yield Static("── Time Control ───────────────────────", classes="section-header")
            yield MenuOption("Time Control", "opt-timecontrol")
            yield Static("────────────────────────────────────────", classes="section-header")
            yield Button("← Back", id="btn-back")
        yield Footer()

    # ------------------------------------------------------------------
    # Lifecycle
    # ------------------------------------------------------------------

    def on_mount(self) -> None:
        settings = load_settings()
        self.time_control_index = settings.lichess_time_control_index
        self._render_token_status()
        self._render_time_control()
        self._update_highlight()

    # ------------------------------------------------------------------
    # Rendering helpers
    # ------------------------------------------------------------------

    def _render_token_status(self) -> None:
        settings = load_settings()
        has_token = bool(settings.lichess_api_token)
        from rich.text import Text

        text = Text()
        if has_token:
            text.append("✓ token set", style="green")
        else:
            text.append("✗ no token", style="red")
        try:
            self.query_one("#token-status", Static).update(text)
        except Exception:
            pass
        # Update the menu option label
        try:
            label = "✓ token saved" if has_token else "▸ Set token..."
            self.query_one("#opt-token", MenuOption).set_value(label)
        except Exception:
            pass

    def _render_time_control(self) -> None:
        _, _, label = TIME_CONTROLS[self.time_control_index]
        try:
            self.query_one("#opt-timecontrol", MenuOption).set_value(
                f"◀ {label} ▶"
            )
        except Exception:
            pass

    # ------------------------------------------------------------------
    # Focus navigation
    # ------------------------------------------------------------------

    def _update_highlight(self) -> None:
        focusable = _FOCUSABLE
        for opt_id in ["opt-token", "opt-timecontrol"]:
            try:
                widget = self.query_one(f"#{opt_id}", MenuOption)
                widget.highlighted = opt_id in focusable and focusable.index(opt_id) == self.focus_index
            except Exception:
                pass
        # Button
        any_button_focused = False
        try:
            btn = self.query_one("#btn-back", Button)
            idx = focusable.index("btn-back")
            if idx == self.focus_index:
                btn.focus()
                btn.add_class("highlighted")
                any_button_focused = True
            else:
                btn.remove_class("highlighted")
        except Exception:
            pass
        if not any_button_focused:
            self.set_focus(None)

    def watch_focus_index(self, value: int) -> None:
        self._update_highlight()

    def action_focus_prev(self) -> None:
        total = len(_FOCUSABLE)
        self.focus_index = (self.focus_index - 1) % total

    def action_focus_next(self) -> None:
        total = len(_FOCUSABLE)
        self.focus_index = (self.focus_index + 1) % total

    def action_cycle_left(self) -> None:
        self._cycle_focused(-1)

    def action_cycle_right(self) -> None:
        self._cycle_focused(1)

    def _cycle_focused(self, direction: int) -> None:
        if self.focus_index >= len(_FOCUSABLE):
            return
        current_id = _FOCUSABLE[self.focus_index]
        if current_id == "opt-timecontrol":
            self.time_control_index = (self.time_control_index + direction) % len(TIME_CONTROLS)

    # ------------------------------------------------------------------
    # Watchers
    # ------------------------------------------------------------------

    def watch_time_control_index(self, value: int) -> None:
        self._render_time_control()
        settings = load_settings()
        settings.lichess_time_control_index = value
        save_settings(settings)

    # ------------------------------------------------------------------
    # Actions
    # ------------------------------------------------------------------

    def action_select(self) -> None:
        if self.focus_index >= len(_FOCUSABLE):
            return
        current_id = _FOCUSABLE[self.focus_index]
        if current_id == "opt-token":
            self._open_token_input()
        elif current_id == "opt-timecontrol":
            self._cycle_focused(1)
        elif current_id == "btn-back":
            self.app.pop_screen()

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "btn-back":
            self.app.pop_screen()

    def _open_token_input(self) -> None:
        def on_token(token: str) -> None:
            if token:
                settings = load_settings()
                settings.lichess_api_token = token
                save_settings(settings)
                self.notify("API token saved.", severity="information")
            self._render_token_status()

        self.app.push_screen(TokenInputModal(), callback=on_token)

    def action_back(self) -> None:
        self.app.pop_screen()
