/** Blockscout ERC-20 transfer parsing (shared by aggregator + indexer). */

export interface TokenTransferSummary {
  token: string;
  tokenSymbol: string;
  tokenDecimals: number;
  from: string;
  to: string;
  value: bigint;
  logIndex: number;
}

interface TokenTransferItem {
  from?: { hash?: string };
  to?: { hash?: string };
  token?: { address?: string; symbol?: string; decimals?: string };
  total?: { value?: string; decimals?: string };
  value?: string | null;
  type?: string;
  log_index?: number;
}

function parseItem(item: TokenTransferItem): TokenTransferSummary | null {
  const token = item.token?.address;
  const raw =
    item.total?.value ??
    (item.value != null && item.value !== '' ? item.value : undefined);
  if (!token || raw === undefined) return null;
  const value = BigInt(raw);
  if (value === 0n) return null;
  const decimals = parseInt(
    item.token?.decimals || item.total?.decimals || '18',
    10
  );
  return {
    token,
    tokenSymbol: item.token?.symbol || '',
    tokenDecimals: Number.isFinite(decimals) ? decimals : 18,
    from: item.from?.hash || '',
    to: item.to?.hash || '',
    value,
    logIndex: item.log_index ?? 0,
  };
}

/** Largest ERC-20 transfer in a tx (legacy primary payment). */
export function pickPrimaryTokenTransfer(items: TokenTransferItem[]): TokenTransferSummary | null {
  let best: TokenTransferSummary | null = null;
  for (const item of items) {
    const summary = parseItem(item);
    if (!summary) continue;
    if (!best || summary.value > best.value) best = summary;
  }
  return best;
}

/** All non-zero ERC-20 transfers in a tx. */
export function parseAllTokenTransfers(items: TokenTransferItem[]): TokenTransferSummary[] {
  const out: TokenTransferSummary[] = [];
  for (const item of items) {
    const summary = parseItem(item);
    if (summary) out.push(summary);
  }
  return out.sort((a, b) => (a.logIndex < b.logIndex ? -1 : a.logIndex > b.logIndex ? 1 : 0));
}

export async function fetchTokenTransferItemsForTx(
  apiBase: string,
  txHash: string
): Promise<TokenTransferItem[]> {
  const base = apiBase.replace(/\/$/, '');
  const res = await fetch(`${base}/transactions/${txHash}/token-transfers`);
  if (!res.ok) return [];
  const body = (await res.json()) as { items?: TokenTransferItem[] };
  return body.items ?? [];
}

export function pickPrimaryFromSummaries(
  items: TokenTransferSummary[]
): TokenTransferSummary | null {
  let best: TokenTransferSummary | null = null;
  for (const s of items) {
    if (!best || s.value > best.value) best = s;
  }
  return best;
}

export function applyPrimaryTransferToLeaf(
  leaf: Record<string, unknown>,
  primary: TokenTransferSummary | null
): void {
  if (!primary) return;
  leaf.token = primary.token;
  leaf.tokenSymbol = primary.tokenSymbol;
  leaf.tokenDecimals = primary.tokenDecimals;
  leaf.tokenValue = primary.value.toString();
  leaf.tokenLogIndex = primary.logIndex;
  if (leaf.nativeValueWei == null) leaf.nativeValueWei = String(leaf.value ?? '0');
}

export async function fetchAllTokenTransfersForTx(
  apiBase: string,
  txHash: string
): Promise<TokenTransferSummary[]> {
  const items = await fetchTokenTransferItemsForTx(apiBase, txHash);
  return parseAllTokenTransfers(items);
}

export async function fetchPrimaryTokenTransferForTx(
  apiBase: string,
  txHash: string
): Promise<TokenTransferSummary | null> {
  const items = await fetchTokenTransferItemsForTx(apiBase, txHash);
  return pickPrimaryTokenTransfer(items);
}
