import fs from 'fs';
import path from 'path';

export interface MonadRelayLaneChainSide {
  chainId: number;
  selector: string;
  explorer: string;
  rpcEnv?: string;
  rpcDefault?: string;
  sendBridgeWeth9: string;
  relayBridgeInbound?: string;
  relayBridgeOutbound?: string;
  ccipEventRouter?: string;
  ccipRelayRouter?: string;
  ccipRouterSend?: string;
  hubBridgeWeth9?: string;
}

export interface MonadRelaySeedMessage {
  messageId: string;
  direction: '138-to-monad' | 'monad-to-138';
  status: 'initiated' | 'relaying' | 'delivered' | 'failed';
  sourceTxHash?: string;
  relayTxHash?: string;
  amountWei?: string;
  tokenSymbol?: string;
  sender?: string;
  recipient?: string;
}

export interface MonadRelayLaneConfig {
  version: string;
  laneId: string;
  description: string;
  integration?: {
    explorerApi?: string;
    ccipExplorer?: boolean;
    relayService?: string;
    creRequired?: boolean;
    creNotes?: string;
  };
  chain138: MonadRelayLaneChainSide;
  monad: MonadRelayLaneChainSide;
  seedMessages?: MonadRelaySeedMessage[];
}

const BUILTIN_DEFAULTS: MonadRelayLaneConfig = {
  version: '2026-06-13',
  laneId: '138-monad-relay',
  description: 'Custom CCIP relay lane (event-only routers + off-chain relay).',
  chain138: {
    chainId: 138,
    selector: '16015286601757825753',
    explorer: 'https://explorer.d-bis.org',
    rpcEnv: 'RPC_URL_138',
    sendBridgeWeth9: '0xcacfd227A040002e49e2e01626363071324f820a',
    relayBridgeInbound: '0xEB87B3bE09Ab383Ea391caf5bCE70B44Dbd80A9B',
    ccipEventRouter: '0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817',
    ccipRelayRouter: '0xe75d26bc558a28442f30750c6d97bffb46f39abc',
  },
  monad: {
    chainId: 143,
    selector: '8481857512324358265',
    explorer: 'https://monadscan.com',
    rpcEnv: 'MONAD_MAINNET_RPC',
    rpcDefault: 'https://rpc.monad.xyz',
    sendBridgeWeth9: '0xF9DD3349C7f11812d727Db5335690b1e6AD16a52',
    relayBridgeOutbound: '0xC158b6cD3A3088C52F797D41f5Aa02825361629e',
    ccipRelayRouter: '0x89dd12025bfCD38A168455A44B400e913ED33BE2',
    ccipRouterSend: '0x937824f2516fa58f25aeAb92E7BFf7D74F463B4c',
    hubBridgeWeth9: '0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e',
  },
};

function uniquePaths(paths: Array<string | undefined | null>): string[] {
  const seen = new Set<string>();
  const out: string[] = [];
  for (const candidate of paths) {
    if (typeof candidate !== 'string') continue;
    const trimmed = candidate.trim();
    if (!trimmed || seen.has(trimmed)) continue;
    seen.add(trimmed);
    out.push(trimmed);
  }
  return out;
}

export function resolveMonadRelayLaneConfigPath(): string | null {
  const candidates = uniquePaths([
    process.env.MONAD_RELAY_LANE_JSON_PATH,
    path.resolve(process.cwd(), 'config', 'monad-chain138-relay-lane.v1.json'),
    path.resolve(process.cwd(), '..', 'config', 'monad-chain138-relay-lane.v1.json'),
    path.resolve(process.cwd(), '..', '..', 'config', 'monad-chain138-relay-lane.v1.json'),
    path.resolve(process.cwd(), '..', '..', '..', 'config', 'monad-chain138-relay-lane.v1.json'),
    path.resolve(__dirname, '../../../../../config/monad-chain138-relay-lane.v1.json'),
  ]);

  for (const candidate of candidates) {
    if (fs.existsSync(candidate)) return candidate;
  }
  return null;
}

export function loadMonadRelayLaneConfig(): MonadRelayLaneConfig {
  const configPath = resolveMonadRelayLaneConfigPath();
  if (!configPath) return BUILTIN_DEFAULTS;

  try {
    const raw = fs.readFileSync(configPath, 'utf8');
    const parsed = JSON.parse(raw) as MonadRelayLaneConfig;
    return {
      ...BUILTIN_DEFAULTS,
      ...parsed,
      chain138: { ...BUILTIN_DEFAULTS.chain138, ...parsed.chain138 },
      monad: { ...BUILTIN_DEFAULTS.monad, ...parsed.monad },
    };
  } catch {
    return BUILTIN_DEFAULTS;
  }
}

export function resolveMonadRpcUrl(config: MonadRelayLaneConfig = loadMonadRelayLaneConfig()): string {
  const envKey = config.monad.rpcEnv ?? 'MONAD_MAINNET_RPC';
  const fromEnv = process.env[envKey]?.trim();
  if (fromEnv) return fromEnv;
  return config.monad.rpcDefault ?? 'https://rpc.monad.xyz';
}
