"""Tests for requests interceptor (mocked HTTP)."""

import base64
import json
from unittest.mock import patch, MagicMock
import pytest
import responses

from x402_stacks.http.interceptor_v2 import private_key_to_account
from x402_stacks.http.client_requests import (
    PaymentSession,
    create_payment_session,
    PaymentSessionV1,
    create_payment_session_v1,
)
from x402_stacks.types_v2 import X402_HEADERS

TEST_KEY = "edf9aee84d9b7abc145504dde6726c64f369d37ee34ced614f76c2dcb7004497"
TEST_URL = "http://example.com/api"


class TestRequestsV2:
    @responses.activate
    def test_auto_payment_on_402(self):
        account = private_key_to_account(TEST_KEY, "testnet")

        body_402 = {
            "x402Version": 2,
            "resource": {"url": TEST_URL},
            "accepts": [{
                "scheme": "exact",
                "network": "stacks:2147483648",
                "amount": "1000",
                "asset": "STX",
                "payTo": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM",
                "maxTimeoutSeconds": 300,
            }],
        }
        header_val = base64.b64encode(json.dumps(body_402).encode()).decode()

        # First call: 402
        responses.add(
            responses.GET,
            TEST_URL,
            json=body_402,
            status=402,
            headers={X402_HEADERS["PAYMENT_REQUIRED"]: header_val},
        )
        # Second call: 200 (with payment)
        responses.add(
            responses.GET,
            TEST_URL,
            json={"data": "premium"},
            status=200,
        )

        session = create_payment_session(account)
        response = session.get(TEST_URL)
        assert response.status_code == 200
        assert response.json()["data"] == "premium"

    @responses.activate
    def test_no_retry_on_200(self):
        account = private_key_to_account(TEST_KEY, "testnet")

        responses.add(
            responses.GET,
            TEST_URL,
            json={"ok": True},
            status=200,
        )

        session = create_payment_session(account)
        response = session.get(TEST_URL)
        assert response.status_code == 200
        assert len(responses.calls) == 1

    def test_create_session(self):
        account = private_key_to_account(TEST_KEY, "testnet")
        session = create_payment_session(account)
        assert isinstance(session, PaymentSession)


class TestRequestsV1:
    @responses.activate
    def test_auto_payment_on_402_v1(self):
        account = private_key_to_account(TEST_KEY, "testnet")

        body_402 = {
            "maxAmountRequired": "1000",
            "resource": "/api",
            "payTo": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM",
            "network": "testnet",
            "nonce": "abc123",
            "expiresAt": "2099-01-01T00:00:00Z",
        }

        responses.add(responses.GET, TEST_URL, json=body_402, status=402)
        responses.add(responses.GET, TEST_URL, json={"data": "ok"}, status=200)

        session = create_payment_session_v1(account)
        response = session.get(TEST_URL)
        assert response.status_code == 200
