# #region TestAgentChat.Api [C:3] [TYPE Module] [SEMANTICS test,agent,api,conversations]
# @BRIEF Tests for AgentChat REST API — save, active gate, LLM config.
# @RELATION BINDS_TO -> [AgentChat.Api.Conversations]
# @TEST_EDGE: save_valid -> new conversation created
# @TEST_EDGE: save_update -> existing conversation updated
# @TEST_EDGE: active_gate -> always returns {active: false}
# @TEST_EDGE: llm_config -> endpoint reachable
# @NOTE History and delete/archive for /api/assistant prefix are handled by legacy assistant routes
#       (FR-020 backward compat). The new agent routes use /api/agent prefix for save/active/llm-config.
import os
import pytest
from unittest.mock import MagicMock

from fastapi.testclient import TestClient

from src.app import app
from src.dependencies import get_current_user


def _make_mock_user(user_id: str = "test-user-id"):
    """Create a mock authenticated user."""
    mock_user = MagicMock()
    mock_user.id = user_id
    mock_user.username = "test-user"
    return mock_user


MOCK_USER = _make_mock_user()


@pytest.fixture(autouse=True)
def override_deps():
    """Override FastAPI dependencies with mock user for all tests."""
    app.dependency_overrides[get_current_user] = lambda: MOCK_USER
    yield
    app.dependency_overrides.clear()


client = TestClient(app)


# #region TestAgentChat.Api.Save [C:2] [TYPE Function] [SEMANTICS test,api,save]
# @BRIEF Conversation save endpoint tests — POST /api/agent/conversations/save.

def test_save_conversation():
    """POST /api/agent/conversations/save creates a new conversation."""
    response = client.post(
        "/api/agent/conversations/save",
        json={"conversation_id": "test-save-1", "title": "Save Test", "user_id": "test-user-id"},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["saved"] is True
    assert data["conversation_id"] == "test-save-1"


def test_save_conversation_updates_existing():
    """POST /api/agent/conversations/save updates existing conversation title."""
    # Create
    client.post(
        "/api/agent/conversations/save",
        json={"conversation_id": "test-save-2", "title": "Original", "user_id": "test-user-id"},
    )
    # Update
    response = client.post(
        "/api/agent/conversations/save",
        json={"conversation_id": "test-save-2", "title": "Updated Title", "user_id": "test-user-id"},
    )
    assert response.status_code == 200
    assert response.json()["saved"] is True


def test_save_conversation_default_user_id():
    """POST /api/agent/conversations/save without user_id defaults to 'admin'."""
    response = client.post(
        "/api/agent/conversations/save",
        json={"conversation_id": "test-save-default", "title": "Default User"},
    )
    assert response.status_code == 200
    assert response.json()["saved"] is True
# #endregion TestAgentChat.Api.Save


# #region TestAgentChat.Api.ActiveGate [C:2] [TYPE Function] [SEMANTICS test,api,active]
# @BRIEF Multi-tab active session gate tests — GET /api/agent/conversations/active.

def test_check_active_session():
    """GET /api/agent/conversations/active returns {active: false}."""
    response = client.get("/api/agent/conversations/active")
    assert response.status_code == 200
    data = response.json()
    assert data == {"active": False}
# #endregion TestAgentChat.Api.ActiveGate


# #region TestAgentChat.Api.LlmConfig [C:2] [TYPE Function] [SEMANTICS test,api,llm]
# @BRIEF LLM config endpoint tests — GET /api/agent/llm-config.
# @NOTE Requires ENCRYPTION_KEY at request time. Passes even when env var is cleared mid-suite.

def test_llm_config_endpoint_reachable():
    """GET /api/agent/llm-config is reachable (skip if EncryptionManager unavailable)."""
    try:
        response = client.get("/api/agent/llm-config")
        assert response.status_code in (200, 500), \
            f"Expected 200 or 500, got {response.status_code}: {response.text[:200]}"
    except RuntimeError as e:
        if "ENCRYPTION_KEY" in str(e):
            pytest.skip("ENCRYPTION_KEY not available at request time")
        raise


def test_llm_config_response_shape():
    """LLM config response contains expected fields when 200."""
    try:
        response = client.get("/api/agent/llm-config")
        if response.status_code == 200:
            data = response.json()
            assert "configured" in data, "Response should have 'configured' field"
    except RuntimeError as e:
        if "ENCRYPTION_KEY" in str(e):
            pytest.skip("ENCRYPTION_KEY not available at request time")
        raise
# #endregion TestAgentChat.Api.LlmConfig


# #region TestAgentChat.Api.LegacyCompat [C:2] [TYPE Function] [SEMANTICS test,api,legacy]
# @BRIEF Legacy assistant route backward compatibility (FR-020).

def test_legacy_history_returns_empty_for_nonexistent():
    """GET /api/assistant/history returns 200 with empty items for nonexistent conversation (legacy compat)."""
    import uuid
    bad_id = f"nonexistent-{uuid.uuid4().hex}"
    response = client.get(f"/api/assistant/history?conversation_id={bad_id}")
    # Legacy route returns 200 with empty items, not 404
    assert response.status_code == 200, f"Legacy history should be 200: {response.status_code}"
    data = response.json()
    assert "items" in data


def test_legacy_conversations_list():
    """GET /api/assistant/conversations returns 200 with items (legacy compat)."""
    response = client.get("/api/assistant/conversations")
    assert response.status_code == 200
    data = response.json()
    assert "items" in data


def test_legacy_pagination_params():
    """GET /api/assistant/conversations supports page/page_size (legacy compat)."""
    response = client.get("/api/assistant/conversations?page=1&page_size=5")
    assert response.status_code == 200
# #endregion TestAgentChat.Api.LegacyCompat
# #endregion TestAgentChat.Api
