/**
 * Helper endpoint that wraps a user-signed EIP-3009 authorization into the
 * x402 X-PAYMENT header format and submits it to a target priced endpoint.
 *
 * The user's wallet signs the TransferWithAuthorization typed data directly
 * on their device (Base App / Coinbase Wallet / etc.) — we never touch the key.
 * This route only assembles the base64 X-PAYMENT header and proxies the call.
 *
 * Body:
 *   {
 *     targetPath: "/api/x402/trust/agent-status",
 *     method: "GET" | "POST",
 *     query?: "?address=0x..." (for GET),
 *     body?: { ... } (for POST),
 *     authorization: { from, to, value, validAfter, validBefore, nonce },
 *     signature: "0x..." (65 bytes hex),
 *     network: "base",
 *     scheme: "exact"
 *   }
 *
 * Response: forwards the priced endpoint's status, body, and X-PAYMENT-RESPONSE.
 */

import { NextRequest, NextResponse } from 'next/server';
import { x402ReleaseGateClosed } from '../_lib/release-gate';

interface SubmitBody {
  targetPath: string;
  method: 'GET' | 'POST';
  query?: string;
  body?: any;
  authorization: {
    from: string;
    to: string;
    value: string;
    validAfter: string;
    validBefore: string;
    nonce: string;
  };
  signature: string;
  network?: string;
  scheme?: string;
  x402Version?: number;
}

function isAllowedTarget(path: string): boolean {
  // Allowlist of priced endpoints we will help submit to
  return /^\/api\/x402\/trust\/(agent-status|protocol-stats|contracts|bonds|insurance|disputes|performance|vouching|credentials|bridge|analytics)$/.test(path)
      || path === '/api/x402/contract-call';
}

export async function POST(req: NextRequest) {
  return x402ReleaseGateClosed();

  /* Release gate intentionally makes the legacy implementation unreachable.
     Keep it below only for a separately reviewed replacement/migration. */
  let body: SubmitBody;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
  }

  // Basic validation
  if (!body.targetPath || !isAllowedTarget(body.targetPath)) {
    return NextResponse.json({ error: 'targetPath not allowed' }, { status: 400 });
  }
  if (body.method !== 'GET' && body.method !== 'POST') {
    return NextResponse.json({ error: 'method must be GET or POST' }, { status: 400 });
  }
  const a = body.authorization;
  if (!a || !a.from || !a.to || !a.value || !a.validAfter || !a.validBefore || !a.nonce) {
    return NextResponse.json({ error: 'authorization missing required fields' }, { status: 400 });
  }
  if (!body.signature || !/^0x[0-9a-fA-F]+$/.test(body.signature) || body.signature.length !== 132) {
    return NextResponse.json({ error: 'signature must be a 0x-prefixed 132-char hex string' }, { status: 400 });
  }

  // Build the x402 payment payload
  const paymentPayload = {
    x402Version: body.x402Version ?? 1,
    scheme: body.scheme ?? 'exact',
    network: body.network ?? 'base',
    payload: {
      signature: body.signature,
      authorization: {
        from: a.from,
        to: a.to,
        value: a.value,
        validAfter: a.validAfter,
        validBefore: a.validBefore,
        nonce: a.nonce,
      },
    },
  };

  const xPaymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');

  // Forward to the priced endpoint — same origin (server-to-server)
  const origin = req.nextUrl.origin;
  const targetUrl = origin + body.targetPath + (body.query ?? '');

  const headers: Record<string, string> = { 'X-PAYMENT': xPaymentHeader };
  if (body.method === 'POST') headers['Content-Type'] = 'application/json';

  let resp: Response;
  try {
    resp = await fetch(targetUrl, {
      method: body.method,
      headers,
      body: body.method === 'POST' ? JSON.stringify(body.body ?? {}) : undefined,
    });
  } catch (e: any) {
    return NextResponse.json({ error: 'fetch failed', detail: e?.message ?? String(e) }, { status: 502 });
  }

  // Capture x-payment-response header (contains tx hash) and forward result
  const xPaymentResponse = resp.headers.get('x-payment-response');
  const status = resp.status;
  let payload: any;
  try {
    payload = await resp.json();
  } catch {
    payload = { raw: (await resp.text()).slice(0, 500) };
  }

  let settlement: any = null;
  if (xPaymentResponse) {
    try {
      settlement = JSON.parse(Buffer.from(xPaymentResponse, 'base64').toString('utf-8'));
    } catch { /* ignore */ }
  }

  return NextResponse.json(
    {
      ok: status === 200,
      status,
      settlement, // { success, transaction, network, payer } when paid
      response: payload,
    },
    { status: 200, headers: { 'Cache-Control': 'no-store' } },
  );
}

export async function OPTIONS() {
  return new NextResponse(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    },
  });
}
