/**
 * Shared network definitions for Wagmi, Viem, CowSwap, Jumper, and others.
 * Single source of truth for chainId, RPC, explorers, native currency.
 * Chainlist entries: ../chains/_data/chains/eip155-*.json
 */

import { defineChain } from 'viem'
import {
  mainnet,
  base,
  arbitrum,
  polygon,
  optimism,
} from 'wagmi/chains'

const rpcUrl138 = import.meta.env.VITE_RPC_URL_138 || 'https://rpc-http-pub.d-bis.org'
const rpcUrl651940 = import.meta.env.VITE_RPC_URL_651940 || 'https://mainnet-rpc.alltra.global'
const rpcUrl42793 = import.meta.env.VITE_RPC_URL_42793 || 'https://node.mainnet.etherlink.com'

/** When true, testnet 2138 is included in Wagmi chains, RPC map, and supportedChainIds. */
export const chain2138TestnetEnabled =
  import.meta.env.VITE_ENABLE_CHAIN2138 === 'true' ||
  import.meta.env.VITE_ENABLE_CHAIN2138 === '1'

const rpcUrl2138 =
  import.meta.env.VITE_RPC_URL_2138 || 'https://rpc.public-2138.defi-oracle.io'
const explorerUrl2138 =
  import.meta.env.VITE_EXPLORER_URL_2138 || 'https://public-2138.defi-oracle.io'
const configuredDefaultFrontendChainId = Number(
  import.meta.env.VITE_DEFAULT_FRONTEND_CHAIN_ID || 138
)

/** Chain 2138 - DeFi Oracle Meta Testnet (optional; enable with VITE_ENABLE_CHAIN2138) */
export const chain2138Testnet = defineChain({
  id: 2138,
  name: 'DeFi Oracle Meta Testnet',
  network: 'chain2138-testnet',
  nativeCurrency: {
    decimals: 18,
    name: 'testEther',
    symbol: 'tETH',
  },
  rpcUrls: {
    default: { http: [rpcUrl2138] },
    public: { http: [rpcUrl2138] },
  },
  blockExplorers: {
    default: {
      name: 'DeFi Oracle Meta Testnet Explorer',
      url: explorerUrl2138,
    },
  },
})

/** Chain 138 - DeFi Oracle Meta Mainnet */
export const chain138 = defineChain({
  id: 138,
  name: 'DeFi Oracle Meta Mainnet',
  network: 'chain138',
  nativeCurrency: {
    decimals: 18,
    name: 'Ether',
    symbol: 'ETH',
  },
  rpcUrls: {
    default: { http: [rpcUrl138] },
    public: { http: [rpcUrl138] },
  },
  blockExplorers: {
    default: {
      name: 'DBIS Explorer',
      url: 'https://explorer.d-bis.org',
    },
  },
})

/** Chain 651940 - ALL Mainnet */
export const allMainnet = defineChain({
  id: 651940,
  name: 'ALL Mainnet',
  network: 'all-mainnet',
  nativeCurrency: {
    decimals: 18,
    name: 'ALL',
    symbol: 'ALL',
  },
  rpcUrls: {
    default: { http: [rpcUrl651940] },
    public: { http: [rpcUrl651940] },
  },
  blockExplorers: {
    default: {
      name: 'Alltra Explorer',
      url: 'https://alltra.global',
    },
  },
})

/** Chain 42793 - Etherlink Mainnet (Tezos EVM L2) */
export const etherlink = defineChain({
  id: 42793,
  name: 'Etherlink Mainnet',
  network: 'etherlink-mainnet',
  nativeCurrency: {
    decimals: 18,
    name: 'tez',
    symbol: 'XTZ',
  },
  rpcUrls: {
    default: { http: [rpcUrl42793] },
    public: { http: [rpcUrl42793] },
  },
  blockExplorers: {
    default: {
      name: 'Etherlink Explorer',
      url: 'https://explorer.etherlink.com',
    },
  },
})

const rpcUrlBsc = import.meta.env.VITE_BSC_RPC_URL || 'https://bsc-dataseed.binance.org'
const rpcUrlAvalanche = import.meta.env.VITE_AVALANCHE_RPC_URL || 'https://api.avax.network/ext/bc/C/rpc'
const rpcUrlCronos = import.meta.env.VITE_CRONOS_RPC_URL || 'https://evm.cronos.org'
const rpcUrlGnosis = import.meta.env.VITE_GNOSIS_RPC_URL || 'https://rpc.gnosischain.com'

/** BSC - Binance Smart Chain (56) */
export const bsc = defineChain({
  id: 56,
  name: 'BNB Smart Chain',
  network: 'bsc',
  nativeCurrency: { decimals: 18, name: 'BNB', symbol: 'BNB' },
  rpcUrls: { default: { http: [rpcUrlBsc] }, public: { http: [rpcUrlBsc] } },
  blockExplorers: { default: { name: 'BscScan', url: 'https://bscscan.com' } },
})

/** Avalanche C-Chain (43114) */
export const avalanche = defineChain({
  id: 43114,
  name: 'Avalanche C-Chain',
  network: 'avalanche',
  nativeCurrency: { decimals: 18, name: 'AVAX', symbol: 'AVAX' },
  rpcUrls: { default: { http: [rpcUrlAvalanche] }, public: { http: [rpcUrlAvalanche] } },
  blockExplorers: { default: { name: 'Snowtrace', url: 'https://snowtrace.io' } },
})

/** Cronos (25) */
export const cronos = defineChain({
  id: 25,
  name: 'Cronos',
  network: 'cronos',
  nativeCurrency: { decimals: 18, name: 'CRO', symbol: 'CRO' },
  rpcUrls: { default: { http: [rpcUrlCronos] }, public: { http: [rpcUrlCronos] } },
  blockExplorers: { default: { name: 'CronosScan', url: 'https://cronoscan.com' } },
})

/** Gnosis Chain (100) */
export const gnosis = defineChain({
  id: 100,
  name: 'Gnosis',
  network: 'gnosis',
  nativeCurrency: { decimals: 18, name: 'xDAI', symbol: 'xDAI' },
  rpcUrls: { default: { http: [rpcUrlGnosis] }, public: { http: [rpcUrlGnosis] } },
  blockExplorers: { default: { name: 'GnosisScan', url: 'https://gnosisscan.io' } },
})

const customChainsWithout2138 = [
  chain138,
  allMainnet,
  etherlink,
  bsc,
  avalanche,
  cronos,
  gnosis,
] as const

const customChainsWith2138 = [
  chain138,
  chain2138Testnet,
  allMainnet,
  etherlink,
  bsc,
  avalanche,
  cronos,
  gnosis,
] as const

/** All custom chains (Viem Chain type) - for use with Wagmi/Viem */
export const customChains = chain2138TestnetEnabled
  ? customChainsWith2138
  : customChainsWithout2138

/** Source chains the frontend can intentionally target for wallet UX. */
export const frontendSourceChains = chain2138TestnetEnabled
  ? [chain138, chain2138Testnet] as const
  : [chain138] as const

/** Shared source-chain IDs for connect/switch prompts. */
export const frontendSourceChainIds: number[] = frontendSourceChains.map((chain) => chain.id)

const configuredFrontendChain =
  chain2138TestnetEnabled && configuredDefaultFrontendChainId === chain2138Testnet.id
    ? chain2138Testnet
    : chain138

/** Default chain the wallet UX should prompt for. */
export const defaultFrontendChain = configuredFrontendChain
export const defaultFrontendChainId = defaultFrontendChain.id
export const defaultFrontendChainName = defaultFrontendChain.name
export const defaultFrontendExplorerUrl = defaultFrontendChain.blockExplorers.default.url

/** Standard L2s from wagmi/chains (Ethereum, Base, Arbitrum, Polygon, Optimism) */
export const standardChains = [mainnet, base, arbitrum, polygon, optimism] as const

/** All networks: custom + standard. Use in Wagmi createConfig({ chains: allNetworks }) */
export const allNetworks = [...customChains, ...standardChains] as const

/** Chain IDs we support (for CowSwap, Jumper, UI filters) - all deployed contract networks */
export const supportedChainIds = [
  chain138.id,
  ...(chain2138TestnetEnabled ? [chain2138Testnet.id] : []),
  allMainnet.id,
  etherlink.id,
  mainnet.id,
  base.id,
  arbitrum.id,
  polygon.id,
  optimism.id,
  bsc.id,
  avalanche.id,
  cronos.id,
  gnosis.id,
] as const

/** Map chainId -> RPC URL for transports */
export const chainRpcUrls: Record<number, string> = {
  [mainnet.id]: import.meta.env.VITE_MAINNET_RPC_URL || 'https://ethereum.publicnode.com',
  [chain138.id]: rpcUrl138,
  ...(chain2138TestnetEnabled ? { [chain2138Testnet.id]: rpcUrl2138 } : {}),
  [allMainnet.id]: rpcUrl651940,
  [etherlink.id]: rpcUrl42793,
  [bsc.id]: rpcUrlBsc,
  [avalanche.id]: rpcUrlAvalanche,
  [cronos.id]: rpcUrlCronos,
  [gnosis.id]: rpcUrlGnosis,
}
