# pyright: reportPrivateUsage=false
"""Mock tests: health, auth, account, payments resources."""

from typing import Any
from unittest.mock import AsyncMock, patch

from seaart import AsyncClient

from ._fixtures import ACCOUNT_INFO, PAYMENT_ACCESS_INFO
from .conftest import make_ok as _ok


# ── Health ──────────────────────────────────────────────────────────────────


class TestHealthMock:
    async def test_ping(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok()):
            result = await client.health.ping()
            assert result.status.code == 10000

    async def test_ping_with_action(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok()) as mock:
            await client.health.ping(action="first_open")
            assert mock.call_args.kwargs["json"]["action"] == "first_open"


# ── Auth ────────────────────────────────────────────────────────────────────


class TestAuthMock:
    async def test_login_as_tourist(self, client: AsyncClient) -> None:
        data: dict[str, Any] = {
            "account": {"id": "u1", "name": "Tourist", "email": "", "type": "tourist", "head": ""},
            "token": "tourist-token-abc",
        }
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok(data)):
            result = await client.auth.login_as_tourist()
            assert result.value.token == "tourist-token-abc"
            assert client.token == "tourist-token-abc"

    async def test_login(self, client: AsyncClient) -> None:
        data: dict[str, Any] = {
            "account": {"id": "u2", "name": "User", "email": "t@t.com", "type": "normal", "head": ""},
            "token": "user-token-xyz",
        }
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok(data)):
            result = await client.auth.login("t@t.com", "pass123")
            assert result.value.token == "user-token-xyz"
            assert client.token == "user-token-xyz"

    async def test_logout_clears_token(self, client: AsyncClient) -> None:
        assert client.token == "test-token"
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok()):
            await client.auth.logout()
            assert client.token is None


# ── Account ─────────────────────────────────────────────────────────────────


class TestAccountMock:
    async def test_me(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok(ACCOUNT_INFO)):
            result = await client.account.me()
            assert result.value.id == "u1"
            assert result.value.name == "TestUser"

    async def test_edit_no_changes(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok({"status": 1})):
            result = await client.account.edit()
            assert result.status.code == 10000

    async def test_settings(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok()):
            result = await client.account.settings()
            assert result.status.code == 10000

    async def test_settings_with_params(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok()) as mock:
            await client.account.settings(auto_pub_community=1, localization=2)
            body: dict[str, Any] = mock.call_args.kwargs["json"]
            assert body["auto_pub_community"] == 1
            assert body["localization"] == 2


# ── Payments ────────────────────────────────────────────────────────────────


class TestPaymentsMock:
    async def test_assets(self, client: AsyncClient) -> None:
        with patch.object(client, "request_route", new_callable=AsyncMock, return_value=_ok(PAYMENT_ACCESS_INFO)):
            result = await client.payments.assets()
            assert result.status.code == 10000
            assert result.value is not None
