import {
  applyPrimaryTransferToLeaf,
  fetchAllTokenTransfersForTx,
  pickPrimaryFromSummaries,
} from '@dbis/checkpoint-core';
import { checkpointIndexerConfig as cfg } from './config';
import { enrichLeafUsdRecord } from './usdEnrich';

export type LeafRecord = Record<string, unknown>;

export async function enrichLeaves(
  leaves: LeafRecord[],
  blockscoutApi: string
): Promise<LeafRecord[]> {
  const api = blockscoutApi.replace(/\/$/, '');
  const out: LeafRecord[] = [];
  for (const leaf of leaves) {
    const copy = { ...leaf };
    const txHash = String(leaf.txHash || '');
    const needsToken =
      cfg.enrichTokenTransfers &&
      /^0x[a-fA-F0-9]{64}$/.test(txHash) &&
      !copy.token &&
      BigInt(String(copy.value ?? copy.nativeValueWei ?? '0')) === 0n;

    let allErc20: Awaited<ReturnType<typeof fetchAllTokenTransfersForTx>> = [];
    if (needsToken || (cfg.usdEnrichEnabled && /^0x[a-fA-F0-9]{64}$/.test(txHash))) {
      allErc20 = await fetchAllTokenTransfersForTx(api, txHash);
      if (needsToken) {
        applyPrimaryTransferToLeaf(copy, pickPrimaryFromSummaries(allErc20));
      }
    }

    const withUsd = await enrichLeafUsdRecord(copy, {
      apiBaseUrl: cfg.tokenAggregationApiUrl,
      chainId: 138,
      enabled: cfg.usdEnrichEnabled,
      requestDelayMs: cfg.usdRequestDelayMs,
      blockscoutApi: api,
      preloadedErc20: allErc20,
    });
    out.push(withUsd);
    await sleep(60);
  }
  return out;
}

function sleep(ms: number): Promise<void> {
  return new Promise((r) => setTimeout(r, ms));
}
