"""End-to-end graph tests — requires a running graph database."""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest

from koan.graph import (
    DecisionTracer,
    GraphConfig,
    PrecedentSearch,
    create_graph_client,
    get_run_trace,
)

if TYPE_CHECKING:
    from collections.abc import AsyncIterator

    from koan.graph.client import GraphClient

pytestmark = [pytest.mark.integration, pytest.mark.graph]


@pytest.fixture
async def graph_client() -> AsyncIterator[GraphClient]:
    config = GraphConfig(
        provider="neo4j",
        uri="bolt://localhost:7687",
        username="neo4j",
        password="koan-dev-password",
    )
    async with create_graph_client(config) as client:
        yield client


class TestGraphTraceE2E:
    async def test_full_decision_trace_cycle(self, graph_client: GraphClient) -> None:
        """Record decisions, query them back, search for precedents."""
        run_id = "e2e-test-run-001"
        agent_id = "e2e-test-agent"
        thread_id = "e2e-test-thread"

        # 1. Record a decision trace
        async with DecisionTracer(
            graph_client,
            run_id=run_id,
            agent_id=agent_id,
            thread_id=thread_id,
        ) as tracer:
            decision_id = await tracer.record_decision(
                description="Classified user request as billing inquiry",
                decision_type="classification",
                confidence=0.95,
                reasoning="Keywords: 'invoice', 'payment'",
            )

            await tracer.record_action(
                decision_id=decision_id,
                action_type="tool_call",
                tool_name="lookup_billing",
            )

            await tracer.record_outcome(
                status="success",
                result="Resolved billing inquiry",
                evaluation_score=0.9,
            )

            await tracer.link_entity(
                decision_id=decision_id,
                entity_id="acct-e2e-001",
                entity_type="account",
                source_system="crm",
            )

        # 2. Query the trace back
        trace = await get_run_trace(graph_client, run_id)
        assert len(trace) > 0

        # 3. Search for precedents
        search = PrecedentSearch(graph_client)
        results = await search.find(
            entity_id="acct-e2e-001",
            decision_type="classification",
            min_confidence=0.5,
        )
        assert len(results) >= 1
        assert results[0].confidence >= 0.5

    async def test_health_check(self, graph_client: GraphClient) -> None:
        """Verify the graph database is reachable."""
        healthy = await graph_client.health_check()
        assert healthy is True
