"""Tests for MacroClient."""

from __future__ import annotations

from datetime import UTC, datetime, timedelta

import pytest
from pytest_httpx import HTTPXMock

from cerbero_bite.clients._base import HttpToolClient
from cerbero_bite.clients.macro import MacroClient


def _client() -> MacroClient:
    http = HttpToolClient(
        service="macro",
        base_url="http://mcp-macro:9013",
        token="t",
        retry_max=1,
    )
    return MacroClient(http)


@pytest.mark.asyncio
async def test_get_calendar_parses_events(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(
        url="http://mcp-macro:9013/tools/get_macro_calendar",
        json={
            "events": [
                {
                    "name": "FOMC Meeting",
                    "country_code": "US",
                    "importance": "high",
                    "datetime_utc": "2026-05-05T18:00:00+00:00",
                },
                {
                    "event": "ECB rate decision",
                    "country_code": "EU",
                    "importance": "high",
                    "datetime_utc": "2026-05-08T12:00:00Z",
                },
            ]
        },
    )
    events = await _client().get_calendar(days=18)
    assert [e.name for e in events] == ["FOMC Meeting", "ECB rate decision"]
    assert events[0].country_code == "US"
    assert events[0].importance == "high"
    assert events[0].datetime_utc == datetime(2026, 5, 5, 18, 0, tzinfo=UTC)


@pytest.mark.asyncio
async def test_get_calendar_skips_non_dict_entries(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(json={"events": ["not-a-dict", None]})
    assert await _client().get_calendar(days=18) == []


@pytest.mark.asyncio
async def test_next_high_severity_returns_min_days(httpx_mock: HTTPXMock) -> None:
    now = datetime(2026, 4, 27, 14, 0, tzinfo=UTC)
    httpx_mock.add_response(
        json={
            "events": [
                {
                    "name": "FOMC",
                    "country_code": "US",
                    "importance": "high",
                    "datetime_utc": (now + timedelta(days=10, hours=4)).isoformat(),
                },
                {
                    "name": "ECB",
                    "country_code": "EU",
                    "importance": "high",
                    "datetime_utc": (now + timedelta(days=3, hours=1)).isoformat(),
                },
            ]
        }
    )
    days = await _client().next_high_severity_within(
        days=18, countries=["US", "EU"], now=now
    )
    assert days == 3


@pytest.mark.asyncio
async def test_next_high_severity_ignores_past_events(httpx_mock: HTTPXMock) -> None:
    now = datetime(2026, 4, 27, 14, 0, tzinfo=UTC)
    httpx_mock.add_response(
        json={
            "events": [
                {
                    "name": "stale",
                    "country_code": "US",
                    "importance": "high",
                    "datetime_utc": (now - timedelta(days=2)).isoformat(),
                },
            ]
        }
    )
    assert (
        await _client().next_high_severity_within(days=18, countries=None, now=now)
        is None
    )


@pytest.mark.asyncio
async def test_next_high_severity_no_events_returns_none(
    httpx_mock: HTTPXMock,
) -> None:
    httpx_mock.add_response(json={"events": []})
    out = await _client().next_high_severity_within(
        days=18, countries=["US"], now=datetime(2026, 4, 27, 14, 0, tzinfo=UTC)
    )
    assert out is None


@pytest.mark.asyncio
async def test_get_calendar_passes_filters(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(json={"events": []})
    await _client().get_calendar(
        days=18, country_filter=["US", "EU"], importance_min="high"
    )
    request = httpx_mock.get_request()
    assert request is not None
    body = request.read().decode()
    assert '"days":18' in body
    assert '"country_filter":["US","EU"]' in body
    assert '"importance_min":"high"' in body


def test_macro_client_rejects_wrong_service() -> None:
    bad = HttpToolClient(
        service="deribit",
        base_url="http://x:1",
        token="t",
        retry_max=1,
    )
    with pytest.raises(ValueError, match="requires service 'macro'"):
        MacroClient(bad)
