from uuid import UUID
from unittest.mock import AsyncMock

import pytest

from dsg_core_client import DSGCoreClient


@pytest.mark.asyncio
async def test_query_item_events_calls_events_item_endpoint() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        item_id = UUID("00000000-0000-0000-0000-000000000001")
        user_id = UUID("00000000-0000-0000-0000-000000000002")

        get_mock = AsyncMock(
            return_value=[
                {
                    "eventUid": "00000000-0000-0000-0000-000000000003",
                    "timestamp": "2026-01-01T00:00:00Z",
                    "release": 1,
                    "eventType": "ItemCreatedEvent",
                    "data": {"name": "item-1"},
                    "aggregateId": str(item_id),
                    "userUid": str(user_id),
                    "taskUid": None,
                }
            ]
        )
        setattr(client, "get", get_mock)

        response = await client.events.query_item_events(item_id)

        assert len(response) == 1
        assert response[0].event_type == "ItemCreatedEvent"
        assert response[0].aggregate_id == item_id
        get_mock.assert_awaited_once_with(client.path(f"/events/items/{item_id}"))
    finally:
        await client.close()


@pytest.mark.asyncio
async def test_query_item_last_event_calls_events_last_endpoint() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        item_id = UUID("00000000-0000-0000-0000-000000000001")
        user_id = UUID("00000000-0000-0000-0000-000000000002")

        get_mock = AsyncMock(
            return_value={
                "eventUid": "00000000-0000-0000-0000-000000000003",
                "timestamp": "2026-01-01T00:00:00Z",
                "release": 2,
                "eventType": "ItemUpdatedEvent",
                "data": {"name": "item-2"},
                "aggregateId": str(item_id),
                "userUid": str(user_id),
                "taskUid": None,
            }
        )
        setattr(client, "get", get_mock)

        response = await client.events.query_item_last_event(item_id)

        assert response.event_type == "ItemUpdatedEvent"
        assert response.release == 2
        get_mock.assert_awaited_once_with(client.path(f"/events/items/{item_id}/last"))
    finally:
        await client.close()


@pytest.mark.asyncio
async def test_query_item_last_n_events_calls_events_last_n_endpoint() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        item_id = UUID("00000000-0000-0000-0000-000000000001")
        user_id = UUID("00000000-0000-0000-0000-000000000002")

        get_mock = AsyncMock(
            return_value=[
                {
                    "eventUid": "00000000-0000-0000-0000-000000000003",
                    "timestamp": "2026-01-01T00:00:00Z",
                    "release": 3,
                    "eventType": "ItemRetiredEvent",
                    "data": {},
                    "aggregateId": str(item_id),
                    "userUid": str(user_id),
                    "taskUid": None,
                }
            ]
        )
        setattr(client, "get", get_mock)

        response = await client.events.query_item_last_n_events(item_id, 5)

        assert len(response) == 1
        assert response[0].release == 3
        get_mock.assert_awaited_once_with(
            client.path(f"/events/items/{item_id}/last/5")
        )
    finally:
        await client.close()
