"""Smoke tests — verify every major page loads without uncaught exceptions.

These tests catch regressions that unit tests miss: import errors,
template rendering failures, database schema mismatches, and startup
crashes.  They run fast (no Ollama needed) and should stay green on
every commit.
"""

from unittest.mock import MagicMock, patch

import pytest
from fastapi.testclient import TestClient


@pytest.fixture
def client():
    from dashboard.app import app

    # Block all LLM calls so smoke tests never hit a real Ollama
    mock_run = MagicMock()
    mock_run.content = "Smoke test — no LLM."
    mock_agent = MagicMock()
    mock_agent.run.return_value = mock_run
    with patch("timmy.agent.create_timmy", return_value=mock_agent):
        with TestClient(app, raise_server_exceptions=False) as c:
            yield c


# ---------------------------------------------------------------------------
# Core pages — these MUST return 200
# ---------------------------------------------------------------------------


class TestCorePages:
    """Every core dashboard page loads without error."""

    def test_index(self, client):
        r = client.get("/")
        assert r.status_code == 200

    def test_health(self, client):
        r = client.get("/health")
        assert r.status_code == 200

    def test_health_status(self, client):
        r = client.get("/health/status")
        assert r.status_code == 200

    def test_agent_panel(self, client):
        r = client.get("/agents/default/panel")
        assert r.status_code == 200

    def test_agent_history(self, client):
        r = client.get("/agents/default/history")
        assert r.status_code == 200


# ---------------------------------------------------------------------------
# Feature pages — should return 200 (or 307 redirect, never 500)
# ---------------------------------------------------------------------------


class TestFeaturePages:
    """Feature pages load without 500 errors."""

    def test_briefing(self, client):
        r = client.get("/briefing")
        assert r.status_code in (200, 307)

    def test_thinking(self, client):
        r = client.get("/thinking")
        assert r.status_code == 200

    def test_tools(self, client):
        r = client.get("/tools")
        assert r.status_code == 200

    def test_memory(self, client):
        r = client.get("/memory")
        assert r.status_code == 200

    def test_calm(self, client):
        r = client.get("/calm")
        assert r.status_code == 200

    def test_tasks(self, client):
        r = client.get("/tasks")
        assert r.status_code == 200

    def test_work_orders_queue(self, client):
        r = client.get("/work-orders/queue")
        assert r.status_code == 200

    def test_mobile(self, client):
        r = client.get("/mobile")
        assert r.status_code == 200

    def test_spark(self, client):
        r = client.get("/spark")
        assert r.status_code in (200, 307)

    def test_models(self, client):
        r = client.get("/models")
        assert r.status_code == 200

    def test_memory_page(self, client):
        r = client.get("/memory")
        assert r.status_code in (200, 307)


# ---------------------------------------------------------------------------
# JSON API endpoints — should return valid JSON, never 500
# ---------------------------------------------------------------------------


class TestAPIEndpoints:
    """API endpoints return valid JSON without server errors."""

    def test_health_json(self, client):
        r = client.get("/health")
        assert r.status_code == 200
        data = r.json()
        assert "status" in data

    def test_health_components(self, client):
        r = client.get("/health/components")
        assert r.status_code == 200

    def test_health_sovereignty(self, client):
        r = client.get("/health/sovereignty")
        assert r.status_code == 200

    def test_health_snapshot(self, client):
        r = client.get("/health/snapshot")
        assert r.status_code == 200
        data = r.json()
        assert "overall_status" in data
        assert data["overall_status"] in ["green", "yellow", "red", "unknown"]

    def test_queue_status(self, client):
        r = client.get("/api/queue/status")
        assert r.status_code == 200

    def test_tasks_api(self, client):
        r = client.get("/api/tasks")
        assert r.status_code == 200

    def test_chat_history(self, client):
        r = client.get("/api/chat/history")
        assert r.status_code == 200

    def test_tools_stats(self, client):
        r = client.get("/tools/api/stats")
        assert r.status_code == 200

    def test_thinking_api(self, client):
        r = client.get("/thinking/api")
        assert r.status_code == 200

    def test_notifications_api(self, client):
        r = client.get("/api/notifications")
        assert r.status_code == 200

    def test_mobile_status(self, client):
        r = client.get("/mobile/status")
        assert r.status_code == 200

    def test_discord_status(self, client):
        r = client.get("/discord/status")
        assert r.status_code == 200

    def test_telegram_status(self, client):
        r = client.get("/telegram/status")
        assert r.status_code == 200

    def test_grok_status(self, client):
        r = client.get("/grok/status")
        assert r.status_code == 200


# ---------------------------------------------------------------------------
# No 500s — every GET route should survive without server error
# ---------------------------------------------------------------------------


class TestNo500:
    """Verify that no page returns a 500 Internal Server Error."""

    @pytest.mark.parametrize(
        "path",
        [
            "/",
            "/health",
            "/health/status",
            "/health/sovereignty",
            "/health/snapshot",
            "/health/components",
            "/agents/default/panel",
            "/agents/default/history",
            "/briefing",
            "/thinking",
            "/thinking/api",
            "/tools",
            "/tools/api/stats",
            "/memory",
            "/calm",
            "/tasks",
            "/tasks/pending",
            "/tasks/active",
            "/tasks/completed",
            "/work-orders/queue",
            "/work-orders/queue/pending",
            "/work-orders/queue/active",
            "/mobile",
            "/mobile/status",
            "/spark",
            "/models",
            "/api/queue/status",
            "/api/tasks",
            "/api/chat/history",
            "/api/notifications",
            "/discord/status",
            "/telegram/status",
            "/grok/status",
            "/grok/stats",
        ],
    )
    def test_no_500(self, client, path):
        r = client.get(path)
        assert r.status_code != 500, f"GET {path} returned 500"
