export interface GruNetworkLink {
  chainId: number
  chainName: string
  symbol: string
  address: string
  notes?: string
  explorerUrl?: string
}

export interface GruExplorerMetadata {
  currencyCode?: string
  iso20022Ready: boolean
  x402Ready: boolean
  activeVersion?: string
  transportActiveVersion?: string
  x402PreferredVersion?: string
  canonicalForwardVersion?: string
  canonicalForwardAddress?: string
  otherNetworks: GruNetworkLink[]
}

interface GruExplorerEntry extends GruExplorerMetadata {
  symbol: string
  addresses: string[]
}

function chainExplorerUrl(chainId: number, address: string): string | undefined {
  switch (chainId) {
    case 1:
      return `https://etherscan.io/address/${address}`
    case 651940:
      return `https://alltra.global/address/${address}`
    case 56:
      return `https://bscscan.com/address/${address}`
    case 100:
      return `https://gnosisscan.io/address/${address}`
    case 137:
      return `https://polygonscan.com/address/${address}`
    default:
      return undefined
  }
}

function networkLink(chainId: number, chainName: string, symbol: string, address: string, notes?: string): GruNetworkLink {
  return {
    chainId,
    chainName,
    symbol,
    address,
    notes,
    explorerUrl: chainExplorerUrl(chainId, address),
  }
}

const GRU_EXPLORER_ENTRIES: GruExplorerEntry[] = [
  {
    symbol: 'cUSDC',
    addresses: [
      '0xf22258f57794cc8e06237084b353ab30fffa640b',
      '0x219522c60e83dee01fc5b0329d6fa8fd84b9d13d',
    ],
    currencyCode: 'USD',
    iso20022Ready: true,
    x402Ready: true,
    activeVersion: 'v1',
    transportActiveVersion: 'v1',
    x402PreferredVersion: 'v2',
    canonicalForwardVersion: 'v2',
    canonicalForwardAddress: '0x219522c60e83dEe01FC5b0329d6fA8fD84b9D13d',
    otherNetworks: [
      networkLink(651940, 'ALL Mainnet (Alltra)', 'AUSDC', '0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881', 'Primary Alltra-native origin counterpart.'),
      networkLink(1, 'Ethereum Mainnet', 'USDC', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'Native Ethereum settlement counterpart.'),
      networkLink(1, 'Ethereum Mainnet', 'cWUSDC', '0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a', 'GRU wrapped public-network representation on Ethereum.'),
      networkLink(56, 'BNB Chain', 'USDC', '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', 'Native BNB Chain settlement counterpart.'),
      networkLink(56, 'BNB Chain', 'cWUSDC', '0x5355148C4740fcc3D7a96F05EdD89AB14851206b', 'GRU wrapped public-network representation on BNB Chain.'),
      networkLink(137, 'Polygon', 'USDC', '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', 'Native Polygon settlement counterpart.'),
      networkLink(137, 'Polygon', 'cWUSDC', '0xd6969bC19b53f866C64f2148aE271B2Dae0C58E4', 'GRU wrapped public-network representation on Polygon.'),
      networkLink(100, 'Gnosis', 'USDC', '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83', 'Native Gnosis settlement counterpart.'),
      networkLink(100, 'Gnosis', 'cWUSDC', '0xd6969bC19b53f866C64f2148aE271B2Dae0C58E4', 'GRU wrapped public-network representation on Gnosis.'),
    ],
  },
  {
    symbol: 'cUSDT',
    addresses: [
      '0x93e66202a11b1772e55407b32b44e5cd8eda7f22',
      '0x9fbfab33882efe0038daa608185718b772ee5660',
    ],
    currencyCode: 'USD',
    iso20022Ready: true,
    x402Ready: true,
    activeVersion: 'v1',
    transportActiveVersion: 'v1',
    x402PreferredVersion: 'v2',
    canonicalForwardVersion: 'v2',
    canonicalForwardAddress: '0x9FBfab33882Efe0038DAa608185718b772EE5660',
    otherNetworks: [
      networkLink(651940, 'ALL Mainnet (Alltra)', 'AUSDT', '0x015B1897Ed5279930bC2Be46F661894d219292A6', 'Primary Alltra-native origin counterpart.'),
      networkLink(1, 'Ethereum Mainnet', 'USDT', '0xdAC17F958D2ee523a2206206994597C13D831ec7', 'Native Ethereum settlement counterpart.'),
      networkLink(1, 'Ethereum Mainnet', 'cWUSDT', '0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE', 'GRU wrapped public-network representation on Ethereum.'),
      networkLink(56, 'BNB Chain', 'USDT', '0x55d398326f99059fF775485246999027B3197955', 'Native BNB Chain settlement counterpart.'),
      networkLink(56, 'BNB Chain', 'cWUSDT', '0x9a1D0dBEE997929ED02fD19E0E199704d20914dB', 'GRU wrapped public-network representation on BNB Chain.'),
      networkLink(137, 'Polygon', 'USDT', '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', 'Native Polygon settlement counterpart.'),
      networkLink(137, 'Polygon', 'cWUSDT', '0x0cb0192C056aa425C557BdeAD8E56C7eEabf7acF', 'GRU wrapped public-network representation on Polygon.'),
      networkLink(100, 'Gnosis', 'USDT', '0x4ECaBa5870353805a9F068101A40E0f32ed605C6', 'Native Gnosis settlement counterpart.'),
      networkLink(100, 'Gnosis', 'cWUSDT', '0x0cb0192C056aa425C557BdeAD8E56C7eEabf7acF', 'GRU wrapped public-network representation on Gnosis.'),
    ],
  },
  {
    symbol: 'cEURC',
    addresses: ['0x8085961f9cf02b4d800a3c6d386d31da4b34266a', '0x243e6581dc8a98d98b92265858b322b193555c81'],
    currencyCode: 'EUR',
    iso20022Ready: true,
    x402Ready: true,
    activeVersion: 'v2',
    x402PreferredVersion: 'v2',
    canonicalForwardVersion: 'v2',
    canonicalForwardAddress: '0x243e6581Dc8a98d98B92265858b322b193555C81',
    otherNetworks: [
      networkLink(56, 'BNB Chain', 'cWEURC', '0x50b073d0D1D2f002745cb9FC28a057d5be84911c', 'GRU wrapped public-network representation on BNB Chain.'),
      networkLink(137, 'Polygon', 'cWEURC', '0x3CD9ee18db7ad13616FCC1c83bC6098e03968E66', 'GRU wrapped public-network representation on Polygon.'),
      networkLink(100, 'Gnosis', 'cWEURC', '0x25603ae4bff0b71d637b3573d1b6657f5f6d17ef', 'GRU wrapped public-network representation on Gnosis.'),
    ],
  },
  {
    symbol: 'cEURT',
    addresses: ['0xdf4b71c61e5912712c1bdd451416b9ac26949d72', '0x2bafa83d8ff8bae9505511998987d0659791605b'],
    currencyCode: 'EUR',
    iso20022Ready: true,
    x402Ready: true,
    activeVersion: 'v2',
    x402PreferredVersion: 'v2',
    canonicalForwardVersion: 'v2',
    canonicalForwardAddress: '0x2bAFA83d8fF8BaE9505511998987D0659791605B',
    otherNetworks: [
      networkLink(56, 'BNB Chain', 'cWEURT', '0x1ED9E491A5eCd53BeF21962A5FCE24880264F63f', 'GRU wrapped public-network representation on BNB Chain.'),
      networkLink(137, 'Polygon', 'cWEURT', '0xBeF5A0Bcc0E77740c910f197138cdD90F98d2427', 'GRU wrapped public-network representation on Polygon.'),
      networkLink(100, 'Gnosis', 'cWEURT', '0x8e54c52d34a684e22865ac9f2d7c27c30561a7b9', 'GRU wrapped public-network representation on Gnosis.'),
    ],
  },
  ...[
    ['cGBPC', 'GBP', '0x003960f16d9d34f2e98d62723b6721fb92074ad2', '0x707508D223103f5D2d9EFBc656302c9d48878b29'],
    ['cGBPT', 'GBP', '0x350f54e4d23795f86a9c03988c7135357ccad97c', '0xee17c18E10E55ce23F7457D018aAa2Fb1E64B281'],
    ['cAUDC', 'AUD', '0xd51482e567c03899eece3cae8a058161fd56069d', '0xfb37aFd415B70C5cEDc9bA58a72D517207b769Bb'],
    ['cJPYC', 'JPY', '0xee269e1226a334182aace90056ee4ee5cc8a6770', '0x2c751bBE4f299b989b3A8c333E0A966cdcA6Fd98'],
    ['cCHFC', 'CHF', '0x873990849dda5117d7c644f0af24370797c03885', '0x60B7FB8e0DD0Be8595AD12Fe80AE832861Be747c'],
    ['cCADC', 'CAD', '0x54dbd40cf05e15906a2c21f600937e96787f5679', '0xe799033c87fE0CE316DAECcefBE3134CC74b76a9'],
    ['cXAUC', 'XAU', '0x290e52a8819a4fbd0714e517225429aa2b70ec6b', '0xF0F0F81bE3D033D8586bAfd2293e37eE2f615647'],
    ['cXAUT', 'XAU', '0x94e408e26c6fd8f4ee00b54df19082fda07dc96e', '0x89477E982847023aaB5C3492082cd1bB4b1b9Ef1'],
  ].map(([symbol, currencyCode, v1Address, v2Address]) => ({
    symbol,
    addresses: [v1Address.toLowerCase(), v2Address.toLowerCase()],
    currencyCode,
    iso20022Ready: true,
    x402Ready: true,
    activeVersion: 'v2',
    x402PreferredVersion: 'v2',
    canonicalForwardVersion: 'v2',
    canonicalForwardAddress: v2Address,
    otherNetworks: [],
  })),
]

function normalizeAddress(address?: string | null): string {
  return (address || '').trim().toLowerCase()
}

function normalizeSymbol(symbol?: string | null): string {
  return (symbol || '').trim().toUpperCase()
}

export function getGruExplorerMetadata(input: {
  address?: string | null
  symbol?: string | null
}): GruExplorerMetadata | null {
  const address = normalizeAddress(input.address)
  const symbol = normalizeSymbol(input.symbol)
  const matched = GRU_EXPLORER_ENTRIES.find((entry) => {
    if (address && entry.addresses.includes(address)) return true
    if (symbol && entry.symbol.toUpperCase() === symbol) return true
    return false
  })
  return matched || null
}
