/**
 * GET /api/x402/trust/scoped-delegations?address=0x...&chain=base — $0.02 USDC
 * Calls ScopedDelegation.getGrantedScopes(address) returning uint256[]
 * Selector 0xf8389ef4 (full ABI 100% matched on-chain bytecode).
 */
import { NextRequest, NextResponse } from 'next/server';
import { withX402MultiNet } from '../_lib/with-x402-multinet';
import { ethers } from 'ethers';
import { withFailover } from '../../../_lib/rpc-retry';

const ADDRS: Record<string, { address: string; rpc: string; chainId: number; explorer: string }> = {
  base:      { address: '0x716C4f0a822f8A7F73126aEe123ACa0Db225a3DC', rpc: 'https://base-rpc.publicnode.com', chainId: 8453, explorer: 'https://basescan.org' },
  avalanche: { address: '0xD8A8c9604Af2Be2573c3a3102D5094654Da55971', rpc: 'https://api.avax.network/ext/bc/C/rpc', chainId: 43114, explorer: 'https://snowtrace.io' },
  arbitrum:  { address: '0xd42BBfD3061A38D4B5540317A31D90212380069b', rpc: 'https://arb1.arbitrum.io/rpc', chainId: 42161, explorer: 'https://arbiscan.io' },
  polygon:   { address: '0xE02F5029fcDd6c51e957eb3895bd5805126A5Cdc', rpc: 'https://polygon-bor-rpc.publicnode.com', chainId: 137, explorer: 'https://polygonscan.com' },
};

const ABI = [
  'function getGrantedScopes(address agent) view returns (uint256[])',
] as const;

const handler = async (req: NextRequest) => {
  const { searchParams } = req.nextUrl;
  const address = searchParams.get('address');
  const chain = (searchParams.get('chain') || 'base').toLowerCase();
  if (!address) return NextResponse.json({ error: 'address query parameter is required' }, { status: 400 });
  if (!ethers.isAddress(address)) return NextResponse.json({ error: 'Invalid address' }, { status: 400 });
  const cfg = ADDRS[chain];
  if (!cfg) return NextResponse.json({ error: 'Invalid chain. Use base|avalanche|arbitrum|polygon' }, { status: 400 });

  try {
    const ids: bigint[] = await withFailover(chain, async (provider) => {
      const c = new ethers.Contract(cfg.address, ABI, provider);
      return await c.getGrantedScopes(address);
    });
    const scopeIds = ids.map((x) => x.toString());
    return NextResponse.json({
      address: address.toLowerCase(),
      chain,
      contractAddress: cfg.address,
      scopeCount: scopeIds.length,
      scopeIds,
      explorerUrl: `${cfg.explorer}/address/${cfg.address}`,
      _x402: { paid: true, price: '$0.02 USDC', service: 'vaultfire-trust', facilitator: 'cdp' },
    }, { headers: { 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-store' } });
  } catch (e: any) {
    return NextResponse.json({ error: 'Failed to query ScopedDelegation', detail: e?.shortMessage || e?.message || String(e) }, { status: 502 });
  }
};

// Multi-network paywall: accepts USDC on Base AND Solana mainnet.
// Bazaar discovery picks up both networks from the 402 response's `accepts` array.
export const GET = withX402MultiNet(handler, {
  price: '$0.02',
  description: 'List the scoped delegations granted by an agent via ScopedDelegation.getGrantedScopes() — returns the array of scope ids the agent has issued.',
    mimeType: 'application/json',
    outputSchema: {
      type: 'object',
      properties: {
        address: { type: 'string' },
        chain: { type: 'string' },
        contractAddress: { type: 'string' },
        scopeCount: { type: 'number' },
        scopeIds: { type: 'array', items: { type: 'string' } },
        explorerUrl: { type: 'string' },
      },
    }
}) as (req: NextRequest) => Promise<Response>;
