/**
 * POST /api/x402/actions/request-validation — $0.25 USDC
 * Calls ERC8004ValidationRegistry.requestValidation(address agentAddress, string claimURI, bytes32 claimHash, uint8 validationType, uint256 validatorsRequired) [payable]
 * Selector 0xd749c05d
 */
import { NextRequest, NextResponse } from 'next/server';
import { withX402 } from 'x402-next';
import { facilitator } from '@coinbase/x402';
import { withActionLogging } from '../_lib/log-action';
import {
  CHAIN_IDS, RPC_URLS, EXPLORERS, VALIDATION_REGISTRY, SUPPORTED_CHAINS,
  isValidAddress, isValidChain, isValidBytes32, encodeAddress, encodeUint256, encodeBytes32, encodeString,
  estimateGas, rejectsPrivateKeyShape,
} from '../_lib/tx-encode';

const PAY_TO = '0xfA15Ee28939B222B0448261A22156070f0A7813C';

const handler = async (req: NextRequest) => {
  let body: any;
  try { body = await req.json(); } catch { body = {}; }
  const keyErr = rejectsPrivateKeyShape(body);
  if (keyErr) return NextResponse.json({ error: keyErr }, { status: 400 });

  const { walletAddress, agentAddress, claimURI, claimHash, validationType = 0, validatorsRequired = 3, bountyWei = '5000000000000000', chain = 'base' } = body;
  if (!walletAddress || !agentAddress || !claimURI || !claimHash) return NextResponse.json({ error: 'Missing: walletAddress, agentAddress, claimURI, claimHash' }, { status: 400 });
  if (!isValidAddress(walletAddress) || !isValidAddress(agentAddress)) return NextResponse.json({ error: 'Invalid address' }, { status: 400 });
  if (!isValidChain(chain)) return NextResponse.json({ error: 'Invalid chain' }, { status: 400 });
  if (!isValidBytes32(claimHash)) return NextResponse.json({ error: 'claimHash must be 0x + 64 hex chars' }, { status: 400 });
  const vType = Number(validationType);
  if (!Number.isInteger(vType) || vType < 0 || vType > 255) return NextResponse.json({ error: 'validationType must be uint8 (0-255)' }, { status: 400 });

  // requestValidation(address, string, bytes32, uint8, uint256)
  // Layout: head (5 slots = 0xa0) where param[1] is offset to string
  // head = address(32) + offset(32) + bytes32(32) + uint8(32) + uint256(32) = 0xa0
  // string at offset 0xa0
  const calldata = '0xd749c05d'
    + encodeAddress(agentAddress)         // [0]
    + encodeUint256(0xa0)                 // [1] offset to string
    + encodeBytes32(claimHash)            // [2]
    + encodeUint256(BigInt(vType))        // [3] uint8 padded
    + encodeUint256(BigInt(validatorsRequired)) // [4]
    + encodeString(String(claimURI));     // string body

  const contract = VALIDATION_REGISTRY[chain];
  const valueHex = '0x' + BigInt(bountyWei).toString(16);
  const gasEstimate = await estimateGas(RPC_URLS[chain], walletAddress, contract, calldata, valueHex);

  return NextResponse.json({
    success: true,
    txData: { to: contract, data: calldata, value: bountyWei, chainId: CHAIN_IDS[chain], gasEstimate },
    chain, explorer: `${EXPLORERS[chain]}/address/${contract}`,
    message: `Sign to request validation for ${agentAddress} on ${chain}. Validators required: ${validatorsRequired}, bounty: ${bountyWei} wei.`,
    securityNote: 'Vaultfire NEVER accepts private keys.',
    _x402: { paid: true, price: '$0.25 USDC', service: 'vaultfire-trust', facilitator: 'cdp', pattern: 'tx-prepare (caller signs)' },
  }, { headers: { 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-store' } });
};

export const POST = withX402(withActionLogging(handler, '$0.25', '/actions/request-validation'), PAY_TO, {
  price: '$0.25', network: 'base',
  config: {
    description: 'Open a validation request on the ERC-8004 Validation Registry — request that N independent validators verify a claim about an agent. Pay $0.25 USDC, post a bounty in ETH, sign in your wallet to file the request on-chain.',
    mimeType: 'application/json',
    outputSchema: {
      input: { type: 'http', method: 'POST', discoverable: true,
        bodySchema: {
          type: 'object', required: ['walletAddress', 'agentAddress', 'claimURI', 'claimHash'],
          properties: {
            walletAddress: { type: 'string' }, agentAddress: { type: 'string' },
            claimURI: { type: 'string' }, claimHash: { type: 'string', description: 'bytes32' },
            validationType: { type: 'string', description: 'uint8 0-255' },
            validatorsRequired: { type: 'string' }, bountyWei: { type: 'string' },
            chain: { type: 'string', enum: ['base', 'avalanche', 'arbitrum', 'polygon'] },
          },
        },
      },
      output: { type: 'object', properties: { success: { type: 'boolean' }, txData: { type: 'object' }, chain: { type: 'string' } } },
    },
  },
}, facilitator);

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' } });
}
