#!/usr/bin/env python3
"""Widget Gallery - Imperial CRT Theme Showcase.

A standalone TUI to preview all styled widgets in the Imperial CRT theme.
Includes live theme switching via Forge World presets.

Run with: python examples/widget_gallery.py
"""

import os
from pathlib import Path

from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Horizontal, Vertical, VerticalScroll
from textual.widgets import (
    Button,
    Checkbox,
    DataTable,
    Footer,
    Header,
    Input,
    Label,
    ProgressBar,
    RadioButton,
    RadioSet,
    Rule,
    Select,
    Static,
    Switch,
)
from textual.reactive import reactive

# Import the theme
import sys
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from styrene.themes.color_cascade import (
    ColorCascade,
    FORGE_WORLD_PRESETS,
    FORGE_WORLD_ORDER,
    list_presets,
    generate_all_themes,
)
from styrene.widgets.highlighted_panel import (
    HighlightedPanel,
    set_color_cascade,
    get_color_cascade,
)
from styrene.themes.semantic import (
    format_status,
    format_button_label,
    SemanticSymbols,
)
from styrene.widgets.animated_status import (
    AnimatedStatusIndicator,
    ScanningBar,
    PulsingIndicator,
)


class ThemePreviewPanel(Static):
    """A panel showing the current theme's color derivations."""

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self._content = ""

    def render(self) -> str:
        return self._content

    def update_preview(self, cascade: ColorCascade) -> None:
        """Update the preview with new cascade colors."""
        lines = [
            f"[bold]Phosphex:[/] [{cascade.phosphex}]{cascade.phosphex}[/]",
            f"[bold]Preset:[/] {cascade.preset_name}",
            "",
            f"[{cascade.bright}]Bright[/] [{cascade.medium}]Medium[/] [{cascade.dim}]Dim[/] [{cascade.dark}]Dark[/]",
        ]
        self._content = "\n".join(lines)
        self.refresh()


class LiveThemedPanel(Static):
    """A panel that re-renders when the theme changes."""

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self._cascade = get_color_cascade()

    def render(self) -> str:
        cascade = self._cascade
        lines = [
            f"[{cascade.bright}]BRIGHT TEXT[/]",
            f"[{cascade.medium}]MEDIUM TEXT[/]",
            f"[{cascade.dim}]DIM TEXT[/]",
            "────────────────────",
            f"[{cascade.corner_highlight}]Corner: {cascade.corner_highlight}[/]",
            f"[{cascade.border_bright}]Border: {cascade.border_bright}[/]",
        ]
        return "\n".join(lines)

    def update_theme(self, cascade: ColorCascade) -> None:
        """Update with new cascade and re-render."""
        self._cascade = cascade
        self.refresh()


class WidgetGalleryApp(App[None]):
    """Widget gallery showcasing the Imperial CRT theme with live theme switching."""

    TITLE = "WIDGET GALLERY"
    SUB_TITLE = "Forge World Phosphex Themes"

    CSS_PATH = Path(__file__).parent.parent / "src" / "styrene" / "styles" / "imperial_crt.tcss"

    BINDINGS = [
        Binding("q", "quit", "Quit"),
        Binding("r", "refresh", "Refresh"),
    ]

    # Current cascade for live updates
    current_preset = reactive("mars")

    def compose(self) -> ComposeResult:
        yield Header()
        with VerticalScroll(id="main-scroll"):
            # Theme Selector Section
            yield HighlightedPanel(
                Horizontal(
                    Label("FORGE WORLD: ", classes="medium"),
                    Select(
                        [(preset.name, key) for key, preset in list_presets()],
                        value="mars",
                        id="theme-select",
                    ),
                    classes="row",
                ),
                ThemePreviewPanel(id="theme-preview"),
                title="PHOSPHEX THEME SELECTOR",
            )

            # Live Theme Example
            yield HighlightedPanel(
                LiveThemedPanel(id="live-themed"),
                title="LIVE THEME PREVIEW",
            )

            # Color Palette Section
            yield HighlightedPanel(
                Horizontal(
                    Static(" BRIGHT ", classes="color-swatch bright"),
                    Static(" MEDIUM ", classes="color-swatch medium"),
                    Static(" DIM ", classes="color-swatch dim"),
                    Static(" DARK ", classes="color-swatch dark"),
                    classes="row",
                ),
                Rule(),
                Label("Status Indicators (symbol + style differentiation):", classes="dim"),
                Horizontal(
                    Static(format_status("online", "ONLINE"), classes="status-online"),
                    Static(format_status("offline", "OFFLINE"), classes="status-offline"),
                    Static(format_status("pending", "PENDING"), classes="status-pending"),
                    Static(format_status("scanning", "SCANNING"), classes="status-scanning"),
                    Static(format_status("info", "INFO"), classes="status-info"),
                    id="status-row",
                ),
                title="COLOR PALETTE",
            )

            # Buttons Section - with shade pattern differentiation
            yield HighlightedPanel(
                Label("Semantic buttons (shade + style differentiation):", classes="dim"),
                Horizontal(
                    Button("Default", id="btn-default"),
                    Button("Primary", id="btn-primary", classes="-primary"),
                    Button(format_button_label("danger", "Danger"), id="btn-danger", classes="-danger"),
                    Button(format_button_label("warning", "Warning"), id="btn-warning", classes="-warning"),
                    Button(format_button_label("success", "Success"), id="btn-success", classes="-success"),
                    classes="row",
                ),
                Rule(),
                Label("Mechanicum-style indicators:", classes="dim"),
                Static(
                    f"{SemanticSymbols.APPROVED} Approved  "
                    f"{SemanticSymbols.REJECTED} Rejected  "
                    f"{SemanticSymbols.PROCESSING} Processing  "
                    f"{SemanticSymbols.IDLE} Idle",
                    id="mechanicum-row",
                ),
                title="BUTTONS & INDICATORS",
            )

            # Inputs Section
            yield HighlightedPanel(
                Label("Normal input:", classes="input-label"),
                Input(placeholder="Enter command...", id="input-normal"),
                Label("Valid input:", classes="input-label"),
                Input(value="valid_value", id="input-valid", classes="-valid"),
                Label("Invalid input:", classes="input-label"),
                Input(value="error!", id="input-invalid", classes="-invalid"),
                title="INPUT FIELDS",
            )

            # Selection Controls Section
            yield HighlightedPanel(
                Horizontal(
                    Switch(value=True, id="switch-on"),
                    Label("Enabled", classes="medium"),
                    classes="row",
                ),
                Horizontal(
                    Switch(value=False, id="switch-off"),
                    Label("Disabled", classes="dim"),
                    classes="row",
                ),
                Rule(),
                Horizontal(
                    Checkbox("Option Alpha", value=True, id="check-1"),
                    Checkbox("Option Beta", id="check-2"),
                    Checkbox("Option Gamma", id="check-3"),
                    classes="row",
                ),
                Rule(),
                Label("Radio Set:", classes="dim"),
                RadioSet(
                    RadioButton("Protocol Alpha"),
                    RadioButton("Protocol Beta", value=True),
                    RadioButton("Protocol Gamma"),
                    id="radio-set",
                ),
                title="SELECTION CONTROLS",
            )

            # Progress Indicators Section
            yield HighlightedPanel(
                Label("Determinate progress:", classes="dim"),
                ProgressBar(total=100, id="progress-1"),
                Label("Indeterminate progress (unknown duration):", classes="dim"),
                ProgressBar(total=None, id="progress-indeterminate"),
                Label("Completed:", classes="dim"),
                ProgressBar(total=100, id="progress-complete"),
                title="PROGRESS INDICATORS",
            )

            # Animated Status Indicators Section
            yield HighlightedPanel(
                Label("Animated status indicators (scanning/pending animate):", classes="dim"),
                AnimatedStatusIndicator(status="online", label="ONLINE", id="anim-online"),
                AnimatedStatusIndicator(status="offline", label="OFFLINE", id="anim-offline"),
                AnimatedStatusIndicator(status="pending", label="PENDING", id="anim-pending"),
                AnimatedStatusIndicator(status="scanning", label="SCANNING", id="anim-scanning"),
                Rule(),
                Label("Scanning bar:", classes="dim"),
                ScanningBar(width=40, bar_width=6, id="scan-bar"),
                Rule(),
                Label("Pulsing indicator:", classes="dim"),
                PulsingIndicator("⬤ PROCESSING", id="pulse-indicator"),
                title="ANIMATED INDICATORS",
            )

            # Data Table Section
            yield HighlightedPanel(
                DataTable(id="device-table"),
                title="DATA TABLE",
            )

            # Log Output Section
            yield HighlightedPanel(
                Static("[14:32:01] System initialized", classes="log-info"),
                Static("[14:32:05] Connection established", classes="log-success"),
                Static("[14:33:12] Signal degradation detected", classes="log-warning"),
                Static("[14:33:45] Link failure on interface eth0", classes="log-error"),
                title="LOG OUTPUT",
            )

        yield Footer()

    def on_mount(self) -> None:
        """Initialize widgets after mount."""
        # Set progress bar values
        self.query_one("#progress-1", ProgressBar).update(progress=75)
        self.query_one("#progress-complete", ProgressBar).update(progress=100)

        # Start animated indicators
        self.query_one("#scan-bar", ScanningBar).start()
        self.query_one("#pulse-indicator", PulsingIndicator).start()

        # Populate data table
        table = self.query_one("#device-table", DataTable)
        table.add_columns("DESIGNATION", "STATUS", "PROTOCOL", "LATENCY")
        table.add_rows([
            ("ALPHA-01", "ONLINE", "LXMF", "12ms"),
            ("BETA-02", "PENDING", "TCP/IP", "-"),
            ("GAMMA-03", "OFFLINE", "LXMF", "-"),
            ("DELTA-04", "ONLINE", "LoRa", "340ms"),
            ("EPSILON-05", "SCANNING", "UDP", "-"),
        ])

        # Initialize theme preview
        self._update_theme_preview()

    def on_select_changed(self, event: Select.Changed) -> None:
        """Handle theme selection change."""
        if event.select.id == "theme-select":
            preset_key = str(event.value)
            self._apply_theme(preset_key)

    def _apply_theme(self, preset_key: str) -> None:
        """Apply a new forge world theme."""
        try:
            cascade = ColorCascade.from_preset(preset_key)
            set_color_cascade(cascade)
            # Switch Textual theme (updates CSS-driven elements)
            self.theme = preset_key
            # Update Rich markup panels
            self._update_theme_preview()
            self._update_live_themed_panel()
            self._refresh_all_panels()
            self.notify(f"Theme: {cascade.preset_name}", severity="information")
        except ValueError as e:
            self.notify(str(e), severity="error")

    def _refresh_all_panels(self) -> None:
        """Refresh all HighlightedPanel borders with new cascade colors."""
        for panel in self.query(HighlightedPanel):
            panel.refresh_theme()

    def _update_theme_preview(self) -> None:
        """Update the theme preview panel."""
        preview = self.query_one("#theme-preview", ThemePreviewPanel)
        preview.update_preview(get_color_cascade())

    def _update_live_themed_panel(self) -> None:
        """Update the live themed panel with new cascade."""
        panel = self.query_one("#live-themed", LiveThemedPanel)
        panel.update_theme(get_color_cascade())

    def action_refresh(self) -> None:
        """Refresh the display."""
        self.bell()

    def __init__(self) -> None:
        super().__init__()
        # Register all forge world themes
        for theme in generate_all_themes().values():
            self.register_theme(theme)
        # Start with Mars Pattern (default)
        self.theme = "mars"


if __name__ == "__main__":
    import sys

    app = WidgetGalleryApp()
    # Check for --dev flag or TEXTUAL_DEV env var for live reload
    if "--dev" in sys.argv or os.environ.get("TEXTUAL_DEV"):
        # Run with textual dev server for live CSS reload
        app.run()
    else:
        app.run()
