"""Tests for AgentDrop.list_connections() method.

TDD: Tests written BEFORE implementation.
Covers: response structure, filtering, empty state, error handling.
"""

from unittest.mock import patch, MagicMock

import pytest

from agentdrop.client import AgentDrop, AgentDropError


# ── Fixtures ──────────────────────────────────────────────────────────

def _make_client(**overrides) -> AgentDrop:
    """Build an AgentDrop client with mocked config loading."""
    defaults = dict(
        api_key="agd_test_key",
        agent_id="test-agent",
        agent_uuid="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
        shield=False,
        config_dir="/tmp/agentdrop_test_nonexistent",
    )
    defaults.update(overrides)
    with patch.object(AgentDrop, "_load_config"):
        return AgentDrop(**defaults)


FULL_RESPONSE = {
    "connections": [
        {
            "id": "conn-1",
            "other_account": {
                "id": "acct-1",
                "name": "Alice Bot",
                "email": "alice@example.com",
                "avatar_url": "https://example.com/alice.png",
            },
            "status": "active",
            "invited_by": "acct-owner",
            "message": "Let's collaborate",
            "created_at": "2026-01-01T00:00:00Z",
            "accepted_at": "2026-01-01T01:00:00Z",
            "pairing_count": 2,
            "pending_pairing_count": 0,
        },
    ],
    "pending_incoming": [
        {
            "id": "inv-1",
            "from": {"id": "acct-2", "name": "Bob", "email": "bob@example.com"},
            "message": "Hey, connect?",
            "created_at": "2026-03-28T12:00:00Z",
        },
    ],
    "pending_outgoing": [
        {
            "id": "inv-2",
            "to_email": "carol@example.com",
            "message": "Join me",
            "created_at": "2026-03-28T13:00:00Z",
        },
    ],
    "pending_pairings_count": 1,
}

EMPTY_RESPONSE = {
    "connections": [],
    "pending_incoming": [],
    "pending_outgoing": [],
    "pending_pairings_count": 0,
}


# ── Tests ─────────────────────────────────────────────────────────────

class TestListConnections:
    """Tests for list_connections()."""

    @patch.object(AgentDrop, "_request")
    def test_returns_full_structure_with_active_connections(self, mock_request):
        """Active connections, pending incoming/outgoing all returned correctly."""
        mock_request.return_value = FULL_RESPONSE
        client = _make_client()

        result = client.list_connections()

        assert isinstance(result, dict)
        assert len(result["connections"]) == 1
        assert result["connections"][0]["id"] == "conn-1"
        assert result["connections"][0]["other_account"]["name"] == "Alice Bot"
        assert result["connections"][0]["status"] == "active"
        assert result["connections"][0]["pairing_count"] == 2

    @patch.object(AgentDrop, "_request")
    def test_returns_pending_incoming_and_outgoing(self, mock_request):
        """Pending invitations are returned in the correct keys."""
        mock_request.return_value = FULL_RESPONSE
        client = _make_client()

        result = client.list_connections()

        assert len(result["pending_incoming"]) == 1
        assert result["pending_incoming"][0]["from"]["email"] == "bob@example.com"
        assert len(result["pending_outgoing"]) == 1
        assert result["pending_outgoing"][0]["to_email"] == "carol@example.com"
        assert result["pending_pairings_count"] == 1

    @patch.object(AgentDrop, "_request")
    def test_empty_state_no_connections(self, mock_request):
        """Empty response when account has no connections."""
        mock_request.return_value = EMPTY_RESPONSE
        client = _make_client()

        result = client.list_connections()

        assert result["connections"] == []
        assert result["pending_incoming"] == []
        assert result["pending_outgoing"] == []
        assert result["pending_pairings_count"] == 0

    @patch.object(AgentDrop, "_request")
    def test_status_filter_passed_as_query_param(self, mock_request):
        """Status filter is forwarded to the API as a query parameter."""
        mock_request.return_value = EMPTY_RESPONSE
        client = _make_client()

        client.list_connections(status="active")

        mock_request.assert_called_once_with(
            "GET", "/v1/connections", params={"status": "active"}
        )

    @patch.object(AgentDrop, "_request")
    def test_default_status_is_all(self, mock_request):
        """Default status filter is 'all'."""
        mock_request.return_value = EMPTY_RESPONSE
        client = _make_client()

        client.list_connections()

        mock_request.assert_called_once_with(
            "GET", "/v1/connections", params={"status": "all"}
        )

    @patch.object(AgentDrop, "_request")
    def test_status_pending_filter(self, mock_request):
        """Status='pending' is passed correctly."""
        mock_request.return_value = EMPTY_RESPONSE
        client = _make_client()

        client.list_connections(status="pending")

        mock_request.assert_called_once_with(
            "GET", "/v1/connections", params={"status": "pending"}
        )

    @patch.object(AgentDrop, "_request")
    def test_api_error_raises_agentdrop_error(self, mock_request):
        """API errors propagate as AgentDropError."""
        mock_request.side_effect = AgentDropError(
            "Forbidden", code="FORBIDDEN", status=403
        )
        client = _make_client()

        with pytest.raises(AgentDropError) as exc_info:
            client.list_connections()

        assert exc_info.value.status == 403
        assert exc_info.value.code == "FORBIDDEN"
