export interface NetworkSeedEntry {
  readonly name: string;
  readonly symbol: string;
  readonly chainId?: number | null;
  readonly category?: 'evm' | 'nonEvm';
}

export const evmNetworks: NetworkSeedEntry[] = [
  { name: 'Ethereum', symbol: 'ETH', chainId: 1 },
  { name: 'BNB Smart Chain', symbol: 'BNB', chainId: 56 },
  { name: 'Base', symbol: 'ETH', chainId: 8453 },
  { name: 'Arbitrum One', symbol: 'ETH', chainId: 42161 },
  { name: 'Optimism', symbol: 'ETH', chainId: 10 },
  { name: 'Polygon PoS', symbol: 'POL', chainId: 137 },
  { name: 'Avalanche C-Chain', symbol: 'AVAX', chainId: 43114 },
  { name: 'Fantom', symbol: 'FTM', chainId: 250 },
  { name: 'Sonic', symbol: 'S', chainId: 146 },
  { name: 'Linea', symbol: 'ETH', chainId: 59144 },
  { name: 'zkSync Era', symbol: 'ETH', chainId: 324 },
  { name: 'Scroll', symbol: 'ETH', chainId: 534352 },
  { name: 'Mantle', symbol: 'MNT', chainId: 5000 },
  { name: 'Blast', symbol: 'ETH', chainId: 81457 },
  { name: 'Manta Pacific', symbol: 'ETH', chainId: 169 },
  { name: 'Ronin', symbol: 'RON', chainId: 2020 },
  { name: 'Celo', symbol: 'CELO', chainId: 42220 },
  { name: 'Cronos', symbol: 'CRO', chainId: 25 },
  { name: 'Gnosis', symbol: 'xDAI', chainId: 100 },
  { name: 'Moonbeam', symbol: 'GLMR', chainId: 1284 },
  { name: 'Moonriver', symbol: 'MOVR', chainId: 1285 },
  { name: 'Harmony', symbol: 'ONE', chainId: 1666600000 },
  { name: 'Aurora', symbol: 'ETH', chainId: 1313161554 },
  { name: 'Kava EVM', symbol: 'KAVA', chainId: 2222 },
  { name: 'OKTC', symbol: 'OKT', chainId: 66 },
  { name: 'HECO', symbol: 'HT', chainId: 128 },
  { name: 'Wanchain', symbol: 'WAN', chainId: 888 },
  { name: 'Viction', symbol: 'VIC', chainId: 88 },
  { name: 'Ethereum Classic', symbol: 'ETC', chainId: 61 },
  { name: 'Acala EVM', symbol: 'ACA', chainId: 787 },
  { name: 'GoChain', symbol: 'GO', chainId: 60 },
  { name: 'ThunderCore', symbol: 'TT', chainId: 108 },
  { name: 'Callisto', symbol: 'CLO', chainId: 820 },
  { name: 'POA Network', symbol: 'POA', chainId: 99 },
];

export const nonEvmNetworks: NetworkSeedEntry[] = [
  { name: 'Bitcoin', symbol: 'BTC' },
  { name: 'Litecoin', symbol: 'LTC' },
  { name: 'Dogecoin', symbol: 'DOGE' },
  { name: 'Bitcoin Cash', symbol: 'BCH' },
  { name: 'Dash', symbol: 'DASH' },
  { name: 'DigiByte', symbol: 'DGB' },
  { name: 'Zcash', symbol: 'ZEC' },
  { name: 'Ravencoin', symbol: 'RVN' },
  { name: 'Decred', symbol: 'DCR' },
  { name: 'Cosmos', symbol: 'ATOM' },
  { name: 'Osmosis', symbol: 'OSMO' },
  { name: 'Sei', symbol: 'SEI' },
  { name: 'Injective', symbol: 'INJ' },
  { name: 'Celestia', symbol: 'TIA' },
  { name: 'Akash', symbol: 'AKT' },
  { name: 'Juno', symbol: 'JUNO' },
  { name: 'Stargaze', symbol: 'STARS' },
  { name: 'Terra', symbol: 'LUNA' },
  { name: 'Terra Classic', symbol: 'LUNC' },
  { name: 'Axelar', symbol: 'AXL' },
  { name: 'Agoric', symbol: 'BLD' },
  { name: 'Stride', symbol: 'STRD' },
  { name: 'Evmos', symbol: 'EVMOS' },
  { name: 'Polkadot', symbol: 'DOT' },
  { name: 'Kusama', symbol: 'KSM' },
  { name: 'Cardano', symbol: 'ADA' },
  { name: 'Algorand', symbol: 'ALGO' },
  { name: 'Solana', symbol: 'SOL' },
  { name: 'Aptos', symbol: 'APT' },
  { name: 'Sui', symbol: 'SUI' },
  { name: 'Near Protocol', symbol: 'NEAR' },
  { name: 'TON', symbol: 'TON' },
  { name: 'Tron', symbol: 'TRX' },
  { name: 'XRP Ledger', symbol: 'XRP' },
  { name: 'Stellar', symbol: 'XLM' },
  { name: 'Tezos', symbol: 'XTZ' },
  { name: 'Hedera', symbol: 'HBAR' },
  { name: 'VeChain', symbol: 'VET' },
  { name: 'IoTeX', symbol: 'IOTX' },
  { name: 'EOS', symbol: 'EOS' },
  { name: 'NEO', symbol: 'NEO' },
  { name: 'Ontology', symbol: 'ONT' },
  { name: 'Nano', symbol: 'XNO' },
  { name: 'Nervos', symbol: 'CKB' },
  { name: 'MultiversX', symbol: 'EGLD' },
  { name: 'Secret Network', symbol: 'SCRT' },
  { name: 'Kaspa', symbol: 'KAS' },
  { name: 'ZetaChain', symbol: 'ZETA' },
  { name: 'Chia', symbol: 'XCH' },
  { name: 'ICON', symbol: 'ICX' },
  { name: 'Qtum', symbol: 'QTUM' },
  { name: 'Waves', symbol: 'WAVES' },
  { name: 'Filecoin', symbol: 'FIL' },
];

export const allNetworks: NetworkSeedEntry[] = [
  ...evmNetworks.map((entry) => ({ ...entry, category: 'evm' as const })),
  ...nonEvmNetworks.map((entry) => ({ ...entry, category: 'nonEvm' as const })),
];

const evmExplorerByChainId: Record<number, string> = {
  1: 'https://etherscan.io',
  56: 'https://bscscan.com',
  8453: 'https://basescan.org',
  42161: 'https://arbiscan.io',
  10: 'https://optimistic.etherscan.io',
  137: 'https://polygonscan.com',
  43114: 'https://snowtrace.io',
  250: 'https://ftmscan.com',
  146: 'https://sonicscan.org',
  59144: 'https://lineascan.build',
  324: 'https://explorer.zksync.io',
  534352: 'https://scrollscan.com',
  5000: 'https://explorer.mantle.xyz',
  81457: 'https://blastscan.io',
  169: 'https://pacific-explorer.manta.network',
  2020: 'https://explorer.roninchain.com',
  42220: 'https://explorer.celo.org',
  25: 'https://cronoscan.com',
  100: 'https://gnosisscan.io',
  1284: 'https://moonbeam.moonscan.io',
  1285: 'https://moonriver.moonscan.io',
  1666600000: 'https://explorer.harmony.one',
  1313161554: 'https://explorer.aurora.dev',
  2222: 'https://explorer.kava.io',
  66: 'https://www.oklink.com/oktc',
  128: 'https://hecoinfo.com',
  888: 'https://wanscan.org',
  88: 'https://vicscan.xyz',
  61: 'https://etc.blockscout.com',
  787: 'https://blockscout.acala.network',
  60: 'https://explorer.gochain.io',
  108: 'https://scan.thundercore.com',
  820: 'https://explorer.callisto.network',
  99: 'https://blockscout.com/poa/core',
};

export const evmTrustWalletChainByChainId: Record<number, string> = {
  1: 'ethereum',
  56: 'smartchain',
  8453: 'base',
  42161: 'arbitrum',
  10: 'optimism',
  137: 'polygon',
  43114: 'avalanchec',
  250: 'fantom',
  146: 'sonic',
  59144: 'linea',
  324: 'zksync',
  534352: 'scroll',
  5000: 'mantle',
  81457: 'blast',
  169: 'manta',
  2020: 'ronin',
  42220: 'celo',
  25: 'cronos',
  100: 'xdai',
  1284: 'moonbeam',
  1285: 'moonriver',
  1666600000: 'harmony',
  1313161554: 'aurora',
  2222: 'kava',
  66: 'okc',
  128: 'heco',
  888: 'wanchain',
  88: 'tomochain',
  61: 'classic',
  787: 'acala',
  60: 'gochain',
  820: 'callisto',
  99: 'poa',
};

const nonEvmExplorerByName: Record<string, string> = {
  Bitcoin: 'https://blockchair.com/bitcoin',
  Litecoin: 'https://blockchair.com/litecoin',
  Dogecoin: 'https://blockchair.com/dogecoin',
  'Bitcoin Cash': 'https://blockchair.com/bitcoin-cash',
  Dash: 'https://blockchair.com/dash',
  DigiByte: 'https://dgbexplorer.info',
  Zcash: 'https://blockchair.com/zcash',
  Ravencoin: 'https://blockchair.com/ravencoin',
  Decred: 'https://dcrdata.decred.org',
  Cosmos: 'https://www.mintscan.io/cosmos',
  Osmosis: 'https://www.mintscan.io/osmosis',
  Sei: 'https://www.mintscan.io/sei',
  Injective: 'https://www.mintscan.io/injective',
  Celestia: 'https://www.mintscan.io/celestia',
  Akash: 'https://www.mintscan.io/akash',
  Juno: 'https://www.mintscan.io/juno',
  Stargaze: 'https://www.mintscan.io/stargaze',
  Terra: 'https://www.mintscan.io/terra',
  'Terra Classic': 'https://www.mintscan.io/terra-classic',
  Axelar: 'https://www.mintscan.io/axelar',
  Agoric: 'https://www.mintscan.io/agoric',
  Stride: 'https://www.mintscan.io/stride',
  Evmos: 'https://www.mintscan.io/evmos',
  Polkadot: 'https://polkadot.subscan.io',
  Kusama: 'https://kusama.subscan.io',
  Cardano: 'https://cexplorer.io',
  Algorand: 'https://algoexplorer.io',
  Solana: 'https://solscan.io',
  Aptos: 'https://explorer.aptoslabs.com',
  Sui: 'https://suiscan.xyz',
  'Near Protocol': 'https://explorer.near.org',
  TON: 'https://tonscan.org',
  Tron: 'https://tronscan.org',
  'XRP Ledger': 'https://xrpscan.com',
  Stellar: 'https://stellar.expert',
  Tezos: 'https://tzstats.com',
  Hedera: 'https://hashscan.io',
  VeChain: 'https://explore.vechain.org',
  IoTeX: 'https://iotexscan.io',
  EOS: 'https://bloks.io',
  NEO: 'https://neo3.neoline.io',
  Ontology: 'https://explorer.ont.io',
  Nano: 'https://nanolooker.com',
  Nervos: 'https://explorer.nervos.org',
  MultiversX: 'https://explorer.multiversx.com',
  'Secret Network': 'https://www.mintscan.io/secret',
  Kaspa: 'https://explorer.kaspa.org',
  ZetaChain: 'https://explorer.zetachain.com',
  Chia: 'https://www.chiaexplorer.com',
  ICON: 'https://tracker.icon.foundation',
  Qtum: 'https://explorer.qtum.org',
  Waves: 'https://wavesexplorer.com',
  Filecoin: 'https://filfox.info',
};

export const getNetworkSlug = (name: string): string =>
  name
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '');

export const getNetworkThumbnail = (entry: NetworkSeedEntry): string => {
  // Use Trust Wallet assets for EVM chains. cryptologos.cc URLs such as
  // `base-eth-logo.png` return 404 for many L2s and caused the fallback logic
  // to assign the L1 (e.g. Ethereum) logo to every L2 sharing the same symbol.
  if (entry.chainId != null && evmTrustWalletChainByChainId[entry.chainId]) {
    const chain = evmTrustWalletChainByChainId[entry.chainId];
    return `https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/${chain}/info/logo.png`;
  }

  const slug = getNetworkSlug(entry.name);
  const symbol = entry.symbol.toLowerCase();
  return `https://cryptologos.cc/logos/${slug}-${symbol}-logo.png`;
};

export const getNetworkExplorer = (entry: NetworkSeedEntry): string => {
  const category = entry.category ?? (entry.chainId != null ? 'evm' : 'nonEvm');
  if (category === 'evm' && entry.chainId != null) {
    return evmExplorerByChainId[entry.chainId] ?? `https://chainlist.org/chain/${entry.chainId}`;
  }
  return nonEvmExplorerByName[entry.name] ?? `https://www.google.com/search?q=${encodeURIComponent(entry.name + ' block explorer')}`;
};

const utxoLikeSymbols = new Set(['BTC', 'LTC', 'DOGE', 'BCH', 'DASH', 'DGB', 'ZEC', 'RVN', 'DCR']);

export const getNetworkAddressType = (entry: NetworkSeedEntry): string => {
  const category = entry.category ?? (entry.chainId != null ? 'evm' : 'nonEvm');
  if (category === 'evm') {
    return 'evm';
  }

  const symbol = entry.symbol.toUpperCase();
  if (utxoLikeSymbols.has(symbol)) return `bitcoin-${symbol.toLowerCase()}`;

  switch (symbol) {
    case 'SOL':
      return 'solana';
    case 'XRP':
    case 'XLM':
      return 'ripple';
    case 'ATOM':
    case 'OSMO':
    case 'SEI':
    case 'INJ':
    case 'TIA':
    case 'AKT':
    case 'JUNO':
    case 'STARS':
    case 'LUNA':
    case 'LUNC':
    case 'AXL':
    case 'BLD':
    case 'STRD':
    case 'EVMOS':
      return 'cosmos';
    case 'DOT':
    case 'KSM':
      return 'polkadot';
    case 'ADA':
      return 'cardano';
    case 'ALGO':
      return 'algorand';
    case 'APT':
      return 'aptos';
    case 'SUI':
      return 'sui';
    case 'NEAR':
      return 'near';
    case 'TON':
      return 'ton';
    case 'TRX':
      return 'tron';
    case 'XTZ':
      return 'tezos';
    case 'HBAR':
      return 'hedera';
    case 'VET':
      return 'vechain';
    case 'IOTX':
      return 'iotex';
    case 'EOS':
      return 'eos';
    case 'NEO':
      return 'neo';
    case 'ONT':
      return 'ontology';
    case 'XNO':
      return 'nano';
    case 'CKB':
      return 'nervos';
    case 'EGLD':
      return 'multiversx';
    case 'SCRT':
      return 'secret';
    case 'KAS':
      return 'kaspa';
    case 'ZETA':
      return 'zetachain';
    case 'XCH':
      return 'chia';
    case 'ICX':
      return 'icon';
    case 'QTUM':
      return 'qtum';
    case 'WAVES':
      return 'waves';
    case 'FIL':
      return 'filecoin';
    default:
      return 'non-evm';
  }
};

export const getNativeDecimals = (addressType: string, symbol: string): number => {
  const upperSymbol = symbol.toUpperCase();
  switch (addressType) {
    case 'bitcoin':
    case 'bitcoin-btc':
    case 'bitcoin-ltc':
    case 'bitcoin-doge':
    case 'bitcoin-bch':
    case 'bitcoin-dash':
    case 'bitcoin-dgb':
    case 'bitcoin-zec':
    case 'bitcoin-rvn':
    case 'bitcoin-dcr':
      return 8;
    case 'solana':
      return 9;
    case 'ripple':
      return upperSymbol === 'XLM' ? 7 : 6;
    case 'cosmos':
      return 6;
    case 'polkadot':
      return 10;
    case 'cardano':
      return 6;
    case 'algorand':
      return 6;
    case 'aptos':
      return 8;
    case 'sui':
      return 9;
    case 'near':
      return 24;
    case 'ton':
      return 9;
    case 'tron':
      return 6;
    case 'tezos':
      return 6;
    case 'hedera':
      return 8;
    case 'eos':
      return 4;
    case 'neo':
    case 'ontology':
      return 0;
    case 'nano':
      return 30;
    case 'nervos':
      return 8;
    case 'chia':
      return 12;
    case 'qtum':
    case 'waves':
      return 8;
    case 'evm':
    default:
      return 18;
  }
};
