"""BrowserView — drill topic/category browser with side-by-side DataTables."""

from __future__ import annotations

from dataclasses import dataclass

from textual.app import ComposeResult
from textual.containers import Horizontal, Vertical
from textual.message import Message
from textual.widgets import DataTable, Static


class BrowserView(Horizontal):
    """Drill browser showing quiz topics and coding categories side by side."""

    @dataclass
    class TopicSelected(Message):
        topic: str

    @dataclass
    class CategorySelected(Message):
        category: str

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self.quiz_items: list[dict] = []
        self.category_items: list[dict] = []
        self._configured_topics: list[str] = []
        self._show_all_topics: bool = False
        self._show_all_categories: bool = False
        self._visible_quiz: list[dict] = []
        self._visible_cats: list[dict] = []

    def compose(self) -> ComposeResult:
        with Vertical(id="quiz-box", classes="browser-box"):
            yield Static("Quiz Topics", classes="browser-section-header")
            yield DataTable(id="quiz-topic-table")
            yield Static("", id="quiz-show-all")
        with Vertical(id="coding-box", classes="browser-box"):
            yield Static("Coding Problems", classes="browser-section-header")
            yield DataTable(id="coding-category-table")
            yield Static("", id="coding-show-all")

    def on_mount(self) -> None:
        quiz_table = self.query_one("#quiz-topic-table", DataTable)
        quiz_table.cursor_type = "row"
        quiz_table.add_columns("Topic", "Progress", "%", "Acc")

        code_table = self.query_one("#coding-category-table", DataTable)
        code_table.cursor_type = "row"
        code_table.add_columns("Category", "Progress", "%")

    def load(
        self,
        topics: list[dict],
        categories: list[dict],
        configured_topics: list[str],
    ) -> None:
        """Populate the browser with data from API."""
        self._configured_topics = [t.lower() for t in configured_topics]
        configured = [t for t in topics if t["topic"].lower() in self._configured_topics]
        unconfigured = [t for t in topics if t["topic"].lower() not in self._configured_topics]
        configured.sort(key=lambda t: t["topic"])
        unconfigured.sort(key=lambda t: t["topic"])
        self.quiz_items = configured + unconfigured
        self.category_items = sorted(categories, key=lambda c: c["category"])

        self._render_topic_table()
        self._render_category_table()

    def _render_topic_table(self) -> None:
        table = self.query_one("#quiz-topic-table", DataTable)
        table.clear()

        items = self.quiz_items
        configured_count = sum(
            1 for t in items if t["topic"].lower() in self._configured_topics
        )

        visible = items if self._show_all_topics else items[:max(configured_count, 4)]
        self._visible_quiz = list(visible)

        for t in visible:
            marker = " \u2605" if t["topic"].lower() in self._configured_topics else ""
            name = f"{t['topic']}{marker}"
            pct = (t["completed"] / t["total"] * 100) if t["total"] > 0 else 0
            acc = f"{t['accuracy']:.0%}" if t["completed"] > 0 else "\u2014"
            progress = f"{t['completed']}/{t['total']}"
            table.add_row(name, progress, f"{pct:.0f}%", acc)

        show_all = self.query_one("#quiz-show-all", Static)
        hidden = len(items) - len(visible)
        if hidden > 0 and not self._show_all_topics:
            show_all.update(f"[dim]  \u25b8 Show all ({len(items)} topics)[/dim]")
        else:
            show_all.update("")

    def _render_category_table(self) -> None:
        table = self.query_one("#coding-category-table", DataTable)
        table.clear()

        items = self.category_items
        visible = items if self._show_all_categories else items[:4]
        self._visible_cats = list(visible)

        for c in visible:
            pct = (c["solved"] / c["total"] * 100) if c["total"] > 0 else 0
            progress = f"{c['solved']}/{c['total']}"
            table.add_row(c["category"], progress, f"{pct:.0f}%")

        show_all = self.query_one("#coding-show-all", Static)
        hidden = len(items) - len(visible)
        if hidden > 0 and not self._show_all_categories:
            show_all.update(f"[dim]  \u25b8 Show all ({len(items)} categories)[/dim]")
        else:
            show_all.update("")

    def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
        """Handle Enter on a row in either table."""
        if event.data_table.id == "quiz-topic-table":
            idx = event.cursor_row
            if idx < len(self._visible_quiz):
                self.post_message(self.TopicSelected(self._visible_quiz[idx]["topic"]))
        elif event.data_table.id == "coding-category-table":
            idx = event.cursor_row
            if idx < len(self._visible_cats):
                self.post_message(self.CategorySelected(self._visible_cats[idx]["category"]))

    def toggle_show_all(self) -> None:
        """Toggle show-all for the currently focused section."""
        focused = self.app.focused
        if focused and getattr(focused, "id", "") == "quiz-topic-table":
            self._show_all_topics = not self._show_all_topics
            self._render_topic_table()
        elif focused and getattr(focused, "id", "") == "coding-category-table":
            self._show_all_categories = not self._show_all_categories
            self._render_category_table()
        else:
            # No DataTable focused — do nothing to avoid surprising toggles
            return

    def select_current(self) -> None:
        """Programmatically select the highlighted item in the focused table."""
        focused = self.app.focused
        if isinstance(focused, DataTable) and focused.cursor_row is not None:
            focused.action_select_cursor()
