import { getCanonicalTokenByAddress, getCanonicalTokenBySymbol } from './canonical-tokens';

const CHAIN_138 = 138;
const CHAIN_138_WETH = (
  process.env.WETH ||
  process.env.WETH9 ||
  process.env.WETH_ADDRESS_138 ||
  '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
).toLowerCase();
const CHAIN_138_WETH10 = (
  process.env.WETH10 ||
  process.env.WETH10_ADDRESS ||
  process.env.WETH10_ADDRESS_138 ||
  '0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f'
).toLowerCase();

export interface RoutingAssetSpec {
  symbol: string;
  address: string;
  decimals: number;
  kind: 'wrapped' | 'stable' | 'compliant' | 'commodity' | 'monetary_unit';
}

function requireSymbolAddress(chainId: number, symbol: string, fallback?: string): string {
  const canonical = getCanonicalTokenBySymbol(chainId, symbol)?.addresses?.[chainId];
  const value = String(canonical || fallback || '').trim().toLowerCase();
  return value;
}

export function getChain138RoutingAssets(): Record<string, RoutingAssetSpec> {
  return {
    WETH: {
      symbol: 'WETH',
      address: CHAIN_138_WETH,
      decimals: 18,
      kind: 'wrapped',
    },
    WETH10: {
      symbol: 'WETH10',
      address: CHAIN_138_WETH10,
      decimals: 18,
      kind: 'wrapped',
    },
    USDT: {
      symbol: 'USDT',
      address: requireSymbolAddress(CHAIN_138, 'USDT', '0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1'),
      decimals: 6,
      kind: 'stable',
    },
    USDC: {
      symbol: 'USDC',
      address: requireSymbolAddress(CHAIN_138, 'USDC', '0x71D6687F38b93CCad569Fa6352c876eea967201b'),
      decimals: 6,
      kind: 'stable',
    },
    cUSDT: {
      symbol: 'cUSDT',
      address: requireSymbolAddress(CHAIN_138, 'cUSDT', '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22'),
      decimals: 6,
      kind: 'compliant',
    },
    cUSDC: {
      symbol: 'cUSDC',
      address: requireSymbolAddress(CHAIN_138, 'cUSDC', '0xf22258f57794CC8E06237084b353Ab30fFfa640b'),
      decimals: 6,
      kind: 'compliant',
    },
    cBTC: {
      symbol: 'cBTC',
      address: requireSymbolAddress(CHAIN_138, 'cBTC', '0xcb7c000000000000000000000000000000000138'),
      decimals: 8,
      kind: 'monetary_unit',
    },
    cEURT: {
      symbol: 'cEURT',
      address: requireSymbolAddress(CHAIN_138, 'cEURT', '0xdf4b71c61E5912712C1Bdd451416B9aC26949d72'),
      decimals: 6,
      kind: 'compliant',
    },
    cXAUC: {
      symbol: 'cXAUC',
      address: requireSymbolAddress(CHAIN_138, 'cXAUC', '0x290E52a8819A4fbD0714E517225429aA2B70EC6b'),
      decimals: 6,
      kind: 'commodity',
    },
  };
}

export function getDefaultIntermediateAddresses(chainId: number): string[] {
  if (chainId !== CHAIN_138) return [];
  const assets = getChain138RoutingAssets();
  return [
    assets.WETH.address,
    assets.USDT.address,
    assets.USDC.address,
    assets.cUSDT.address,
    assets.cUSDC.address,
    assets.cBTC.address,
  ];
}

export function getCommodityIntermediateAddresses(chainId: number): string[] {
  if (chainId !== CHAIN_138) return [];
  return [getChain138RoutingAssets().cXAUC.address];
}

export function getRoutingSymbolForAddress(chainId: number, address: string): string | undefined {
  const normalized = address.trim().toLowerCase();
  if (chainId === CHAIN_138) {
    const assets = Object.values(getChain138RoutingAssets());
    const asset = assets.find((entry) => entry.address === normalized);
    if (asset) return asset.symbol;
  }

  return getCanonicalTokenByAddress(chainId, normalized)?.symbol;
}

export function getRoutingAddressForSymbol(chainId: number, symbol: string): string | undefined {
  if (chainId === CHAIN_138) {
    const assets = getChain138RoutingAssets();
    const normalized = symbol.trim().toUpperCase();
    if (normalized === 'WETH') {
      return assets.WETH.address;
    }
    if (normalized === 'WETH10') {
      return assets.WETH10.address;
    }
  }
  return getCanonicalTokenBySymbol(chainId, symbol)?.addresses?.[chainId]?.toLowerCase();
}
