/**
 * GET  /api/agent/keys?address=0x...&chain=base  — Read session key + delegation status
 * POST /api/agent/keys                            — Prepare VKP transactions (create wallet, create session, delegate)
 *
 * Vaultfire Key Protocol (VKP) — Secure key management for AI agents.
 * Three contracts work together:
 *   - VKPFactory: Creates dedicated key wallets for agents
 *   - VKPSessionKeyManager: Temporary scoped session keys with expiry
 *   - VKPDelegationRegistry: Agent-to-agent permission delegation
 *
 * SECURITY: This route NEVER accepts or handles private keys.
 */

import { NextRequest, NextResponse } from 'next/server';
import { resolveChain, SUPPORTED_CHAINS } from '../../_lib/resolve-chain';
import {
  VKP_SESSION_KEYS,
  VKP_DELEGATION,
  VKP_FACTORY,
  CHAIN_IDS,
  RPC_URLS,
  EXPLORER_URLS,
  type SupportedChain,
} from '../../../lib/contracts';
import { checkRateLimit, RATE_LIMIT_GET, RATE_LIMIT_WRITE } from '../../../lib/rate-limit';

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

/* ── Selectors ── */
const TOTAL_SESSIONS    = '0x1a7a98e2'; // totalSessions()
const TOTAL_DELEGATIONS = '0x26dc3d48'; // totalDelegations()
const TOTAL_WALLETS     = '0x3f7c4d18'; // totalWallets()

async function rpcCall(rpc: string, to: string, data: string): Promise<string> {
  const res = await fetch(rpc, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_call', params: [{ to, data }, 'latest'] }),
  });
  const json = await res.json();
  return json.result || '0x0';
}

/* ── GET — read VKP status ── */
export async function GET(request: NextRequest) {
  const rl = checkRateLimit(request, RATE_LIMIT_GET);
  if (rl) return rl;

  const chain = resolveChain(request.nextUrl.searchParams.get('chain')) as SupportedChain;
  if (!chain || !SUPPORTED_CHAINS.includes(chain)) {
    return NextResponse.json({ error: `Invalid chain. Use: ${SUPPORTED_CHAINS.join(', ')}` }, { status: 400, headers: CORS });
  }

  const sessionMgr = VKP_SESSION_KEYS[chain];
  const delegation = VKP_DELEGATION[chain];
  const factory    = VKP_FACTORY[chain];
  const rpc        = RPC_URLS[chain];

  try {
    const [rawSessions, rawDelegations, rawWallets] = await Promise.all([
      rpcCall(rpc, sessionMgr, TOTAL_SESSIONS),
      rpcCall(rpc, delegation, TOTAL_DELEGATIONS),
      rpcCall(rpc, factory, TOTAL_WALLETS),
    ]);

    return NextResponse.json({
      chain,
      chainId: CHAIN_IDS[chain],
      contracts: {
        sessionKeyManager: sessionMgr,
        delegationRegistry: delegation,
        factory,
      },
      stats: {
        totalSessions: parseInt(rawSessions, 16) || 0,
        totalDelegations: parseInt(rawDelegations, 16) || 0,
        totalWallets: parseInt(rawWallets, 16) || 0,
      },
      explorer: {
        sessionKeyManager: `${EXPLORER_URLS[chain]}/address/${sessionMgr}`,
        delegationRegistry: `${EXPLORER_URLS[chain]}/address/${delegation}`,
        factory: `${EXPLORER_URLS[chain]}/address/${factory}`,
      },
    }, { headers: CORS });
  } catch {
    return NextResponse.json({ error: 'Failed to read on-chain VKP data' }, { status: 502, headers: CORS });
  }
}

/* ── POST — prepare VKP transaction ── */
export async function POST(request: NextRequest) {
  const rl = checkRateLimit(request, RATE_LIMIT_WRITE);
  if (rl) return rl;

  try {
    const body = await request.json();
    if (body.privateKey || body.private_key) {
      return NextResponse.json({ error: 'SECURITY: This endpoint does not accept private keys.' }, { status: 400, headers: CORS });
    }

    const { action, walletAddress, chain: rawChain = 'base' } = body;
    const chain = resolveChain(rawChain) as SupportedChain;

    if (!walletAddress || !action) {
      return NextResponse.json({ error: 'Missing required fields: action, walletAddress. Actions: createWallet, createSession, delegate' }, { status: 400, headers: CORS });
    }
    if (!chain || !SUPPORTED_CHAINS.includes(chain)) {
      return NextResponse.json({ error: `Invalid chain. Use: ${SUPPORTED_CHAINS.join(', ')}` }, { status: 400, headers: CORS });
    }

    const contracts = {
      sessionKeyManager: VKP_SESSION_KEYS[chain],
      delegationRegistry: VKP_DELEGATION[chain],
      factory: VKP_FACTORY[chain],
    };

    // Return contract info + ABI signatures for the requested action
    const actions: Record<string, { contract: string; abi: string; description: string }> = {
      createWallet: {
        contract: contracts.factory,
        abi: 'createKeyWallet(address agent)',
        description: 'Create a dedicated VKP key wallet for the agent',
      },
      createSession: {
        contract: contracts.sessionKeyManager,
        abi: 'createSession(address agent, address sessionKey, uint256 expiry, bytes32 scope)',
        description: 'Create a temporary scoped session key with expiry',
      },
      delegate: {
        contract: contracts.delegationRegistry,
        abi: 'delegate(address delegator, address delegate, bytes32 permissions)',
        description: 'Delegate permissions from one agent to another',
      },
      revoke: {
        contract: contracts.delegationRegistry,
        abi: 'revokeDelegation(address delegator, address delegate)',
        description: 'Revoke a previously granted delegation',
      },
      revokeSession: {
        contract: contracts.sessionKeyManager,
        abi: 'revokeSession(address agent, address sessionKey)',
        description: 'Revoke an active session key',
      },
    };

    const selected = actions[action];
    if (!selected) {
      return NextResponse.json({
        error: `Unknown action "${action}". Available: ${Object.keys(actions).join(', ')}`,
        availableActions: Object.entries(actions).map(([k, v]) => ({ action: k, ...v })),
      }, { status: 400, headers: CORS });
    }

    return NextResponse.json({
      success: true,
      action,
      chain,
      chainId: CHAIN_IDS[chain],
      contract: selected.contract,
      abi: selected.abi,
      description: selected.description,
      allContracts: contracts,
      explorerUrl: `${EXPLORER_URLS[chain]}/address/${selected.contract}`,
      message: `Call ${selected.abi} on ${selected.contract} to ${selected.description.toLowerCase()}.`,
    }, { headers: CORS });
  } catch {
    return NextResponse.json({ error: 'Internal server error' }, { status: 500, headers: CORS });
  }
}
