import functools
import requests
from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse

def protect(wallet: str, price: str):
    """
    Decorator to protect a FastAPI route with x402 payment.
    
    Args:
        wallet (str): The recipient wallet address.
        price (str): The amount in USDC.
    """
    def decorator(func):
        @functools.wraps(func)
        async def wrapper(request: Request, *args, **kwargs):
            payment_hash = request.headers.get("X-Payment-Hash")

            # Scenario A: No Payment Hash -> Return 402
            if not payment_hash:
                return JSONResponse(
                    status_code=402,
                    content={
                        "maxAmountRequired": price,
                        "payTo": wallet,
                        "network": "base-mainnet",
                        "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
                    }
                )

            # Scenario B: Verify Payment
            try:
                response = requests.post(
                    "https://api.402gate.xyz/x402/verify",
                    json={
                        "paymentHash": payment_hash,
                        "expectedRecipient": wallet
                    },
                    timeout=10 # Good practice to add timeout
                )
                
                if response.status_code == 200:
                    # Success -> Proceed to original function
                    return await func(request, *args, **kwargs)
                else:
                    # API returned error (non-200)
                    return JSONResponse(
                        status_code=402,
                        content={"detail": "Payment Invalid"}
                    )
            except requests.RequestException:
                # Network error or other issue contacting verification API
                # Fail safe to 402 or 500? Requirement says "If API returns error -> 402"
                # But if we can't reach API, maybe 500 is better? 
                # Sticking to 402 as per "Payment Invalid" instruction for simplicity unless specified otherwise,
                # but actually if the verification fails due to network, user might want to know.
                # However, the prompt says "If API returns error -> Return 402". 
                # Let's assume connection error also treats as invalid payment for safety.
                return JSONResponse(
                    status_code=402,
                    content={"detail": "Payment Verification Failed"}
                )

        return wrapper
    return decorator
