"""Tests for FastAPI middleware (mocked facilitator)."""

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

from starlette.testclient import TestClient
from fastapi import FastAPI, Request

from x402_stacks.http.middleware_fastapi import (
    PaymentMiddleware,
    PaymentMiddlewareConfig,
    get_payment,
)
from x402_stacks.types_v2 import X402_HEADERS


@pytest.fixture
def app():
    app = FastAPI()
    config = PaymentMiddlewareConfig(
        network="testnet",
        amount="1000",
        pay_to="ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM",
        facilitator_url="http://mock-facilitator:8085",
    )
    app.add_middleware(PaymentMiddleware, config=config)

    @app.get("/test")
    async def test_endpoint(request: Request):
        payment = get_payment(request)
        return {"ok": True, "paid": payment is not None}

    return app


@pytest.fixture
def client(app):
    return TestClient(app)


class TestFastAPIMiddleware:
    def test_returns_402_without_payment(self, client):
        response = client.get("/test")
        assert response.status_code == 402
        body = response.json()
        assert body["x402Version"] == 2
        assert len(body["accepts"]) == 1
        # Header should be set
        assert X402_HEADERS["PAYMENT_REQUIRED"] in response.headers

    def test_returns_400_invalid_payload(self, client):
        response = client.get(
            "/test",
            headers={X402_HEADERS["PAYMENT_SIGNATURE"]: "not-valid-base64!!!"},
        )
        assert response.status_code == 400

    def test_returns_400_wrong_version(self, client):
        payload = {"x402Version": 1, "accepted": {}, "payload": {"transaction": "x"}}
        encoded = base64.b64encode(json.dumps(payload).encode()).decode()
        response = client.get(
            "/test",
            headers={X402_HEADERS["PAYMENT_SIGNATURE"]: encoded},
        )
        assert response.status_code == 400
