"""Tests for httpx interceptor (mocked transport)."""

import base64
import json
import pytest
import httpx

from x402_stacks.http.interceptor_v2 import private_key_to_account
from x402_stacks.http.client_httpx import (
    wrap_httpx_with_payment_sync,
    create_payment_client_sync,
)
from x402_stacks.types_v2 import X402_HEADERS

TEST_KEY = "edf9aee84d9b7abc145504dde6726c64f369d37ee34ced614f76c2dcb7004497"


class MockTransport(httpx.BaseTransport):
    """Mock transport that returns 402, then 200 on retry with payment."""

    def __init__(self):
        self.call_count = 0

    def handle_request(self, request: httpx.Request) -> httpx.Response:
        self.call_count += 1

        # If payment header present, return 200
        if request.headers.get(X402_HEADERS["PAYMENT_SIGNATURE"]):
            return httpx.Response(200, json={"data": "premium"})

        # Otherwise, return 402 with payment requirements
        body = {
            "x402Version": 2,
            "resource": {"url": str(request.url)},
            "accepts": [{
                "scheme": "exact",
                "network": "stacks:2147483648",
                "amount": "1000",
                "asset": "STX",
                "payTo": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM",
                "maxTimeoutSeconds": 300,
            }],
        }
        body_bytes = json.dumps(body).encode()
        header_val = base64.b64encode(body_bytes).decode()
        return httpx.Response(
            402,
            json=body,
            headers={X402_HEADERS["PAYMENT_REQUIRED"]: header_val},
        )


class TestHttpxV2:
    def test_auto_payment_on_402(self):
        account = private_key_to_account(TEST_KEY, "testnet")
        transport = MockTransport()
        client = httpx.Client(transport=transport)
        wrapped = wrap_httpx_with_payment_sync(client, account)

        response = wrapped.get("http://example.com/api")
        assert response.status_code == 200
        assert response.json()["data"] == "premium"
        assert transport.call_count == 2  # First 402, then 200

    def test_no_retry_on_200(self):
        account = private_key_to_account(TEST_KEY, "testnet")

        class OkTransport(httpx.BaseTransport):
            def __init__(self):
                self.call_count = 0
            def handle_request(self, request):
                self.call_count += 1
                return httpx.Response(200, json={"ok": True})

        transport = OkTransport()
        client = httpx.Client(transport=transport)
        wrapped = wrap_httpx_with_payment_sync(client, account)

        response = wrapped.get("http://example.com/api")
        assert response.status_code == 200
        assert transport.call_count == 1

    def test_create_payment_client_sync(self):
        account = private_key_to_account(TEST_KEY, "testnet")
        client = create_payment_client_sync(account)
        assert isinstance(client, httpx.Client)
