from typing import Any

import pytest
from fastapi.testclient import TestClient
from nanoid import generate as generate_nanoid
from sqlalchemy.ext.asyncio import AsyncSession

from src import crud
from src.models import Peer, Workspace


def test_get_or_create_peer(client: TestClient, sample_data: tuple[Workspace, Peer]):
    test_workspace, _ = sample_data
    name = str(generate_nanoid())
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": name, "metadata": {"peer_key": "peer_value"}},
    )
    assert response.status_code in [200, 201]
    data = response.json()
    assert data["id"] == name
    assert data["metadata"] == {"peer_key": "peer_value"}
    assert "id" in data


def test_get_or_create_peer_with_configuration(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer creation with configuration parameter"""
    test_workspace, _ = sample_data
    name = str(generate_nanoid())
    configuration = {"experimental": True, "beta": False}

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": name, "configuration": configuration},
    )
    assert response.status_code in [200, 201]
    data = response.json()
    assert data["id"] == name
    assert data["configuration"] == configuration


def test_get_or_create_peer_with_all_optional_params(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer creation with all optional parameters"""
    test_workspace, _ = sample_data
    name = str(generate_nanoid())
    metadata = {"key": "value", "number": 42}
    configuration = {"feature1": True, "feature2": False}

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": name, "metadata": metadata, "configuration": configuration},
    )
    assert response.status_code in [200, 201]
    data = response.json()
    assert data["id"] == name
    assert data["metadata"] == metadata
    assert data["configuration"] == configuration


def test_get_or_create_existing_peer(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    test_workspace, _ = sample_data
    name = str(generate_nanoid())

    # Create the peer
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": name, "metadata": {"peer_key": "peer_value"}},
    )
    assert response.status_code in [200, 201]
    peer1 = response.json()

    # Try to create the same peer again - should return existing peer
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": name, "metadata": {"peer_key": "peer_value"}},
    )
    assert response.status_code in [200, 201]
    peer2 = response.json()

    # Both should be the same peer
    assert peer1["id"] == peer2["id"]
    assert peer1["metadata"] == peer2["metadata"]


def test_get_peers(client: TestClient, sample_data: tuple[Workspace, Peer]):
    test_workspace, _ = sample_data

    # Create a few peers with metadata
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": str(generate_nanoid()), "metadata": {"peer_key": "peer_value"}},
    )
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": str(generate_nanoid()), "metadata": {"peer_key": "peer_value"}},
    )
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": str(generate_nanoid()), "metadata": {"peer_key": "peer_value2"}},
    )

    # Get all peers
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list",
        json={},
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert len(data["items"]) > 0

    # Get peers with simple filter (backward compatibility)
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list",
        json={"filters": {"metadata": {"peer_key": "peer_value"}}},
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert len(data["items"]) == 2
    assert data["items"][0]["metadata"]["peer_key"] == "peer_value"

    # Test new filter with NOT operator
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list",
        json={"filters": {"NOT": [{"metadata": {"peer_key": "peer_value2"}}]}},
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    # Should find peers that don't have peer_key = "peer_value2"
    # This includes the 2 peers with "peer_value" + the sample peer with empty metadata
    assert len(data["items"]) == 3


def test_get_peers_with_empty_filter(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer listing with empty filter object"""
    test_workspace, _ = sample_data

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list", json={"filters": {}}
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert isinstance(data["items"], list)


def test_get_peers_with_null_filter(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer listing with null filter"""
    test_workspace, _ = sample_data

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list", json={"filters": None}
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert isinstance(data["items"], list)


def test_update_peer(client: TestClient, sample_data: tuple[Workspace, Peer]):
    test_workspace, test_peer = sample_data
    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"metadata": {"new_key": "new_value"}},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["metadata"] == {"new_key": "new_value"}


def test_update_peer_with_configuration(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer update with configuration parameter"""
    test_workspace, test_peer = sample_data
    configuration = {"new_feature": True, "legacy_feature": False}

    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"configuration": configuration},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["configuration"] == configuration


def test_update_peer_with_all_optional_params(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer update with both metadata and configuration"""
    test_workspace, test_peer = sample_data
    metadata = {"updated_key": "updated_value", "count": 100}
    configuration = {"experimental": True, "beta": True}

    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"metadata": metadata, "configuration": configuration},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["metadata"] == metadata
    assert data["configuration"] == configuration


def test_update_peer_with_null_metadata(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer update with null metadata"""
    test_workspace, test_peer = sample_data

    # First set some metadata
    client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"metadata": {"temp": "value"}},
    )

    # Then clear it with null
    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"metadata": None},
    )
    assert response.status_code == 200
    data = response.json()
    assert "metadata" in data


def test_update_peer_with_null_configuration(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer update with null configuration"""
    test_workspace, test_peer = sample_data

    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"configuration": None},
    )
    assert response.status_code == 200
    data = response.json()
    assert "configuration" in data


def test_get_sessions_for_peer_no_sessions(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    test_workspace, test_peer = sample_data

    # Get sessions for the peer
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions",
        json={},
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data


def test_get_sessions_for_peer(client: TestClient, sample_data: tuple[Workspace, Peer]):
    test_workspace, test_peer = sample_data

    # Create session for the peer
    session_name = str(generate_nanoid())
    create_response = client.post(
        f"/v3/workspaces/{test_workspace.name}/sessions",
        json={"id": session_name, "peer_names": {test_peer.name: {}}},
    )
    assert create_response.status_code in [200, 201]
    created_session = create_response.json()
    assert created_session["id"] == session_name

    # Now get sessions for the peer and validate the session is returned
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions",
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    # Check that the created session is in the returned items
    session_ids = [item["id"] for item in data["items"]]
    assert session_name in session_ids
    assert len(data["items"]) == 1


def test_get_sessions_for_peer_with_empty_filter(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test getting sessions for peer with empty filter object"""
    test_workspace, test_peer = sample_data

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions",
        json={"filters": {}},
    )
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert isinstance(data["items"], list)


def test_chat(
    client: TestClient,
    sample_data: tuple[Workspace, Peer],
):
    test_workspace, test_peer = sample_data
    target_peer = str(generate_nanoid())

    # Test chat endpoint
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/chat",
        json={
            "query": "Hello, how are you?",
            "stream": False,
            "target": target_peer,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "content" in data


def test_chat_with_optional_params(
    client: TestClient,
    sample_data: tuple[Workspace, Peer],
):
    """Test chat endpoint with optional parameters"""

    test_workspace, test_peer = sample_data
    session_id = str(generate_nanoid())

    # Create a session first
    client.post(
        f"/v3/workspaces/{test_workspace.name}/sessions",
        json={"id": session_id, "peer_names": {test_peer.name: {}}},
    )

    # Test chat without optional parameters
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/chat",
        json={
            "query": "Hello, how are you?",
            "stream": False,
            "session_id": session_id,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "content" in data


def test_get_peer_representation_with_session(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with session_id parameter"""
    test_workspace, test_peer = sample_data
    session_id = str(generate_nanoid())

    # Create a session first
    client.post(
        f"/v3/workspaces/{test_workspace.name}/sessions",
        json={"id": session_id, "peer_names": {test_peer.name: {}}},
    )

    # Test representation scoped to session
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "session_id": session_id,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data
    assert isinstance(data["representation"], str)


def test_get_peer_representation_global(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation without session_id (global representation)"""
    test_workspace, test_peer = sample_data

    # Test global representation (no session_id)
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={},
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data
    assert isinstance(data["representation"], str)


def test_get_peer_representation_with_target(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with target parameter"""
    test_workspace, test_peer = sample_data

    # Create a second peer to be the target
    target_peer_name = str(generate_nanoid())
    client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": target_peer_name, "metadata": {}},
    )

    # Test representation of target from observer's perspective
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "target": target_peer_name,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data
    assert isinstance(data["representation"], str)


def test_get_peer_representation_with_search_query(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with search_query parameter"""
    test_workspace, test_peer = sample_data

    # Test representation with semantic search query
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "What are my interests and hobbies?",
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data


def test_get_peer_representation_with_search_top_k(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with search_top_k parameter"""
    test_workspace, test_peer = sample_data

    # Test with valid search_top_k values
    for top_k in [1, 10, 50, 100]:
        response = client.post(
            f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
            json={
                "search_query": "test query",
                "search_top_k": top_k,
            },
        )
        assert response.status_code == 200
        data = response.json()
        assert "representation" in data


def test_get_peer_representation_with_search_max_distance(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with search_max_distance parameter"""
    test_workspace, test_peer = sample_data

    # Test with valid search_max_distance values (0.0 to 1.0)
    for max_distance in [0.0, 0.5, 0.8, 1.0]:
        response = client.post(
            f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
            json={
                "search_query": "test query",
                "search_max_distance": max_distance,
            },
        )
        assert response.status_code == 200
        data = response.json()
        assert "representation" in data


def test_get_peer_representation_with_include_most_frequent(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with include_most_frequent parameter"""
    test_workspace, test_peer = sample_data

    # Test with include_most_frequent=True
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "test query",
            "include_most_frequent": True,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data

    # Test with include_most_frequent=False
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "test query",
            "include_most_frequent": False,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data


def test_get_peer_representation_with_max_observations(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with max_observations parameter"""
    test_workspace, test_peer = sample_data

    # Test with various max_observations values
    for max_obs in [1, 25, 50, 100]:
        response = client.post(
            f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
            json={
                "search_query": "test query",
                "max_observations": max_obs,
            },
        )
        assert response.status_code == 200
        data = response.json()
        assert "representation" in data


def test_get_peer_representation_with_all_parameters(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with all optional parameters"""
    test_workspace, test_peer = sample_data
    session_id = str(generate_nanoid())

    # Create a session and target peer
    target_peer_name = str(generate_nanoid())
    client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": target_peer_name, "metadata": {}},
    )
    client.post(
        f"/v3/workspaces/{test_workspace.name}/sessions",
        json={
            "id": session_id,
            "peer_names": {test_peer.name: {}, target_peer_name: {}},
        },
    )

    # Test with all parameters
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "session_id": session_id,
            "target": target_peer_name,
            "search_query": "What do I know about this peer?",
            "search_top_k": 15,
            "search_max_distance": 0.75,
            "include_most_frequent": True,
            "max_observations": 30,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data
    assert isinstance(data["representation"], str)


def test_get_peer_representation_boundary_values(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer representation with boundary values for numeric parameters"""
    test_workspace, test_peer = sample_data

    # Test minimum values
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "test",
            "search_top_k": 1,
            "search_max_distance": 0.0,
            "max_observations": 1,
        },
    )
    assert response.status_code == 200

    # Test maximum values
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "test",
            "search_top_k": 100,
            "search_max_distance": 1.0,
            "max_observations": 100,
        },
    )
    assert response.status_code == 200


def test_get_peer_representation_default_max_observations(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test that max_observations defaults to 25 when not provided"""
    test_workspace, test_peer = sample_data

    # Test without max_observations - should use default of 25
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/representation",
        json={
            "search_query": "test query",
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert "representation" in data


def test_search_peer(client: TestClient, sample_data: tuple[Workspace, Peer]):
    """Test the peer search functionality"""
    test_workspace, test_peer = sample_data

    # Add some messages to search through
    client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions/test_session/messages",
        json={
            "messages": [
                {"content": "Search this content", "peer_id": test_peer.name},
                {"content": "Another searchable message", "peer_id": test_peer.name},
            ]
        },
    )

    # Search with a query
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/search",
        json={"query": "search query", "limit": 10},
    )
    assert response.status_code == 200
    data = response.json()

    # Response should be a direct list of messages
    assert isinstance(data, list)


def test_search_peer_empty_query(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer search with empty query"""
    test_workspace, test_peer = sample_data

    # Search with empty query
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/search",
        json={"query": "", "limit": 10},
    )
    assert response.status_code == 200
    data = response.json()

    # Response should be a direct list of messages
    assert isinstance(data, list)


def test_search_peer_nonexistent(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test searching a peer that doesn't exist"""
    test_workspace, _ = sample_data
    nonexistent_peer_id = str(generate_nanoid())

    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{nonexistent_peer_id}/search",
        json={"query": "test query", "limit": 10},
    )
    assert response.status_code == 200
    data: list[dict[str, Any]] = response.json()
    assert isinstance(data, list)
    assert len(data) == 0


def test_search_peer_with_messages(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer search with actual messages"""
    test_workspace, test_peer = sample_data

    # Add some messages to search through
    client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions/test_session/messages",
        json={
            "messages": [
                {"content": "Search this content", "peer_id": test_peer.name},
                {"content": "Another searchable message", "peer_id": test_peer.name},
            ]
        },
    )

    # Search for content
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/search",
        json={"query": "search", "limit": 10},
    )
    assert response.status_code == 200
    data = response.json()

    # Response should be a direct list of messages
    assert isinstance(data, list)


def test_search_peer_with_limit(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer search with custom limit"""
    test_workspace, test_peer = sample_data

    # Add some messages to search through
    client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/sessions/test_session/messages",
        json={
            "messages": [
                {"content": "Search this content", "peer_id": test_peer.name},
                {"content": "Another searchable message", "peer_id": test_peer.name},
                {"content": "More searchable content", "peer_id": test_peer.name},
            ]
        },
    )

    # Search with custom limit
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}/search",
        json={"query": "search", "limit": 2},
    )

    assert response.status_code == 200
    data: list[dict[str, Any]] = response.json()
    assert isinstance(data, list)
    # Should not exceed the limit
    assert len(data) <= 2


def test_get_peers_with_complex_filter(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer listing with complex filters"""
    test_workspace, _ = sample_data

    # Create peers with different metadata
    for i in range(3):
        client.post(
            f"/v3/workspaces/{test_workspace.name}/peers",
            json={
                "name": str(generate_nanoid()),
                "metadata": {"index": i, "type": "test"},
            },
        )

    # Test complex filter combination
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers/list",
        json={
            "filters": {
                "AND": [
                    {"metadata": {"type": "test"}},
                    {"metadata": {"index": {"gte": 1}}},
                ]
            }
        },
    )
    assert response.status_code == 200
    data = response.json()
    # for each peer returned, assert that the metadata["index"] fits our filter
    for peer in data["items"]:
        assert (
            peer["metadata"].get("index", 0) >= 1
            and peer["metadata"].get("type", "") == "test"
        )
    assert "items" in data


def test_update_peer_all_fields(
    client: TestClient, sample_data: tuple[Workspace, Peer]
):
    """Test peer update with all possible fields"""
    test_workspace, test_peer = sample_data

    # Test updating both metadata and configuration
    metadata = {"updated": True, "version": 2}
    configuration = {"features": {"new_feature": True}}

    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{test_peer.name}",
        json={"metadata": metadata, "configuration": configuration},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["metadata"] == metadata
    assert data["configuration"] == configuration


def test_get_peer_card(client: TestClient, sample_data: tuple[Workspace, Peer]):
    """Test the peer cards endpoint"""
    test_workspace, observer_peer = sample_data

    # Create a second peer (the target/observed peer)
    target_peer_name = str(generate_nanoid())
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": target_peer_name},
    )
    assert response.status_code in [200, 201]

    # Test getting observer's own card (should return null initially)
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card"
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] is None

    # Test getting card for target peer (should return null initially)
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
        params={"target": target_peer_name},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] is None


@pytest.mark.asyncio
async def test_get_peer_card_with_data(
    client: TestClient,
    db_session: AsyncSession,
    sample_data: tuple[Workspace, Peer],
):
    """Test the peer cards endpoint with actual peer card data"""
    test_workspace, observer_peer = sample_data

    # Create a second peer (the target/observed peer)
    target_peer_name = str(generate_nanoid())
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": target_peer_name},
    )
    assert response.status_code in [200, 201]

    # Set up peer cards using the database directly
    # Set a self-card for the observer peer
    self_card_content = ["I am a helpful AI assistant", "I enjoy learning about users"]
    await crud.set_peer_card(
        db_session,
        test_workspace.name,
        self_card_content,
        observer=observer_peer.name,
        observed=observer_peer.name,
    )

    # Set a card for the observer describing the target peer
    target_card_content = ["This peer seems friendly", "They ask good questions"]
    await crud.set_peer_card(
        db_session,
        test_workspace.name,
        target_card_content,
        observer=observer_peer.name,
        observed=target_peer_name,
    )

    # Test getting observer's own card
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card"
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] == self_card_content

    # Test getting card for target peer
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
        params={"target": target_peer_name},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] == target_card_content


def test_set_peer_card(client: TestClient, sample_data: tuple[Workspace, Peer]):
    """Test setting peer cards via the PUT endpoint."""
    test_workspace, observer_peer = sample_data

    # Create a target peer
    target_peer_name = str(generate_nanoid())
    response = client.post(
        f"/v3/workspaces/{test_workspace.name}/peers",
        json={"name": target_peer_name},
    )
    assert response.status_code in [200, 201]

    # Set the observer's own card
    self_card = ["I am a test peer", "I like writing tests"]
    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
        json={"peer_card": self_card},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] == self_card

    # Verify with GET
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card"
    )
    assert response.status_code == 200
    assert response.json()["peer_card"] == self_card

    # Set a card for the target peer
    target_card = ["Target is helpful", "Target knows Python"]
    response = client.put(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
        params={"target": target_peer_name},
        json={"peer_card": target_card},
    )
    assert response.status_code == 200
    data = response.json()
    assert data["peer_card"] == target_card

    # Verify with GET
    response = client.get(
        f"/v3/workspaces/{test_workspace.name}/peers/{observer_peer.name}/card",
        params={"target": target_peer_name},
    )
    assert response.status_code == 200
    assert response.json()["peer_card"] == target_card
