from unittest.mock import patch, AsyncMock

from aioresponses import aioresponses

from iis_access._types import AuthContext
from iis_access.usage import report_usage


class TestReportUsage:
    async def test_does_nothing_when_not_authenticated(self):
        with patch(
            "iis_access.usage.get_auth_context",
            new_callable=AsyncMock,
            return_value=None,
        ):
            # Should not raise
            await report_usage("aria", credits=1.0)

    async def test_sends_post_when_authenticated(self):
        ctx = AuthContext(
            account_id="acc-123",
            access_token="jwt-token",
            plan="pro",
        )

        with (
            patch(
                "iis_access.usage.get_auth_context",
                new_callable=AsyncMock,
                return_value=ctx,
            ),
            patch(
                "iis_access.usage.get_account_url",
                return_value="http://localhost:9060",
            ),
            aioresponses() as mocked,
        ):
            mocked.post("http://localhost:9060/usage/record", status=200)

            await report_usage("aria", credits=2.5, requests=1)

            # Verify the request was made
            requests_made = mocked.requests
            key = ("POST", mocked.requests)
            # aioresponses stores requests - verify at least one was made
            assert len(requests_made) > 0

    async def test_handles_network_error_gracefully(self):
        ctx = AuthContext(
            account_id="acc-123",
            access_token="jwt-token",
            plan="pro",
        )

        with (
            patch(
                "iis_access.usage.get_auth_context",
                new_callable=AsyncMock,
                return_value=ctx,
            ),
            patch(
                "iis_access.usage.get_account_url",
                return_value="http://localhost:9060",
            ),
            aioresponses() as mocked,
        ):
            mocked.post(
                "http://localhost:9060/usage/record",
                exception=ConnectionError("Network down"),
            )

            # Should not raise
            await report_usage("aria", credits=1.0)
