"""Investigation header widget.

Displays campaign name, repo name, theme, and progress stats.
Docked to top of the screen with Film Noir styling.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from rich.text import Text
from textual.containers import Horizontal
from textual.reactive import reactive
from textual.widget import Widget
from textual.widgets import Static

if TYPE_CHECKING:
    from textual.app import ComposeResult

    from unfamiliar.tui.themes import ThemeConfig
    from unfamiliar.tui.views import HeaderData


class InvestigationHeader(Widget):
    """Header widget showing campaign info and progress.

    Displays:
    - Campaign name
    - Repository name
    - Theme name
    - Progress stats (completed/total, available)

    Attributes:
        data: Reactive HeaderData to display.
        theme: Theme configuration for colors and vocabulary.

    Note: Styling is defined in noir.tcss, not DEFAULT_CSS, to use theme variables.
    """

    data: reactive[HeaderData | None] = reactive(None)

    def __init__(
        self,
        theme: ThemeConfig,
        data: HeaderData | None = None,
        *,
        name: str | None = None,
        id: str | None = None,
        classes: str | None = None,
    ) -> None:
        """Initialize the header widget.

        Args:
            theme: Theme configuration for colors and vocabulary.
            data: Initial header data to display.
            name: Widget name.
            id: Widget ID.
            classes: Space-separated CSS classes.
        """
        super().__init__(name=name, id=id, classes=classes)
        self.theme = theme
        self.data = data

    def _c(self, key: str) -> str:
        """Shorthand for self.theme.color(key)."""
        return self.theme.color(key)

    def compose(self) -> ComposeResult:
        """Compose the header layout."""
        with Horizontal(classes="header-left"):
            yield Static("", id="header-campaign", classes="campaign-title")
            yield Static("", id="header-repo", classes="repo-name")
        with Horizontal(classes="header-right"):
            yield Static("", id="header-progress", classes="progress-label")

    def _update_children(self) -> None:
        """Update child widgets with current data."""
        campaign_widget = self.query_one("#header-campaign", Static)
        repo_widget = self.query_one("#header-repo", Static)
        progress_widget = self.query_one("#header-progress", Static)

        if self.data is None:
            campaign_widget.update(Text("Loading...", style="bold"))
            repo_widget.update("")
            progress_widget.update("")
            return

        # Campaign title with theme accent color
        campaign_widget.update(
            Text(self.data.campaign_name, style=f"bold {self._c('accent')}")
        )

        # Repository name (muted)
        repo_widget.update(
            Text(f"  [{self.data.repo_name}]", style=self._c("text_muted"))
        )

        # Progress and available count combined on one line
        available_style = (
            f"bold {self._c('success')}" if self.data.available > 0
            else self._c("text_dim")
        )
        stats = Text()
        stats.append(
            f"Progress: {self.data.completed}/{self.data.total}",
            style=self._c("text_muted"),
        )
        stats.append(
            f"  |  Available: {self.data.available}",
            style=available_style,
        )
        progress_widget.update(stats)

    def watch_data(
        self, old_data: HeaderData | None, new_data: HeaderData | None
    ) -> None:
        """React to data changes."""
        # Defer render until children are mounted
        self.call_after_refresh(self._update_children)

    def on_mount(self) -> None:
        """Render initial data on mount."""
        # Defer render until children are mounted
        # (parent on_mount fires before children exist)
        self.call_after_refresh(self._update_children)

    def update_data(self, data: HeaderData) -> None:
        """Update the header with new data.

        Args:
            data: New header data to display.
        """
        self.data = data


__all__ = ["InvestigationHeader"]
