"""Bot selection screen — browse and pick a Lichess bot to play against."""

from __future__ import annotations

from typing import TYPE_CHECKING

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
from textual.containers import Vertical
from textual import work

if TYPE_CHECKING:
    from chess_cli.lichess import BotInfo, LichessClient


class BotItem(Static):
    """A selectable bot in the list."""

    highlighted = reactive(False)

    DEFAULT_CSS = """
    BotItem {
        width: 100%;
        height: 3;
        padding: 0 2;
        margin-bottom: 1;
        content-align: left middle;
    }
    BotItem.highlighted {
        border-left: thick white;
    }
    """

    def __init__(self, bot: BotInfo) -> None:
        super().__init__()
        self.bot = bot

    def render(self) -> Text:
        text = Text()
        style = "bold" if self.highlighted else ""
        rating = self.bot.rating
        if rating >= 2500:
            rating_style = "bold red"
        elif rating >= 2000:
            rating_style = "bold yellow"
        elif rating >= 1500:
            rating_style = "bold green"
        else:
            rating_style = "dim"
        text.append(f" \u2654 ", style=style)
        text.append(self.bot.username, style=style)
        text.append("  (", style="dim")
        text.append(str(rating), style=rating_style)
        text.append(")", style="dim")
        if self.bot.description:
            text.append(f"\n   {self.bot.description}", style="dim")
        else:
            text.append("\n   ", style="dim")
        return text

    def watch_highlighted(self, value: bool) -> None:
        self.set_class(value, "highlighted")


class BotSelectScreen(Screen):
    """Screen listing online Lichess bots."""

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

#bot-container {
    width: 68;
    height: auto;
    max-height: 80%;
    border: heavy $primary;
    padding: 2 3;
    background: $surface;
    overflow-y: auto;
}

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

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

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

#bot-loading {
    width: 100%;
    height: 3;
    content-align: center middle;
    color: $text-muted;
}
"""

    BINDINGS = [
        ("up", "focus_prev", "Up"),
        ("down", "focus_next", "Down"),
        ("enter", "select", "Select"),
        ("escape", "back", "Back"),
        ("q", "back", "Back"),
    ]

    focus_index: reactive[int] = reactive(0)

    def __init__(self, client: LichessClient) -> None:
        super().__init__()
        self._client = client
        self._bots: list[BotInfo] = []

    def compose(self) -> ComposeResult:
        yield Header(show_clock=False)
        with Vertical(id="bot-container"):
            yield Static(
                "\u265a  S E L E C T   A   B O T", id="bot-title"
            )
            yield Static(
                "\u2500\u2500 Online Bots \u2500\u2500\u2500\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 Static("Loading bots...", id="bot-loading")
            yield Static(
                "\u2191\u2193 navigate \u00b7 Enter select \u00b7 q back",
                id="bot-hint",
            )
        yield Footer()

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

    @work(thread=True)
    def _fetch_bots(self) -> None:
        try:
            bots = self._client.get_online_bots(max_count=50)
            bots.sort(key=lambda b: b.rating)
            self.app.call_from_thread(self._on_bots_loaded, bots)
        except Exception as e:
            self.app.call_from_thread(self._on_bots_error, str(e))

    def _on_bots_loaded(self, bots: list[BotInfo]) -> None:
        self._bots = bots
        loading = self.query_one("#bot-loading", Static)
        if not bots:
            loading.update("No bots online. Try again later.")
            return
        loading.remove()
        container = self.query_one("#bot-container", Vertical)
        hint = self.query_one("#bot-hint", Static)
        for bot in bots:
            container.mount(BotItem(bot), before=hint)
        self._update_highlight()

    def _on_bots_error(self, error: str) -> None:
        loading = self.query_one("#bot-loading", Static)
        loading.update(f"Error loading bots: {error}")

    def _update_highlight(self) -> None:
        items = self.query(BotItem)
        for i, item in enumerate(items):
            item.highlighted = i == self.focus_index

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

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

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

    def action_select(self) -> None:
        if self._bots:
            self.dismiss(self._bots[self.focus_index])

    def action_back(self) -> None:
        self.dismiss(None)
