const WEI_DECIMALS = 18n

export function formatWeiAsEth(value: string, fractionDigits = 4): string {
  try {
    const normalizedDigits = Math.max(0, Math.min(18, fractionDigits))
    const wei = BigInt(value)
    const divisor = 10n ** WEI_DECIMALS
    const whole = wei / divisor
    const fraction = wei % divisor

    if (normalizedDigits === 0) {
      return `${whole.toString()} ETH`
    }

    const scale = 10n ** (WEI_DECIMALS - BigInt(normalizedDigits))
    const truncatedFraction = fraction / scale
    const paddedFraction = truncatedFraction
      .toString()
      .padStart(normalizedDigits, '0')
      .replace(/0+$/, '')

    if (!paddedFraction) {
      return `${whole.toString()} ETH`
    }

    return `${whole.toString()}.${paddedFraction} ETH`
  } catch {
    return '0 ETH'
  }
}

export function formatUnits(value: string | number | null | undefined, decimals = 18, fractionDigits = 4): string {
  try {
    const safeDecimals = Math.max(0, Math.min(36, decimals))
    const normalizedDigits = Math.max(0, Math.min(12, fractionDigits))
    const amount = BigInt(typeof value === 'number' ? value.toString() : value || '0')
    const divisor = 10n ** BigInt(safeDecimals)
    const whole = amount / divisor
    const fraction = amount % divisor

    if (normalizedDigits === 0 || safeDecimals === 0) {
      return whole.toString()
    }

    const scale = 10n ** BigInt(Math.max(0, safeDecimals - normalizedDigits))
    const truncatedFraction = fraction / scale
    const paddedFraction = truncatedFraction
      .toString()
      .padStart(Math.min(normalizedDigits, safeDecimals), '0')
      .replace(/0+$/, '')

    return paddedFraction ? `${whole.toString()}.${paddedFraction}` : whole.toString()
  } catch {
    return '0'
  }
}

export function formatTokenAmount(value: string | number | null | undefined, decimals = 18, symbol?: string | null, fractionDigits = 4): string {
  const formatted = formatUnits(value, decimals, fractionDigits)
  return symbol ? `${formatted} ${symbol}` : formatted
}

export function formatTimestamp(value?: string | null): string {
  if (!value) return 'Unknown'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) {
    return value
  }
  return date.toLocaleString()
}

export function formatRelativeAge(value?: string | null): string {
  if (!value) return 'Unknown'
  const parsed = Date.parse(value)
  if (!Number.isFinite(parsed)) return 'Unknown'
  const seconds = Math.max(0, Math.round((Date.now() - parsed) / 1000))
  if (seconds < 60) return `${seconds}s ago`
  const minutes = Math.round(seconds / 60)
  if (minutes < 60) return `${minutes}m ago`
  const hours = Math.round(minutes / 60)
  if (hours < 48) return `${hours}h ago`
  const days = Math.round(hours / 24)
  return `${days}d ago`
}
