import { CHAIN_CONFIGS } from '../config/chains';
import { logger } from '../utils/logger';

export interface BlockscoutTokenMeta {
  address: string;
  name?: string;
  symbol?: string;
  decimals: number;
  totalSupply?: string;
  exchangeRate?: number;
}

function parseExchangeRate(value: unknown): number | undefined {
  if (value == null) return undefined;
  const numeric = typeof value === 'number' ? value : Number(value);
  return Number.isFinite(numeric) && numeric > 0 ? numeric : undefined;
}

export async function fetchBlockscoutTokenMeta(
  chainId: number,
  address: string,
): Promise<BlockscoutTokenMeta | null> {
  const explorerUrl = CHAIN_CONFIGS[chainId]?.explorerUrl?.replace(/\/$/, '');
  if (!explorerUrl) {
    return null;
  }

  const normalized = address.toLowerCase();
  try {
    const response = await fetch(`${explorerUrl}/api/v2/tokens/${normalized}`, {
      headers: { Accept: 'application/json' },
      signal: AbortSignal.timeout(8000),
    });
    if (!response.ok) {
      return null;
    }

    const raw = (await response.json()) as {
      address?: string;
      name?: string | null;
      symbol?: string | null;
      decimals?: string | number | null;
      total_supply?: string | null;
      exchange_rate?: string | number | null;
    };

    if (!raw.address) {
      return null;
    }

    return {
      address: raw.address.toLowerCase(),
      name: raw.name || undefined,
      symbol: raw.symbol || undefined,
      decimals: Number(raw.decimals ?? 18),
      totalSupply: raw.total_supply || undefined,
      exchangeRate: parseExchangeRate(raw.exchange_rate),
    };
  } catch (error) {
    logger.warn('Blockscout token meta fetch failed', { chainId, address: normalized, error });
    return null;
  }
}
