export type DexType = 'uniswap_v2' | 'uniswap_v3' | 'dodo' | 'custom';

export interface UniswapV2Config {
  factory: string;
  router: string;
  startBlock: number;
}

export interface UniswapV3Config {
  factory: string;
  router: string;
  startBlock: number;
}

export interface DodoConfig {
  poolManager?: string; // DODO PoolManager contract (allPools + poolRegistry ABI)
  dodoPmmIntegration?: string; // DODOPMMIntegration contract (getAllPools + getPoolConfig + getPoolReserves)
  dodoVendingMachine?: string; // DODO Vending Machine Factory
  dodoApprove?: string; // DODO Approve contract
  startBlock: number;
}

export interface CustomDexConfig {
  factory: string;
  router?: string;
  startBlock: number;
  pairCreatedEvent?: string; // Event signature for pair creation
}

export interface DexFactoryConfig {
  uniswap_v2?: UniswapV2Config[];
  uniswap_v3?: UniswapV3Config[];
  dodo?: DodoConfig[];
  custom?: CustomDexConfig[];
}

export const DEX_FACTORIES: Record<number, DexFactoryConfig> = {
  138: {
    // DODO PMM Integration - index from DODOPMMIntegration or PoolManager
    dodo: [
      {
        poolManager: process.env.CHAIN_138_DODO_POOL_MANAGER || '',
        dodoPmmIntegration: process.env.CHAIN_138_DODO_PMM_INTEGRATION || '',
        dodoVendingMachine: process.env.CHAIN_138_DODO_VENDING_MACHINE || '',
        startBlock: 0,
      },
    ],
    // UniswapV2 - if deployed
    uniswap_v2: process.env.CHAIN_138_UNISWAP_V2_FACTORY
      ? [
          {
            factory: process.env.CHAIN_138_UNISWAP_V2_FACTORY,
            router: process.env.CHAIN_138_UNISWAP_V2_ROUTER || '',
            startBlock: parseInt(process.env.CHAIN_138_UNISWAP_V2_START_BLOCK || '0', 10),
          },
        ]
      : undefined,
    // UniswapV3 - if deployed
    uniswap_v3: process.env.CHAIN_138_UNISWAP_V3_FACTORY
      ? [
          {
            factory: process.env.CHAIN_138_UNISWAP_V3_FACTORY,
            router: process.env.CHAIN_138_UNISWAP_V3_ROUTER || '',
            startBlock: parseInt(process.env.CHAIN_138_UNISWAP_V3_START_BLOCK || '0', 10),
          },
        ]
      : undefined,
  },
  651940: {
    // ALL Mainnet - DEX factories to be discovered/configured
    // These can be set via environment variables or discovered on-chain
    uniswap_v2: process.env.CHAIN_651940_UNISWAP_V2_FACTORY
      ? [
          {
            factory: process.env.CHAIN_651940_UNISWAP_V2_FACTORY,
            router: process.env.CHAIN_651940_UNISWAP_V2_ROUTER || '',
            startBlock: parseInt(process.env.CHAIN_651940_UNISWAP_V2_START_BLOCK || '0', 10),
          },
        ]
      : undefined,
    uniswap_v3: process.env.CHAIN_651940_UNISWAP_V3_FACTORY
      ? [
          {
            factory: process.env.CHAIN_651940_UNISWAP_V3_FACTORY,
            router: process.env.CHAIN_651940_UNISWAP_V3_ROUTER || '',
            startBlock: parseInt(process.env.CHAIN_651940_UNISWAP_V3_START_BLOCK || '0', 10),
          },
        ]
      : undefined,
    dodo: process.env.CHAIN_651940_DODO_POOL_MANAGER
      ? [
          {
            poolManager: process.env.CHAIN_651940_DODO_POOL_MANAGER,
            dodoVendingMachine: process.env.CHAIN_651940_DODO_VENDING_MACHINE || '',
            startBlock: parseInt(process.env.CHAIN_651940_DODO_START_BLOCK || '0', 10),
          },
        ]
      : undefined,
  },
  // cW* edge chains (1, 10, 56, 100, 137): set CHAIN_*_DODO_PMM_INTEGRATION or CHAIN_*_DODO_POOL_MANAGER to index DODO/pools
  1: {
    dodo:
      process.env.CHAIN_1_DODO_PMM_INTEGRATION || process.env.CHAIN_1_DODO_POOL_MANAGER
        ? [
            {
              poolManager: process.env.CHAIN_1_DODO_POOL_MANAGER || '',
              dodoPmmIntegration: process.env.CHAIN_1_DODO_PMM_INTEGRATION || '',
              dodoVendingMachine: process.env.CHAIN_1_DODO_VENDING_MACHINE || '',
              startBlock: parseInt(process.env.CHAIN_1_DODO_START_BLOCK || '0', 10),
            },
          ]
        : undefined,
  },
  10: {
    dodo:
      process.env.CHAIN_10_DODO_PMM_INTEGRATION || process.env.CHAIN_10_DODO_POOL_MANAGER
        ? [
            {
              poolManager: process.env.CHAIN_10_DODO_POOL_MANAGER || '',
              dodoPmmIntegration: process.env.CHAIN_10_DODO_PMM_INTEGRATION || '',
              dodoVendingMachine: process.env.CHAIN_10_DODO_VENDING_MACHINE || '',
              startBlock: parseInt(process.env.CHAIN_10_DODO_START_BLOCK || '0', 10),
            },
          ]
        : undefined,
  },
  56: {
    dodo:
      process.env.CHAIN_56_DODO_PMM_INTEGRATION || process.env.CHAIN_56_DODO_POOL_MANAGER
        ? [
            {
              poolManager: process.env.CHAIN_56_DODO_POOL_MANAGER || '',
              dodoPmmIntegration: process.env.CHAIN_56_DODO_PMM_INTEGRATION || '',
              dodoVendingMachine: process.env.CHAIN_56_DODO_VENDING_MACHINE || '',
              startBlock: parseInt(process.env.CHAIN_56_DODO_START_BLOCK || '0', 10),
            },
          ]
        : undefined,
  },
  100: {
    dodo:
      process.env.CHAIN_100_DODO_PMM_INTEGRATION || process.env.CHAIN_100_DODO_POOL_MANAGER
        ? [
            {
              poolManager: process.env.CHAIN_100_DODO_POOL_MANAGER || '',
              dodoPmmIntegration: process.env.CHAIN_100_DODO_PMM_INTEGRATION || '',
              dodoVendingMachine: process.env.CHAIN_100_DODO_VENDING_MACHINE || '',
              startBlock: parseInt(process.env.CHAIN_100_DODO_START_BLOCK || '0', 10),
            },
          ]
        : undefined,
  },
  137: {
    dodo:
      process.env.CHAIN_137_DODO_PMM_INTEGRATION || process.env.CHAIN_137_DODO_POOL_MANAGER
        ? [
            {
              poolManager: process.env.CHAIN_137_DODO_POOL_MANAGER || '',
              dodoPmmIntegration: process.env.CHAIN_137_DODO_PMM_INTEGRATION || '',
              dodoVendingMachine: process.env.CHAIN_137_DODO_VENDING_MACHINE || '',
              startBlock: parseInt(process.env.CHAIN_137_DODO_START_BLOCK || '0', 10),
            },
          ]
        : undefined,
  },
};

/**
 * Get DEX factory configuration for a chain
 */
export function getDexFactories(chainId: number): DexFactoryConfig | undefined {
  return DEX_FACTORIES[chainId];
}

/**
 * Check if a DEX type is configured for a chain
 */
export function hasDexType(chainId: number, dexType: DexType): boolean {
  const config = DEX_FACTORIES[chainId];
  if (!config) return false;

  switch (dexType) {
    case 'uniswap_v2':
      return !!config.uniswap_v2 && config.uniswap_v2.length > 0;
    case 'uniswap_v3':
      return !!config.uniswap_v3 && config.uniswap_v3.length > 0;
    case 'dodo':
      return !!config.dodo && config.dodo.length > 0;
    case 'custom':
      return !!config.custom && config.custom.length > 0;
    default:
      return false;
  }
}

/**
 * Get all configured DEX types for a chain
 */
export function getConfiguredDexTypes(chainId: number): DexType[] {
  const config = DEX_FACTORIES[chainId];
  if (!config) return [];

  const types: DexType[] = [];
  if (hasDexType(chainId, 'uniswap_v2')) types.push('uniswap_v2');
  if (hasDexType(chainId, 'uniswap_v3')) types.push('uniswap_v3');
  if (hasDexType(chainId, 'dodo')) types.push('dodo');
  if (hasDexType(chainId, 'custom')) types.push('custom');

  return types;
}
