"""Headless TUI tests for the LLMHosts dashboard.

Uses Textual's built-in headless testing framework -- no real terminal needed.
"""

from __future__ import annotations

from datetime import datetime, timezone

from llmhosts.dashboard.app import LLMHostsDashboard
from llmhosts.dashboard.widgets import (
    BackendsWidget,
    HeaderWidget,
    MetricsWidget,
    RequestLogWidget,
    SavingsWidget,
)

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _make_app(**kwargs) -> LLMHostsDashboard:
    """Create a dashboard with a very long refresh interval to avoid HTTP noise in tests."""
    kwargs.setdefault("refresh_interval", 9999.0)
    return LLMHostsDashboard(**kwargs)


# ---------------------------------------------------------------------------
# Startup / widget presence
# ---------------------------------------------------------------------------


async def test_dashboard_launches():
    """Dashboard app starts without error."""
    async with _make_app().run_test() as pilot:
        assert pilot.app is not None
        assert isinstance(pilot.app, LLMHostsDashboard)


async def test_dashboard_title():
    """Dashboard shows correct title and subtitle."""
    async with _make_app().run_test() as pilot:
        assert pilot.app.title == "LLMHosts Dashboard"
        assert pilot.app.sub_title.startswith("v")


async def test_dashboard_has_header():
    """Dashboard shows header with LLMHosts branding."""
    async with _make_app().run_test() as pilot:
        header = pilot.app.query_one("#header", HeaderWidget)
        assert header is not None


async def test_dashboard_has_savings_widget():
    """Dashboard has a savings display widget."""
    async with _make_app().run_test() as pilot:
        savings = pilot.app.query_one("#savings-panel", SavingsWidget)
        assert savings is not None


async def test_dashboard_has_backends_widget():
    """Dashboard has a backends status widget."""
    async with _make_app().run_test() as pilot:
        backends = pilot.app.query_one("#backends-panel", BackendsWidget)
        assert backends is not None


async def test_dashboard_has_request_log():
    """Dashboard has a request log widget."""
    async with _make_app().run_test() as pilot:
        log = pilot.app.query_one("#requests-panel", RequestLogWidget)
        assert log is not None


async def test_dashboard_has_metrics_widget():
    """Dashboard has a metrics widget."""
    async with _make_app().run_test() as pilot:
        metrics = pilot.app.query_one("#metrics-panel", MetricsWidget)
        assert metrics is not None


async def test_dashboard_has_footer():
    """Dashboard includes a Textual Footer (keybinding hints)."""
    from textual.widgets import Footer

    async with _make_app().run_test() as pilot:
        footer = pilot.app.query_one(Footer)
        assert footer is not None


# ---------------------------------------------------------------------------
# Keybindings
# ---------------------------------------------------------------------------


async def test_dashboard_quit_binding():
    """Pressing 'q' quits the dashboard."""
    async with _make_app().run_test() as pilot:
        await pilot.press("q")
        # After pressing quit the app should no longer be running
        assert pilot.app.return_code is not None or pilot.app._exit


async def test_dashboard_refresh_binding():
    """Pressing 'r' triggers a refresh action without crashing."""
    async with _make_app().run_test() as pilot:
        await pilot.press("r")
        # No exception means the refresh action resolved successfully
        await pilot.pause()


async def test_dashboard_detail_toggle():
    """Pressing 'd' toggles detail mode."""
    async with _make_app().run_test() as pilot:
        app: LLMHostsDashboard = pilot.app  # type: ignore[assignment]
        assert app._detail_mode is False
        await pilot.press("d")
        await pilot.pause()
        assert app._detail_mode is True
        await pilot.press("d")
        await pilot.pause()
        assert app._detail_mode is False


# ---------------------------------------------------------------------------
# Widget default state (no data)
# ---------------------------------------------------------------------------


async def test_savings_widget_default_state():
    """SavingsWidget renders a 'waiting' message when there's no data."""
    async with _make_app().run_test() as pilot:
        savings = pilot.app.query_one("#savings-panel", SavingsWidget)
        rendered = savings.render()
        assert "Waiting for requests" in rendered.plain


async def test_backends_widget_default_state():
    """BackendsWidget renders a 'discovering' message when there's no data."""
    async with _make_app().run_test() as pilot:
        backends = pilot.app.query_one("#backends-panel", BackendsWidget)
        rendered = backends.render()
        assert "Discovering" in rendered.plain


async def test_request_log_default_state():
    """RequestLogWidget renders a 'no requests' message when empty."""
    async with _make_app().run_test() as pilot:
        log = pilot.app.query_one("#requests-panel", RequestLogWidget)
        rendered = log.render()
        assert "No requests yet" in rendered.plain


async def test_metrics_widget_default_state():
    """MetricsWidget renders with zero values by default."""
    async with _make_app().run_test() as pilot:
        metrics = pilot.app.query_one("#metrics-panel", MetricsWidget)
        rendered = metrics.render()
        assert "METRICS" in rendered.plain
        assert "RPM" in rendered.plain
        assert "Cache" in rendered.plain


# ---------------------------------------------------------------------------
# push_request API
# ---------------------------------------------------------------------------


async def test_push_request_adds_entry():
    """push_request() adds an entry to the request log widget."""
    async with _make_app().run_test() as pilot:
        app: LLMHostsDashboard = pilot.app  # type: ignore[assignment]
        app.push_request(
            timestamp=datetime(2026, 2, 15, 12, 0, 0, tzinfo=timezone.utc),
            model_requested="gpt-4o-mini",
            model_used="llama3.2:8b",
            backend="ollama",
            cached=False,
            cost=0.0,
            latency_ms=42.5,
        )
        await pilot.pause()

        log = pilot.app.query_one("#requests-panel", RequestLogWidget)
        rendered = log.render()
        assert "gpt-4o-mini" in rendered.plain
        assert "llama3.2:8b" in rendered.plain


async def test_push_request_cached():
    """push_request() correctly shows cached entries."""
    async with _make_app().run_test() as pilot:
        app: LLMHostsDashboard = pilot.app  # type: ignore[assignment]
        app.push_request(
            timestamp=datetime(2026, 2, 15, 12, 0, 0, tzinfo=timezone.utc),
            model_requested="gpt-4o",
            model_used="gpt-4o",
            backend="cache",
            cached=True,
            cost=0.0,
            latency_ms=5.0,
        )
        await pilot.pause()

        log = pilot.app.query_one("#requests-panel", RequestLogWidget)
        assert len(log._log) == 1
        assert log._log[0].cached is True


async def test_push_multiple_requests():
    """Multiple push_request() calls accumulate in the log."""
    async with _make_app().run_test() as pilot:
        app: LLMHostsDashboard = pilot.app  # type: ignore[assignment]
        for i in range(5):
            app.push_request(
                model_requested=f"model-{i}",
                model_used=f"backend-{i}",
                backend="ollama",
            )
        await pilot.pause()

        log = pilot.app.query_one("#requests-panel", RequestLogWidget)
        assert len(log._log) == 5


# ---------------------------------------------------------------------------
# Backend updates
# ---------------------------------------------------------------------------


async def test_backends_widget_update():
    """BackendsWidget renders backend entries after update_backends()."""
    async with _make_app().run_test() as pilot:
        backends = pilot.app.query_one("#backends-panel", BackendsWidget)
        backends.update_backends(
            [
                ("ollama", True, 3),
                ("openai", True, 0),
                ("anthropic", False, 0),
            ]
        )
        await pilot.pause()

        rendered = backends.render()
        assert "Local" in rendered.plain
        assert "Openai" in rendered.plain
        assert "Anthropic" in rendered.plain
        assert "healthy" in rendered.plain
        assert "offline" in rendered.plain
