/**
 * GET /api/x402/trust/leaderboard
 *
 * x402 payment-gated leaderboard — $0.02 USDC per query.
 * Top N agents ranked by trust score, with VNS name + bond count + chain.
 *
 * Query:
 *   ?limit=20        — max results (default 20, max 100)
 *   ?chain=base      — filter to a single chain (default: all)
 *
 * Backed by /api/agent/discover (live on-chain enumeration of ERC-8004 registry)
 * + /api/agent/status for trust scoring of top candidates.
 */

import { NextRequest, NextResponse } from 'next/server';
import { withX402MultiNet } from '../_lib/with-x402-multinet';

const handler = async (req: NextRequest) => {
  const { searchParams } = req.nextUrl;
  const limitRaw = parseInt(searchParams.get('limit') || '20', 10);
  const limit = Math.max(1, Math.min(100, isNaN(limitRaw) ? 20 : limitRaw));
  const chainFilter = searchParams.get('chain');

  try {
    // Pull all registered agents across 4 chains
    const discoverUrl = `${req.nextUrl.origin}/api/agent/discover${chainFilter ? `?chain=${encodeURIComponent(chainFilter)}` : ''}`;
    const dRes = await fetch(discoverUrl, { signal: AbortSignal.timeout(20000) });
    const dData = await dRes.json();
    const agents: any[] = dData?.agents || [];

    if (!agents.length) {
      return NextResponse.json({
        leaderboard: [],
        total: 0,
        message: 'No agents found',
        _x402: { paid: true, price: '$0.02 USDC', service: 'vaultfire-trust', facilitator: 'cdp' },
      });
    }

    // Score each agent by querying /api/agent/status — bound concurrency.
    const candidates = agents.slice(0, Math.min(50, limit * 3));
    const scored = await Promise.all(
      candidates.map(async (a) => {
        try {
          const sUrl = `${req.nextUrl.origin}/api/agent/status?address=${encodeURIComponent(a.address)}&chain=${a.chain || 'base'}`;
          const sRes = await fetch(sUrl, { signal: AbortSignal.timeout(8000) });
          const s = await sRes.json();
          return {
            address: a.address,
            vnsName: a.name || s.vnsName || null,
            chain: a.chain || 'base',
            registered: !!s.registered,
            bondCount: s.bondCount || 0,
            trustScore: s.trustScore || 0,
            registeredAt: a.registeredAt || null,
          };
        } catch {
          return {
            address: a.address,
            vnsName: a.name || null,
            chain: a.chain || 'base',
            registered: true,
            bondCount: 0,
            trustScore: 0,
          };
        }
      })
    );

    // Sort: trustScore desc, bondCount desc, registeredAt asc
    scored.sort((a, b) => {
      if (b.trustScore !== a.trustScore) return b.trustScore - a.trustScore;
      if (b.bondCount !== a.bondCount) return b.bondCount - a.bondCount;
      return 0;
    });

    const leaderboard = scored.slice(0, limit).map((row, idx) => ({ rank: idx + 1, ...row }));

    return NextResponse.json({
      leaderboard,
      total: agents.length,
      scoredCount: scored.length,
      chainFilter: chainFilter || 'all',
      _x402: {
        paid: true,
        price: '$0.02 USDC',
        service: 'vaultfire-trust',
        facilitator: 'cdp',
      },
    }, {
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Cache-Control': 'no-store',
      },
    });
  } catch {
    return NextResponse.json(
      { error: 'Failed to query Vaultfire hub' },
      { 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: 'Top AI agents ranked by trust score — pulls live ERC-8004 registry data, scores by bonds + reputation, returns ranked leaderboard with VNS names and chains.',
      mimeType: 'application/json',
      outputSchema: {
        type: 'object',
        properties: {
          leaderboard: { type: 'array' },
          total: { type: 'number' },
          chainFilter: { type: 'string' },
        },
      }
}) as (req: NextRequest) => Promise<Response>;
