"""Mode selection screen — choose Walkthrough, Drill, or Practice."""

from __future__ import annotations

from rich.text import Text
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.openings.models import Opening
from chess_cli.main import DIFFICULTY_CHOICES
from chess_cli.settings import load_settings, save_settings
from chess_cli.tui.screens.menu_widgets import MenuOption


_BAR_WIDTH = 20


class OpeningModeScreen(Screen):
    """Choose how to learn a selected opening."""

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

#mode-container {
    width: 60;
    height: auto;
    border: heavy $primary;
    padding: 2 3;
    background: $surface;
}

#mode-title {
    text-align: center;
    width: 100%;
    color: $text;
}

#mode-description {
    text-align: center;
    width: 100%;
    height: 1;
    color: $text-muted;
    margin-bottom: 2;
}

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

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

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

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

#difficulty-display {
    margin-top: 1;
}

#difficulty-hint {
    width: 100%;
    height: 1;
    color: $text-muted;
    padding: 0 1;
    text-align: center;
    margin-top: 1;
}

#opt-undo-button {
    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"),
    ]

    focus_index: reactive[int] = reactive(0)
    difficulty_index: reactive[int] = reactive(5)  # Intermediate default
    show_undo_button: reactive[bool] = reactive(False)

    _FOCUSABLE = ["btn-walkthrough", "btn-drill", "btn-practice", "difficulty-display", "opt-undo-button"]

    def __init__(self, opening: Opening) -> None:
        super().__init__()
        self.opening = opening

    def compose(self) -> ComposeResult:
        yield Header(show_clock=False)
        with Vertical(id="mode-container"):
            yield Static(f"♞  {self.opening.name}", id="mode-title")
            yield Static(self.opening.description, id="mode-description")
            yield Static("── Choose Mode ────────────────────────", classes="section-header")
            yield Button("📖 Walkthrough", id="btn-walkthrough", variant="primary")
            yield Button("🎯 Drill", id="btn-drill")
            yield Button("⚔ Practice", id="btn-practice")
            yield Static("── Practice Difficulty ─────────────────", classes="section-header")
            yield MenuOption("Difficulty", "difficulty-display")
            yield Static("\u25c0 \u25b6 to adjust difficulty", id="difficulty-hint")
            yield Static("\u2500\u2500 Practice Settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500", classes="section-header")
            yield MenuOption("Show Undo Btn", "opt-undo-button")
        yield Footer()

    def on_mount(self) -> None:
        settings = load_settings()
        self.show_undo_button = settings.show_undo_button
        self._render_difficulty()
        self._render_undo_toggle()
        self._update_highlight()

    def _update_highlight(self) -> None:
        any_button_focused = False
        for i, fid in enumerate(self._FOCUSABLE):
            try:
                widget = self.query_one(f"#{fid}")
                if isinstance(widget, Button):
                    if i == self.focus_index:
                        widget.focus()
                        widget.add_class("highlighted")
                        any_button_focused = True
                    else:
                        widget.remove_class("highlighted")
                elif isinstance(widget, MenuOption):
                    widget.highlighted = i == self.focus_index
            except Exception:
                pass
        if not any_button_focused:
            self.set_focus(None)

    def _render_difficulty(self) -> None:
        from chess_cli.engine import DIFFICULTY_PRESETS

        idx = self.difficulty_index
        name = DIFFICULTY_CHOICES[idx]
        elo = DIFFICULTY_PRESETS[name]
        total = len(DIFFICULTY_CHOICES)

        filled = int((idx + 1) / total * _BAR_WIDTH)
        text = Text()
        for i in range(_BAR_WIDTH):
            if i < filled:
                frac = i / _BAR_WIDTH
                if frac < 0.5:
                    r = int(100 + 155 * (frac * 2))
                    g = 200
                else:
                    r = 255
                    g = int(200 * (1 - (frac - 0.5) * 2))
                text.append("\u2588", style=f"rgb({r},{g},50)")
            else:
                text.append("\u2591", style="dim")

        text.append(f" {name.capitalize()}")
        if elo is None:
            text.append(" (max)", style="dim")
        else:
            text.append(f" ({elo})", style="dim")

        try:
            self.query_one("#difficulty-display", MenuOption).set_value(text)
        except Exception:
            pass

    def _render_undo_toggle(self) -> None:
        label = "Yes" if self.show_undo_button else "No"
        value = f"\u25c0 {label} \u25b6"
        if self.show_undo_button:
            text = Text()
            text.append(value, style="bold green")
        else:
            text = value
        try:
            self.query_one("#opt-undo-button", MenuOption).set_value(text)
        except Exception:
            pass

    def watch_focus_index(self, _value: int) -> None:
        self._update_highlight()
        self._render_undo_toggle()
        self._render_difficulty()

    def watch_difficulty_index(self, _value: int) -> None:
        self._render_difficulty()

    def watch_show_undo_button(self, value: bool) -> None:
        self._render_undo_toggle()
        settings = load_settings()
        settings.show_undo_button = value
        save_settings(settings)

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

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

    def action_cycle_left(self) -> None:
        fid = self._FOCUSABLE[self.focus_index]
        if fid == "difficulty-display":
            self.difficulty_index = (self.difficulty_index - 1) % len(DIFFICULTY_CHOICES)
        elif fid == "opt-undo-button":
            self.show_undo_button = not self.show_undo_button

    def action_cycle_right(self) -> None:
        fid = self._FOCUSABLE[self.focus_index]
        if fid == "difficulty-display":
            self.difficulty_index = (self.difficulty_index + 1) % len(DIFFICULTY_CHOICES)
        elif fid == "opt-undo-button":
            self.show_undo_button = not self.show_undo_button

    def action_select(self) -> None:
        if self.focus_index >= len(self._FOCUSABLE):
            return
        fid = self._FOCUSABLE[self.focus_index]
        if fid == "btn-walkthrough":
            self._start_walkthrough()
        elif fid == "btn-drill":
            self._start_drill()
        elif fid == "btn-practice":
            self._start_practice()
        elif fid == "difficulty-display":
            self.action_cycle_right()
        elif fid == "opt-undo-button":
            self.show_undo_button = not self.show_undo_button

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "btn-walkthrough":
            self._start_walkthrough()
        elif event.button.id == "btn-drill":
            self._start_drill()
        elif event.button.id == "btn-practice":
            self._start_practice()

    def _start_walkthrough(self) -> None:
        from chess_cli.tui.screens.walkthrough import WalkthroughScreen
        self.app.push_screen(WalkthroughScreen(self.opening))

    def _start_drill(self) -> None:
        from chess_cli.tui.screens.drill import DrillScreen
        self.app.push_screen(DrillScreen(self.opening))

    def _start_practice(self) -> None:
        from chess_cli.tui.screens.practice import PracticeScreen
        difficulty = DIFFICULTY_CHOICES[self.difficulty_index]
        self.app.push_screen(
            PracticeScreen(
                self.opening,
                difficulty=difficulty,
                show_undo_button=self.show_undo_button,
            )
        )

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