"""ASCII art banner widget for the ALiCE TUI with CRT warm-up effect."""

from __future__ import annotations

from typing import TYPE_CHECKING

from textual.color import Color
from textual.widgets import Static

from alice_cli.personality import BANNER

if TYPE_CHECKING:
    from collections.abc import Callable

# CRT warm-up sequence: (delay_seconds, opacity_percent, text_style)
# Simulates phosphor tubes warming up over ~1.2 seconds.
# Opacity is applied via tint; style adds dim/bold variation.
_WARMUP: list[tuple[float, int, str]] = [
    # --- dark / off ---
    (0.00, 0, "dim"),
    # --- first faint glow ---
    (0.06, 10, "dim"),
    (0.10, 20, "dim"),
    (0.14, 15, "dim"),
    (0.17, 25, "dim"),
    # --- first bright flash ---
    (0.20, 60, "bold"),
    (0.23, 30, "dim"),
    (0.26, 15, "dim"),
    # --- second attempt ---
    (0.30, 35, ""),
    (0.33, 50, ""),
    (0.36, 40, "dim"),
    (0.39, 55, ""),
    # --- rapid flicker burst ---
    (0.42, 70, "bold"),
    (0.44, 35, "dim"),
    (0.46, 75, "bold"),
    (0.48, 40, "dim"),
    (0.50, 80, "bold"),
    (0.52, 45, ""),
    (0.54, 85, "bold"),
    # --- stabilising ---
    (0.58, 65, ""),
    (0.62, 80, "bold"),
    (0.66, 70, ""),
    (0.70, 85, "bold"),
    (0.74, 75, ""),
    (0.78, 90, "bold"),
    (0.82, 80, ""),
    (0.86, 92, "bold"),
    (0.90, 85, ""),
    (0.94, 95, "bold"),
    # --- fully on ---
    (1.00, 98, "bold"),
    (1.10, 100, "bold"),
]

# The amber color used for the tint overlay (matches theme #FFD866).
_AMBER = Color.parse("#FFD866")


class BannerWidget(Static):
    """Static widget displaying the ALiCE ASCII art banner with CRT warm-up."""

    def __init__(self) -> None:
        super().__init__(BANNER, id="banner")

    def on_mount(self) -> None:
        # Start fully dark
        self.styles.opacity = 0.0
        self.styles.text_style = "dim"
        for delay, opacity_pct, style in _WARMUP:
            self.set_timer(delay, self._make_step(opacity_pct, style))

    def _make_step(self, opacity_pct: int, style: str) -> Callable[[], None]:
        """Return a callback that applies one warm-up frame."""

        def _apply() -> None:
            self.styles.opacity = opacity_pct / 100.0
            self.styles.text_style = style or "none"

        return _apply
