"""Tests for the web dashboard — FastAPI endpoint tests."""

import pytest
from unittest.mock import patch, MagicMock

# These tests require the web optional dependencies
pytest.importorskip("fastapi")
pytest.importorskip("httpx")

from fastapi.testclient import TestClient


@pytest.fixture
def client(tmp_path):
    """Create a test client with a fresh SQLite DB."""
    from memotrail.storage.sqlite_store import SQLiteStore
    from memotrail.storage.chroma_store import ChromaStore

    sqlite = SQLiteStore(db_path=tmp_path / "test.db")
    sqlite.connect()

    # Patch the module-level stores in web.app
    with patch("memotrail.web.app.sqlite_store", sqlite), \
         patch("memotrail.web.app.chroma_store") as mock_chroma, \
         patch("memotrail.web.app.searcher") as mock_searcher, \
         patch("memotrail.web.app.knowledge_graph") as mock_graph:

        mock_chroma.get_collection_count.return_value = 0
        mock_searcher.search_chats.return_value = []
        mock_graph.get_all_entities.return_value = []
        mock_graph.get_entity_relations.return_value = []

        from memotrail.web.app import app
        yield TestClient(app), sqlite


class TestHomePage:
    def test_index_returns_200(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/")
        assert response.status_code == 200
        assert "Dashboard" in response.text

    def test_index_shows_stats(self, client, tmp_path):
        test_client, sqlite = client
        sqlite.create_session(project="test")
        response = test_client.get("/")
        assert response.status_code == 200


class TestSessionsPage:
    def test_sessions_empty(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/sessions")
        assert response.status_code == 200
        assert "Sessions" in response.text

    def test_sessions_with_data(self, client, tmp_path):
        test_client, sqlite = client
        sqlite.create_session(project="myproject")
        response = test_client.get("/sessions")
        assert response.status_code == 200
        assert "myproject" in response.text

    def test_sessions_pagination(self, client, tmp_path):
        test_client, sqlite = client
        for i in range(25):
            sqlite.create_session(project=f"proj{i}")
        response = test_client.get("/sessions?page=2")
        assert response.status_code == 200

    def test_sessions_project_filter(self, client, tmp_path):
        test_client, sqlite = client
        sqlite.create_session(project="proj1")
        sqlite.create_session(project="proj2")
        response = test_client.get("/sessions?project=proj1")
        assert response.status_code == 200
        assert "proj1" in response.text


class TestSessionDetailPage:
    def test_session_not_found(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/sessions/nonexistent")
        assert response.status_code == 404

    def test_session_detail(self, client, tmp_path):
        test_client, sqlite = client
        session = sqlite.create_session(project="test")
        sqlite.add_message(session.id, "user", "Hello")
        sqlite.add_message(session.id, "assistant", "Hi there!")

        response = test_client.get(f"/sessions/{session.id}")
        assert response.status_code == 200
        assert "Hello" in response.text


class TestSearchPage:
    def test_search_page_loads(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/search")
        assert response.status_code == 200
        assert "Search" in response.text

    def test_search_with_query(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/search?q=test")
        assert response.status_code == 200


class TestMemoriesPage:
    def test_memories_empty(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/memories")
        assert response.status_code == 200
        assert "Memories" in response.text

    def test_memories_with_data(self, client, tmp_path):
        test_client, sqlite = client
        sqlite.save_memory("Remember this important fact", tags=["test"])
        response = test_client.get("/memories")
        assert response.status_code == 200
        assert "important fact" in response.text


class TestGraphPage:
    def test_graph_empty(self, client, tmp_path):
        test_client, _ = client
        response = test_client.get("/graph")
        assert response.status_code == 200
        assert "Knowledge Graph" in response.text

    def test_graph_with_entities(self, client, tmp_path):
        test_client, _ = client
        # Mock is already set up in fixture
        response = test_client.get("/graph")
        assert response.status_code == 200
