// wci26/live-adapter.jsx - direct Sepolia JSON-RPC adapter for the dashboard.

const WCI_INDEXER_PLAN = {
  eventSources: [
    {
      key: 'factory',
      contract: 'WCI26FactoryV3',
      addressField: 'factoryAddress',
      events: [
        'TokenDeployed',
        'PoolCreated',
        'BuybackReady',
        'EliminatedFeesReady',
        'FeesCollected',
        'VolumeRecorded',
        'CountryTokenFeesBurned',
        'BuybackTriggered',
        'BuybackFailed',
        'BuybackDeferred',
        'CountryEliminated',
        'CountryReinstated',
        'ReserveDistributed',
        'AirdropDistributed',
        'TreasuryDistributed',
        'RewardsDistributed',
        'GroupStageResult',
        'WeeklyChampionCrowned',
      ],
    },
    {
      key: 'buyback',
      contract: 'WCI26BuybackV3',
      addressField: 'buybackExecutorAddress',
      events: ['BuybackExecuted', 'BuybackDeferred', 'BuybackDisabled', 'V2PairSet'],
    },
    {
      key: 'countryToken',
      contract: 'CountryTokenV3',
      addressField: 'countries.*.tokenAddress',
      events: ['Initialized', 'PoolCached', 'Transfer'],
    },
    {
      key: 'uniswapV3Pool',
      contract: 'UniswapV3Pool',
      addressField: 'countries.*.v3PoolAddress',
      events: ['Swap', 'Mint', 'Burn', 'Collect'],
    },
  ],
  entities: [
    'countries',
    'country_tokens',
    'country_pools',
    'fee_collections',
    'volume_snapshots',
    'buyback_pressure_snapshots',
    'buyback_executions',
    'allocation_buckets',
    'leaderboard_snapshots',
    'weekly_snapshots',
    'group_stage_results',
    'holders',
    'recent_events',
  ],
  realtimeChannels: [
    'country.updated',
    'leaderboard.updated',
    'buyback.ready',
    'buyback.executed',
    'allocations.updated',
    'season.updated',
  ],
};

const WCI_LIVE_SELECTORS = {
  getCountry: '0xb16f9ab0',
  pendingWETH: '0xbef7b15d',
  getRemainingAllocations: '0x756f790c',
  getTotalBuybackPressure: '0x83183daf',
  getMarketCap: '0xfa8ebf58',
  countryCount: '0xde72edd7',
  initialized: '0x158ef93e',
  countryTokenImpl: '0xde157cbc',
  buybackExecutor: '0x8b4c5b4c',
  factoryWeth: '0xad5c4648',
  positionManager: '0x1bea83fe',
  pendingBuyback: '0xf3bb724a',
  totalETHBought: '0x72e1a09a',
  buybackCount: '0xa7640971',
  v2WethPair: '0xa45f23cd',
  authorizedSender: '0x30fd61ff',
  wci26: '0xd2974c5e',
  buybackWeth: '0xad5c4648',
  v2Router: '0x8ada032e',
  wci26FeeBps: '0x79ee3515',
  name: '0x06fdde03',
  symbol: '0x95d89b41',
  totalSupply: '0x18160ddd',
  balanceOf: '0x70a08231',
  getPool: '0x026b1d5f',
  slot0: '0x3850c7bd',
  liquidity: '0x1a686502',
};

const WCI_LIVE_EVENT_TOPICS = {
  Transfer: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
  PoolCreated: '0x3a6e28794518fe4f6e15c12339c708a4b11f2605884fff792e5253f6003811aa',
  BuybackReady: '0x3b346a313b12c2f3bd33f958368ea4b1c812d2b30ce92ab6cae9c15ea01fe7e4',
  EliminatedFeesReady: '0x637616d49e9b818ed9adff2c593c9c76d64d36e6868acf16af50cff1125404c9',
  FeesCollected: '0x995e7062bca13231ca8ed4d70088acd462b4596a1bfd9ecd7ab93f5bfeb601fc',
  VolumeRecorded: '0xc3bca8100aa866da98a46d62ab724db7e898583b80c7dad70b109ab509620c22',
  BuybackTriggered: '0x4c96fa12417395b937da70a29d3fe737ed4b34c447fd50c7f58114aa78717133',
  BuybackExecuted: '0x8e8412cac6b961b95ef832e2bac486977bbd29eb9725f9eddd97f3380c31f649',
  BuybackDeferred: '0xc855e04853c0ff308d42dfb52503057eea10cc9687857a34da277dfbcfeb41ca',
  CountryEliminated: '0xa94c2ebeb490c2b72cad40481e49a89e4e4fbb89cb4258b7bf2349c94a12065d',
  CountryReinstated: '0xeccae7fd90cb1d4678a8f2af770e67fc346bd1b9459b8119c2b5e2b0505fde51',
  WeeklyChampionCrowned: '0x958ba3d3e467e5914effb0040da165fea196d09d2f1104578638e28689fa8283',
  Swap: '0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67',
};

const WCI_LIVE_PENDING_LABEL = typeof WCI_DEPLOYMENT_PENDING !== 'undefined' ? WCI_DEPLOYMENT_PENDING : 'Pending deployment';
const WCI_LIVE_ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const WCI_LIVE_BLOCKS_PER_MINUTE = 5;
const WCI_LIVE_WEI = 1_000_000_000_000_000_000;
const WCI_LIVE_DEFAULT_INITIAL_MARKET_CAP_WETH = 16;
const WCI_LIVE_INT256_SIGN = 1n << 255n;
const WCI_LIVE_INT256_MOD = 1n << 256n;

const wciLiveCaps = () => (typeof WCI_CONTRACT_CONSTANTS !== 'undefined' ? WCI_CONTRACT_CONSTANTS.allocationCaps : {
  reserve: 200_000_000,
  airdrop: 150_000_000,
  treasury: 100_000_000,
  rewards: 50_000_000,
});

const wciAdapterCountryCodes = (config) => Object.keys(config.countries || {});
const wciLiveLower = (value) => String(value || '').toLowerCase();
const wciLiveWords = (hex) => String(hex || '0x').replace(/^0x/, '').match(/.{1,64}/g) || [];
const wciLiveBigInt = (value) => {
  try { return BigInt(value || 0); } catch { return 0n; }
};
const wciLiveWordUint = (word) => wciLiveBigInt(`0x${word || '0'}`);
const wciLiveWordInt = (word) => {
  const value = wciLiveWordUint(word);
  return value >= WCI_LIVE_INT256_SIGN ? value - WCI_LIVE_INT256_MOD : value;
};
const wciLiveWordBool = (word) => wciLiveWordUint(word) !== 0n;
const wciLiveWordAddress = (word) => (word ? `0x${word.slice(24)}` : WCI_LIVE_ZERO_ADDRESS);
const wciLiveFromWei = (wordOrValue) => Number(wciLiveBigInt(String(wordOrValue || '0x0'))) / WCI_LIVE_WEI;
const wciLiveSignedFromWei = (word) => Number(wciLiveWordInt(word || '0')) / WCI_LIVE_WEI;
const wciLiveTokenFromWei = (wordOrValue) => Number(wciLiveBigInt(String(wordOrValue || '0x0'))) / WCI_LIVE_WEI;
const wciLiveNumber = (wordOrValue) => Number(wciLiveBigInt(String(wordOrValue || '0x0')));
const wciLiveHexBlock = (number) => `0x${Math.max(0, Number(number || 0)).toString(16)}`;
const wciLiveFirstPositive = (...values) => {
  for (const value of values) {
    const numeric = Number(value);
    if (Number.isFinite(numeric) && numeric > 0) return numeric;
  }
  return 0;
};

const wciLiveBytes2Arg = (value) => {
  const text = String(value || '').toUpperCase().slice(0, 2);
  const encoded = text.split('').map((char) => char.charCodeAt(0).toString(16).padStart(2, '0')).join('');
  return encoded.padEnd(64, '0');
};

const wciLiveAddressArg = (value) => String(value || '').replace(/^0x/, '').toLowerCase().padStart(64, '0');

const wciLiveDecodeBytes2Topic = (topic) => {
  const bytes = String(topic || '').replace(/^0x/, '').slice(0, 4);
  if (bytes.length < 4) return '';
  return String.fromCharCode(parseInt(bytes.slice(0, 2), 16), parseInt(bytes.slice(2, 4), 16)).replace(/\0/g, '');
};

const wciLiveTopicAddress = (topic) => wciLiveWordAddress(String(topic || '').replace(/^0x/, '').padStart(64, '0'));

const wciLiveDecodeString = (hex) => {
  const words = wciLiveWords(hex);
  if (words.length < 2) return '';
  const offset = Number(wciLiveWordUint(words[0]) / 32n);
  const length = Number(wciLiveWordUint(words[offset]));
  const bytes = words.slice(offset + 1).join('').slice(0, length * 2);
  try {
    return decodeURIComponent(bytes.match(/.{1,2}/g).map((byte) => `%${byte}`).join(''));
  } catch {
    return '';
  }
};

const wciLiveCallData = (selector, args = []) => `${selector}${args.join('')}`;
const wciLiveEthCall = (key, to, selector, args = [], meta = {}) => ({
  key,
  to,
  data: wciLiveCallData(selector, args),
  meta,
});

const wciLiveRpcUrls = (config = {}) => [...new Set([
  ...(Array.isArray(config.rpcHttpUrls) ? config.rpcHttpUrls : []),
  config.rpcHttpUrl,
].filter(Boolean))];

const wciLiveRpc = async (rpcUrl, method, params) => {
  const response = await fetch(rpcUrl, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
  });
  if (!response.ok) throw new Error(`Sepolia RPC ${response.status} at ${rpcUrl}`);
  const payload = await response.json();
  if (payload.error) throw new Error(payload.error.message || 'Sepolia RPC error');
  return payload.result;
};

const wciLiveBatch = async (rpcUrl, calls, chunkSize = 80) => {
  const results = {};
  const valid = calls.filter((call) => call.to && call.data && WCI_LIVE_CONFIG.isAddress(call.to));
  for (let i = 0; i < valid.length; i += chunkSize) {
    const chunk = valid.slice(i, i + chunkSize);
    const body = chunk.map((call, index) => ({
      jsonrpc: '2.0',
      id: i + index + 1,
      method: 'eth_call',
      params: [{ to: call.to, data: call.data }, 'latest'],
    }));
    const response = await fetch(rpcUrl, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(body),
    });
    if (!response.ok) throw new Error(`Sepolia RPC ${response.status} at ${rpcUrl}`);
    const payload = await response.json();
    if (!Array.isArray(payload) && payload.error) throw new Error(payload.error.message || 'Sepolia batch RPC error');
    const rows = Array.isArray(payload) ? payload : [payload];
    chunk.forEach((call, index) => {
      const match = rows.find((row) => row.id === i + index + 1);
      results[call.key] = {
        ...call,
        result: match?.result || '0x',
        error: match?.error || null,
      };
    });
  }
  return results;
};

const wciLiveAllocationBucket = (totalTokens, remainingTokens, purpose) => {
  const remaining = Math.max(0, Number(remainingTokens || 0));
  const total = Number(totalTokens || 0);
  const distributed = Math.max(0, total - remaining);
  return {
    purpose,
    totalTokens: total,
    distributedTokens: distributed,
    remainingTokens: remaining,
    usedPct: total ? Math.max(0, Math.min(100, (distributed / total) * 100)) : 0,
    claimable: false,
    claimState: 'Owner allocation only',
  };
};

const wciLiveAllocations = (remaining = {}) => {
  const caps = wciLiveCaps();
  return {
    reserve: wciLiveAllocationBucket(caps.reserve, remaining.reserve ?? caps.reserve, 'Operational reserve'),
    airdrop: wciLiveAllocationBucket(caps.airdrop, remaining.airdrop ?? caps.airdrop, 'Community allocation'),
    treasury: wciLiveAllocationBucket(caps.treasury, remaining.treasury ?? caps.treasury, 'Operations allocation'),
    rewards: wciLiveAllocationBucket(caps.rewards, remaining.rewards ?? caps.rewards, 'Future rewards allocation'),
  };
};

const buildLiveBaseCountries = (config) => {
  const codes = typeof COUNTRY_GEO !== 'undefined' ? Object.keys(COUNTRY_GEO) : wciAdapterCountryCodes(config);
  return codes.filter((code) => config.countries?.[code]).map((code) => {
    const [lat = 0, lng = 0, color = '#F5D020', secondary = '#4ED1E6'] = typeof COUNTRY_GEO !== 'undefined'
      ? (COUNTRY_GEO[code] || [])
      : [];
    const tokenInfo = typeof getWciCountryTokenInfo === 'function'
      ? getWciCountryTokenInfo(code)
      : { name: code, countryName: code, ticker: `${code}26` };
    const deployment = config.countries?.[code] || {};
    return {
      code,
      isoCode: code,
      onchainIsoCode: deployment.onchainIsoCode,
      name: deployment.name || tokenInfo.name,
      countryName: tokenInfo.countryName,
      ticker: deployment.ticker || tokenInfo.ticker,
      symbol: deployment.ticker || tokenInfo.ticker,
      tokenSymbol: `$${deployment.ticker || tokenInfo.ticker}`,
      group: typeof teamGroup === 'function' ? teamGroup(code) : '?',
      lat,
      lng,
      color,
      secondary,
      price: 0,
      change24h: 0,
      volume24h: 0,
      holders: 0,
      mcap: 0,
      buys1m: 0,
      momentum: 0,
      rank: 0,
    };
  });
};

const decodeLiveCountryData = (hex) => {
  const words = wciLiveWords(hex);
  return {
    tokenAddress: wciLiveWordAddress(words[0]),
    lpTokenId: String(wciLiveWordUint(words[1])),
    totalFeesWETH: wciLiveFromWei(`0x${words[2] || '0'}`),
    totalVolumeWETH: wciLiveFromWei(`0x${words[3] || '0'}`),
    active: wciLiveWordBool(words[4]),
  };
};

const decodeLiveRemainingAllocations = (hex) => {
  const words = wciLiveWords(hex);
  return {
    reserve: wciLiveTokenFromWei(`0x${words[0] || '0'}`),
    airdrop: wciLiveTokenFromWei(`0x${words[1] || '0'}`),
    treasury: wciLiveTokenFromWei(`0x${words[2] || '0'}`),
    rewards: wciLiveTokenFromWei(`0x${words[3] || '0'}`),
  };
};

const wciLivePriceFromSlot0 = (slot0Hex, tokenAddress, wethAddress) => {
  const sqrtWord = wciLiveWords(slot0Hex)[0];
  const sqrt = Number(wciLiveWordUint(sqrtWord));
  if (!sqrt || !WCI_LIVE_CONFIG.isAddress(tokenAddress) || !WCI_LIVE_CONFIG.isAddress(wethAddress)) return 0;
  const ratio = sqrt / (2 ** 96);
  const raw = ratio * ratio;
  const tokenIsToken0 = wciLiveLower(tokenAddress) < wciLiveLower(wethAddress);
  return tokenIsToken0 ? raw : raw ? 1 / raw : 0;
};

const deriveLiveCountryChangePct = (country = {}, options = {}) => {
  const baseline = wciLiveFirstPositive(
    options.initialMarketCapWETH,
    options.initialCountryMarketCapWETH,
    country.initialMarketCapWETH,
    WCI_LIVE_DEFAULT_INITIAL_MARKET_CAP_WETH
  );
  const marketCapWETH = wciLiveFirstPositive(country.marketCapWETH, country.mcap);
  const priceWETH = wciLiveFirstPositive(country.priceWETH, country.price);
  const totalSupply = wciLiveFirstPositive(country.totalSupply, options.totalSupply, 1_000_000_000);
  const currentMarketCapWETH = marketCapWETH || (priceWETH * totalSupply);
  if (!baseline) return 0;
  const marketChange = currentMarketCapWETH
    ? ((currentMarketCapWETH - baseline) / baseline) * 100
    : 0;
  const activityVolumeWETH = wciLiveFirstPositive(
    country.recentBuyVolumeWETH,
    country.minuteBuyVolumeWETH,
    country.recentSwapVolumeWETH,
    country.totalVolumeWETH
  );
  const activityChange = activityVolumeWETH > 0 ? (activityVolumeWETH / baseline) * 100 : 0;
  return Number(Math.max(marketChange, activityChange, 0).toFixed(4));
};

const buildReadPlan = (config, isoCode) => {
  const code = String(isoCode || '').toUpperCase();
  const country = config.countries?.[code] || {};
  const contractIso = country.onchainIsoCode || code.slice(0, 2);
  return [
    { source: 'direct-rpc', contract: 'factory', address: config.factoryAddress, method: 'getCountry', args: [contractIso] },
    { source: 'direct-rpc', contract: 'factory', address: config.factoryAddress, method: 'pendingWETH', args: [contractIso] },
    { source: 'direct-rpc', contract: 'factory', address: config.factoryAddress, method: 'getRemainingAllocations', args: [contractIso] },
    { source: 'direct-rpc', contract: 'factory', address: config.factoryAddress, method: 'getMarketCap', args: [contractIso] },
    { source: 'direct-rpc', contract: 'factory', address: config.factoryAddress, method: 'getTotalBuybackPressure', args: [] },
    { source: 'direct-rpc', contract: 'buyback', address: config.buybackExecutorAddress, method: 'pendingBuyback', args: [] },
    { source: 'direct-rpc', contract: 'countryToken', address: country.tokenAddress, method: 'getPool', args: [] },
    { source: 'direct-rpc', contract: 'countryToken', address: country.tokenAddress, method: 'name', args: [] },
    { source: 'direct-rpc', contract: 'countryToken', address: country.tokenAddress, method: 'symbol', args: [] },
    { source: 'direct-rpc', contract: 'countryToken', address: country.tokenAddress, method: 'totalSupply', args: [] },
    { source: 'direct-rpc', contract: 'uniswapV3Pool', address: country.v3PoolAddress, method: 'slot0', args: [] },
    { source: 'direct-rpc', contract: 'uniswapV3Pool', address: country.v3PoolAddress, method: 'liquidity', args: [] },
    { source: 'direct-rpc', contract: 'countryToken', address: country.tokenAddress, method: 'poolTokenBalance', args: [country.v3PoolAddress] },
    { source: 'direct-rpc', contract: 'weth', address: config.wethAddress, method: 'poolWethBalance', args: [country.v3PoolAddress] },
  ];
};

const buildWatcherPlan = (config) => WCI_INDEXER_PLAN.eventSources.map((source) => ({
  ...source,
  abiKey: source.key,
  address: config[source.addressField] || null,
  startBlock: config.startBlock || null,
}));

const buildLiveCalls = (config) => {
  const calls = [
    wciLiveEthCall('factory.countryCount', config.factoryAddress, WCI_LIVE_SELECTORS.countryCount),
    wciLiveEthCall('factory.initialized', config.factoryAddress, WCI_LIVE_SELECTORS.initialized),
    wciLiveEthCall('factory.impl', config.factoryAddress, WCI_LIVE_SELECTORS.countryTokenImpl),
    wciLiveEthCall('factory.buybackExecutor', config.factoryAddress, WCI_LIVE_SELECTORS.buybackExecutor),
    wciLiveEthCall('factory.weth', config.factoryAddress, WCI_LIVE_SELECTORS.factoryWeth),
    wciLiveEthCall('factory.positionManager', config.factoryAddress, WCI_LIVE_SELECTORS.positionManager),
    wciLiveEthCall('factory.totalBuybackPressure', config.factoryAddress, WCI_LIVE_SELECTORS.getTotalBuybackPressure),
    wciLiveEthCall('buyback.pendingBuyback', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.pendingBuyback),
    wciLiveEthCall('buyback.totalETHBought', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.totalETHBought),
    wciLiveEthCall('buyback.buybackCount', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.buybackCount),
    wciLiveEthCall('buyback.v2WethPair', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.v2WethPair),
    wciLiveEthCall('buyback.authorizedSender', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.authorizedSender),
    wciLiveEthCall('buyback.wci26', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.wci26),
    wciLiveEthCall('buyback.weth', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.buybackWeth),
    wciLiveEthCall('buyback.router', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.v2Router),
    wciLiveEthCall('buyback.feeBps', config.buybackExecutorAddress, WCI_LIVE_SELECTORS.wci26FeeBps),
  ];

  wciAdapterCountryCodes(config).forEach((code) => {
    const country = config.countries[code];
    const isoArg = wciLiveBytes2Arg(country.onchainIsoCode);
    calls.push(wciLiveEthCall(`country.${code}.getCountry`, config.factoryAddress, WCI_LIVE_SELECTORS.getCountry, [isoArg], { code }));
    calls.push(wciLiveEthCall(`country.${code}.pendingWETH`, config.factoryAddress, WCI_LIVE_SELECTORS.pendingWETH, [isoArg], { code }));
    calls.push(wciLiveEthCall(`country.${code}.allocations`, config.factoryAddress, WCI_LIVE_SELECTORS.getRemainingAllocations, [isoArg], { code }));
    calls.push(wciLiveEthCall(`country.${code}.marketCap`, config.factoryAddress, WCI_LIVE_SELECTORS.getMarketCap, [isoArg], { code }));
    calls.push(wciLiveEthCall(`country.${code}.token.pool`, country.tokenAddress, WCI_LIVE_SELECTORS.getPool, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.token.name`, country.tokenAddress, WCI_LIVE_SELECTORS.name, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.token.symbol`, country.tokenAddress, WCI_LIVE_SELECTORS.symbol, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.token.totalSupply`, country.tokenAddress, WCI_LIVE_SELECTORS.totalSupply, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.pool.slot0`, country.v3PoolAddress, WCI_LIVE_SELECTORS.slot0, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.pool.liquidity`, country.v3PoolAddress, WCI_LIVE_SELECTORS.liquidity, [], { code }));
    calls.push(wciLiveEthCall(`country.${code}.pool.tokenBalance`, country.tokenAddress, WCI_LIVE_SELECTORS.balanceOf, [wciLiveAddressArg(country.v3PoolAddress)], { code }));
    calls.push(wciLiveEthCall(`country.${code}.pool.wethBalance`, config.wethAddress, WCI_LIVE_SELECTORS.balanceOf, [wciLiveAddressArg(country.v3PoolAddress)], { code }));
  });
  return calls;
};

const parseLiveEvents = (logs, config) => {
  const byContractIso = Object.fromEntries(wciAdapterCountryCodes(config).map((code) => [
    config.countries[code].onchainIsoCode,
    { code, ...config.countries[code] },
  ]));
  const byPoolAddress = Object.fromEntries(wciAdapterCountryCodes(config)
    .map((code) => {
      const country = config.countries[code];
      return [wciLiveLower(country.v3PoolAddress), { code, ...country }];
    })
    .filter(([address]) => WCI_LIVE_CONFIG.isAddress(address)));
  const topicToName = Object.fromEntries(Object.entries(WCI_LIVE_EVENT_TOPICS).map(([name, topic]) => [topic, name]));
  return [...(logs || [])].sort((a, b) => Number(b.blockNumber) - Number(a.blockNumber) || Number(b.logIndex) - Number(a.logIndex)).map((log) => {
    const type = topicToName[wciLiveLower(log.topics?.[0])] || topicToName[log.topics?.[0]] || 'ContractEvent';
    const poolDeployment = type === 'Swap' ? byPoolAddress[wciLiveLower(log.address)] : null;
    const contractIso = type === 'Swap'
      ? (poolDeployment?.onchainIsoCode || '')
      : wciLiveDecodeBytes2Topic(log.topics?.[1]);
    const deployment = poolDeployment || byContractIso[contractIso] || {};
    const words = wciLiveWords(log.data);
    const base = {
      id: `${log.transactionHash}-${log.logIndex}`,
      type,
      isoCode: deployment.code || null,
      onchainIsoCode: contractIso || null,
      countryName: deployment.name || 'WCI26',
      timestamp: Date.now(),
      blockNumber: Number(log.blockNumber),
      logIndex: Number(log.logIndex),
      txHash: log.transactionHash,
      simulated: false,
    };
    if (type === 'PoolCreated') {
      return {
        ...base,
        lpTokenId: String(wciLiveWordUint(words[0])),
        poolAddress: wciLiveWordAddress(words[1]),
        message: 'V3 pool created',
      };
    }
    if (type === 'Swap') {
      const amount0WETH = wciLiveSignedFromWei(words[0] || '0');
      const amount1WETH = wciLiveSignedFromWei(words[1] || '0');
      const tokenIsToken0 = wciLiveLower(deployment.tokenAddress) < wciLiveLower(config.wethAddress);
      const wethDelta = tokenIsToken0 ? amount1WETH : amount0WETH;
      const tokenDelta = tokenIsToken0 ? amount0WETH : amount1WETH;
      const isCountryBuy = wethDelta > 0 && tokenDelta < 0;
      return {
        ...base,
        poolAddress: log.address,
        sender: wciLiveWordAddress(String(log.topics?.[1] || '').replace(/^0x/, '')),
        recipient: wciLiveWordAddress(String(log.topics?.[2] || '').replace(/^0x/, '')),
        amount0WETH,
        amount1WETH,
        wethAmount: Math.abs(wethDelta),
        tokenAmount: Math.abs(tokenDelta),
        isCountryBuy,
        tradeSide: isCountryBuy ? 'buy' : 'sell',
        message: isCountryBuy ? 'Country token buy' : 'Country token swap',
      };
    }
    if (type === 'FeesCollected') return { ...base, wethAmount: wciLiveFromWei(`0x${words[0] || '0'}`) };
    if (type === 'VolumeRecorded') {
      return {
        ...base,
        wethVolume: wciLiveFromWei(`0x${words[0] || '0'}`),
        totalVolumeWETH: wciLiveFromWei(`0x${words[1] || '0'}`),
      };
    }
    if (type === 'BuybackReady' || type === 'EliminatedFeesReady') return { ...base, wethOwed: wciLiveFromWei(`0x${words[0] || '0'}`) };
    if (type === 'BuybackExecuted') {
      return {
        ...base,
        countryName: 'WCI26',
        wethAmount: wciLiveFromWei(`0x${words[0] || '0'}`),
        remaining: wciLiveFromWei(`0x${words[1] || '0'}`),
      };
    }
    return base;
  });
};

const wciLiveLatestEventBlock = (events = []) => (
  (events || []).reduce((max, event) => Math.max(max, Number(event?.blockNumber || 0)), 0)
);

const wciLiveWithinBlockWindow = (event, latestBlock, windowBlocks) => {
  const eventBlock = Number(event?.blockNumber || 0);
  const head = Number(latestBlock || 0);
  if (!eventBlock || !head) return false;
  return eventBlock <= head && (head - eventBlock) <= Number(windowBlocks || WCI_LIVE_BLOCKS_PER_MINUTE);
};

const summarizeLiveEventMetrics = (events = [], options = {}) => {
  const latestBlock = Number(options.latestBlock || options.blockNumber || 0) || wciLiveLatestEventBlock(events);
  const minuteWindowBlocks = Number(options.minuteWindowBlocks || WCI_LIVE_BLOCKS_PER_MINUTE);
  const summary = {};
  (events || []).forEach((event) => {
    if (!event?.isoCode) return;
    if (!summary[event.isoCode]) {
      summary[event.isoCode] = {
        recentSwapCount: 0,
        recentBuyCount: 0,
        recentSellCount: 0,
        recentSwapVolumeWETH: 0,
        recentBuyVolumeWETH: 0,
        recentSellVolumeWETH: 0,
        buysPerMinute: 0,
        minuteBuyVolumeWETH: 0,
        lastTradeBlockNumber: 0,
        lastTradeTxHash: null,
      };
    }
    const row = summary[event.isoCode];
    if (event.type === 'Swap') {
      const wethAmount = Number(event.wethAmount || 0);
      row.recentSwapCount += 1;
      row.recentSwapVolumeWETH += wethAmount;
      if (event.isCountryBuy) {
        row.recentBuyCount += 1;
        row.recentBuyVolumeWETH += wethAmount;
        if (wciLiveWithinBlockWindow(event, latestBlock, minuteWindowBlocks)) {
          row.buysPerMinute += 1;
          row.minuteBuyVolumeWETH += wethAmount;
        }
      } else {
        row.recentSellCount += 1;
        row.recentSellVolumeWETH += wethAmount;
      }
      if (Number(event.blockNumber || 0) >= Number(row.lastTradeBlockNumber || 0)) {
        row.lastTradeBlockNumber = Number(event.blockNumber || 0);
        row.lastTradeTxHash = event.txHash || row.lastTradeTxHash;
      }
    }
  });
  Object.values(summary).forEach((row) => {
    row.recentSwapVolumeWETH = Number(row.recentSwapVolumeWETH.toFixed(12));
    row.recentBuyVolumeWETH = Number(row.recentBuyVolumeWETH.toFixed(12));
    row.recentSellVolumeWETH = Number(row.recentSellVolumeWETH.toFixed(12));
    row.minuteBuyVolumeWETH = Number(row.minuteBuyVolumeWETH.toFixed(12));
  });
  return summary;
};

const isLiveCountryBuyEvent = (event = {}) => (
  event.type === 'Swap'
  && event.isCountryBuy === true
  && Number(event.wethAmount || 0) > 0
  && Boolean(event.isoCode)
);

const buildLiveTickerEvents = (events = [], config = {}, countryLookup = null) => (
  (Array.isArray(events) ? events : [])
    .filter(isLiveCountryBuyEvent)
    .sort((a, b) => Number(b.blockNumber || 0) - Number(a.blockNumber || 0) || Number(b.logIndex || 0) - Number(a.logIndex || 0))
    .map((event, index) => {
      const country = typeof countryLookup === 'function' ? countryLookup(event.isoCode) : null;
      const deployment = config.countries?.[event.isoCode] || {};
      const ticker = country?.ticker || deployment.ticker || event.isoCode;
      return {
        id: event.id || `${event.txHash || 'buy'}-${event.logIndex || index}`,
        code: country?.code || event.isoCode,
        name: country?.name || deployment.name || event.countryName,
        ticker,
        symbol: ticker,
        tokenSymbol: country?.tokenSymbol || `$${ticker}`,
        color: country?.color || 'var(--fifa-teal)',
        amount: Number(event.wethAmount || 0),
        amountLabel: `${Number(event.wethAmount || 0).toFixed(4)} WETH`,
        eventType: event.type,
        isCountryBuy: true,
        tradeSide: 'buy',
        txHash: event.txHash || null,
        blockNumber: Number(event.blockNumber || 0),
        logIndex: Number(event.logIndex || 0),
        ts: event.timestamp || Date.now(),
      };
    })
);

const summarizeLiveActivity = (events = [], options = {}) => {
  const countryBuys = (Array.isArray(events) ? events : [])
    .filter(isLiveCountryBuyEvent)
    .sort((a, b) => Number(b.blockNumber || 0) - Number(a.blockNumber || 0) || Number(b.logIndex || 0) - Number(a.logIndex || 0));
  const latestBlock = Number(options.latestBlock || options.blockNumber || 0) || wciLiveLatestEventBlock(countryBuys);
  const minuteWindowBlocks = Number(options.minuteWindowBlocks || WCI_LIVE_BLOCKS_PER_MINUTE);
  const minuteBuys = countryBuys.filter((event) => wciLiveWithinBlockWindow(event, latestBlock, minuteWindowBlocks));
  const recentBuyVolumeWETH = countryBuys.reduce((sum, event) => sum + Number(event.wethAmount || 0), 0);
  const minuteBuyVolumeWETH = minuteBuys.reduce((sum, event) => sum + Number(event.wethAmount || 0), 0);

  return {
    recentBuyCount: countryBuys.length,
    buysPerMinute: minuteBuys.length,
    recentBuyVolumeWETH: Number(recentBuyVolumeWETH.toFixed(12)),
    minuteBuyVolumeWETH: Number(minuteBuyVolumeWETH.toFixed(12)),
    latestBuy: countryBuys[0] || null,
    latestBlock,
    minuteWindowBlocks,
  };
};

const mergeLiveEvents = (current = [], incoming = [], limit = 500) => {
  const byId = new Map();
  [...(current || []), ...(incoming || [])].forEach((event) => {
    if (!event) return;
    byId.set(event.id || `${event.txHash || 'event'}-${event.logIndex || 0}`, event);
  });
  return [...byId.values()]
    .sort((a, b) => Number(b.blockNumber || 0) - Number(a.blockNumber || 0) || Number(b.logIndex || 0) - Number(a.logIndex || 0))
    .slice(0, limit);
};

const summarizeLiveHolderCounts = (logs = [], config = {}) => {
  const byTokenAddress = Object.fromEntries(wciAdapterCountryCodes(config)
    .map((code) => {
      const country = config.countries?.[code] || {};
      return [wciLiveLower(country.tokenAddress), code];
    })
    .filter(([address]) => WCI_LIVE_CONFIG.isAddress(address)));
  const zero = wciLiveLower(WCI_LIVE_ZERO_ADDRESS);
  const balances = {};
  const transferCounts = {};
  (logs || []).forEach((log) => {
    if (wciLiveLower(log.topics?.[0]) !== WCI_LIVE_EVENT_TOPICS.Transfer) return;
    const code = byTokenAddress[wciLiveLower(log.address)];
    if (!code) return;
    const value = wciLiveWordUint(wciLiveWords(log.data)[0] || '0');
    if (value <= 0n) return;
    const from = wciLiveLower(wciLiveTopicAddress(log.topics?.[1]));
    const to = wciLiveLower(wciLiveTopicAddress(log.topics?.[2]));
    if (!balances[code]) balances[code] = new Map();
    const book = balances[code];
    if (from && from !== zero) book.set(from, (book.get(from) || 0n) - value);
    if (to && to !== zero) book.set(to, (book.get(to) || 0n) + value);
    transferCounts[code] = (transferCounts[code] || 0) + 1;
  });
  return Object.fromEntries(Object.entries(balances).map(([code, book]) => {
    let holders = 0;
    book.forEach((balance) => {
      if (balance > 0n) holders += 1;
    });
    return [code, {
      holders,
      indexedTransfers: transferCounts[code] || 0,
      holderDataState: 'transfer-log-indexed',
    }];
  }));
};

const applyEventMetricsToSnapshot = (snapshot, events) => {
  const eventMetrics = summarizeLiveEventMetrics(events || [], { latestBlock: snapshot.global?.blockNumber });
  const countries = { ...(snapshot.countries || {}) };
  Object.entries(eventMetrics).forEach(([code, metrics]) => {
    countries[code] = {
      ...(countries[code] || {}),
      recentSwapCount: metrics.recentSwapCount || 0,
      recentBuyCount: metrics.recentBuyCount || 0,
      recentSellCount: metrics.recentSellCount || 0,
      recentSwapVolumeWETH: metrics.recentSwapVolumeWETH || 0,
      recentBuyVolumeWETH: metrics.recentBuyVolumeWETH || 0,
      recentSellVolumeWETH: metrics.recentSellVolumeWETH || 0,
      buysPerMinute: metrics.buysPerMinute || 0,
      minuteBuyVolumeWETH: metrics.minuteBuyVolumeWETH || 0,
      lastTradeBlockNumber: metrics.lastTradeBlockNumber || 0,
      lastTradeTxHash: metrics.lastTradeTxHash || null,
    };
  });
  return { ...snapshot, countries, events };
};

const fetchRecentLiveEvents = async (config, latestBlock, options = {}) => {
  if (!config.rpcHttpUrl || !WCI_LIVE_CONFIG.isAddress(config.factoryAddress)) return [];
  const lookbackBlocks = Number(options.lookbackBlocks || config.eventLookbackBlocks || 50_000);
  const fromBlock = Math.max(
    Number(config.startBlock || 0),
    Number(options.fromBlock || 0) || Number(latestBlock || 0) - lookbackBlocks,
  );
  const poolFromBlock = Math.max(
    Number(config.poolStartBlock || config.startBlock || 0),
    Number(options.poolFromBlock || options.fromBlock || 0) || Number(latestBlock || 0) - lookbackBlocks,
  );
  const factoryTopics = [
    WCI_LIVE_EVENT_TOPICS.PoolCreated,
    WCI_LIVE_EVENT_TOPICS.BuybackReady,
    WCI_LIVE_EVENT_TOPICS.EliminatedFeesReady,
    WCI_LIVE_EVENT_TOPICS.FeesCollected,
    WCI_LIVE_EVENT_TOPICS.VolumeRecorded,
    WCI_LIVE_EVENT_TOPICS.CountryEliminated,
    WCI_LIVE_EVENT_TOPICS.CountryReinstated,
    WCI_LIVE_EVENT_TOPICS.WeeklyChampionCrowned,
  ];
  const buybackTopics = [WCI_LIVE_EVENT_TOPICS.BuybackExecuted, WCI_LIVE_EVENT_TOPICS.BuybackDeferred];
  const poolAddressChunks = [];
  const poolAddresses = wciAdapterCountryCodes(config)
    .map((code) => config.countries[code]?.v3PoolAddress)
    .filter((address) => WCI_LIVE_CONFIG.isAddress(address));
  for (let i = 0; i < poolAddresses.length; i += 12) {
    poolAddressChunks.push(poolAddresses.slice(i, i + 12));
  }
  const [factoryLogs, buybackLogs, poolLogsNested] = await Promise.all([
    wciLiveRpc(config.rpcHttpUrl, 'eth_getLogs', [{
      address: config.factoryAddress,
      fromBlock: wciLiveHexBlock(fromBlock),
      toBlock: 'latest',
      topics: [factoryTopics],
    }]).catch(() => []),
    wciLiveRpc(config.rpcHttpUrl, 'eth_getLogs', [{
      address: config.buybackExecutorAddress,
      fromBlock: wciLiveHexBlock(fromBlock),
      toBlock: 'latest',
      topics: [buybackTopics],
    }]).catch(() => []),
    Promise.all(poolAddressChunks.map((addresses) => wciLiveRpc(config.rpcHttpUrl, 'eth_getLogs', [{
      address: addresses,
      fromBlock: wciLiveHexBlock(poolFromBlock),
      toBlock: 'latest',
      topics: [WCI_LIVE_EVENT_TOPICS.Swap],
    }]).catch(() => []))).catch(() => []),
  ]);
  const poolLogs = (poolLogsNested || []).flat();
  return parseLiveEvents([...(factoryLogs || []), ...(buybackLogs || []), ...poolLogs], config).slice(0, options.limit || 500);
};

const fetchLiveHolderCounts = async (config, latestBlock, options = {}) => {
  if (!config.rpcHttpUrl) return {};
  const tokenAddresses = wciAdapterCountryCodes(config)
    .map((code) => config.countries[code]?.tokenAddress)
    .filter((address) => WCI_LIVE_CONFIG.isAddress(address));
  const tokenAddressChunks = [];
  for (let i = 0; i < tokenAddresses.length; i += 12) {
    tokenAddressChunks.push(tokenAddresses.slice(i, i + 12));
  }
  const lookbackBlocks = Number(options.lookbackBlocks || config.holderLookbackBlocks || 0);
  const fromBlock = Math.max(
    Number(config.startBlock || 0),
    Number(options.fromBlock || 0) || (lookbackBlocks ? Number(latestBlock || 0) - lookbackBlocks : 0),
  );
  const logsNested = await Promise.all(tokenAddressChunks.map((addresses) => wciLiveRpc(config.rpcHttpUrl, 'eth_getLogs', [{
    address: addresses,
    fromBlock: wciLiveHexBlock(fromBlock),
    toBlock: 'latest',
    topics: [WCI_LIVE_EVENT_TOPICS.Transfer],
  }]).catch(() => []))).catch(() => []);
  return summarizeLiveHolderCounts((logsNested || []).flat(), config);
};

const buildSnapshotFromResults = (config, readiness, chainIdHex, latestBlockHex, results, events, holderSummaries = {}) => {
  const latestBlock = wciLiveNumber(latestBlockHex);
  const eventMetrics = summarizeLiveEventMetrics(events || [], { latestBlock });
  const factoryWeth = wciLiveWordAddress(wciLiveWords(results['factory.weth']?.result)[0]) || config.wethAddress;
  const global = {
    chainId: parseInt(String(chainIdHex || '0x0'), 16),
    blockNumber: latestBlock,
    countryCount: wciLiveNumber(`0x${wciLiveWords(results['factory.countryCount']?.result)[0] || '0'}`),
    initialized: wciLiveWordBool(wciLiveWords(results['factory.initialized']?.result)[0]),
    countryTokenImplementationAddress: wciLiveWordAddress(wciLiveWords(results['factory.impl']?.result)[0]),
    buybackExecutorAddress: wciLiveWordAddress(wciLiveWords(results['factory.buybackExecutor']?.result)[0]),
    factoryWethAddress: factoryWeth,
    positionManagerAddress: wciLiveWordAddress(wciLiveWords(results['factory.positionManager']?.result)[0]),
    totalBuybackPressureWETH: wciLiveFromWei(`0x${wciLiveWords(results['factory.totalBuybackPressure']?.result)[0] || '0'}`),
    executorPendingETH: wciLiveFromWei(`0x${wciLiveWords(results['buyback.pendingBuyback']?.result)[0] || '0'}`),
    totalETHBought: wciLiveFromWei(`0x${wciLiveWords(results['buyback.totalETHBought']?.result)[0] || '0'}`),
    buybackCount: wciLiveNumber(`0x${wciLiveWords(results['buyback.buybackCount']?.result)[0] || '0'}`),
    v2WethPair: wciLiveWordAddress(wciLiveWords(results['buyback.v2WethPair']?.result)[0]),
    authorizedSender: wciLiveWordAddress(wciLiveWords(results['buyback.authorizedSender']?.result)[0]),
    wci26Address: wciLiveWordAddress(wciLiveWords(results['buyback.wci26']?.result)[0]),
    buybackWethAddress: wciLiveWordAddress(wciLiveWords(results['buyback.weth']?.result)[0]),
    v2RouterAddress: wciLiveWordAddress(wciLiveWords(results['buyback.router']?.result)[0]),
    wci26FeeBps: wciLiveNumber(`0x${wciLiveWords(results['buyback.feeBps']?.result)[0] || '0'}`),
  };
  const countries = {};
  wciAdapterCountryCodes(config).forEach((code) => {
    const deployment = config.countries[code];
    const liveEvents = eventMetrics[code] || {};
    const liveHolders = holderSummaries[code] || {};
    const countryData = decodeLiveCountryData(results[`country.${code}.getCountry`]?.result || '0x');
    const hasFactoryCountryData = WCI_LIVE_CONFIG.isAddress(countryData.tokenAddress)
      && countryData.tokenAddress !== WCI_LIVE_ZERO_ADDRESS;
    const poolFromToken = wciLiveWordAddress(wciLiveWords(results[`country.${code}.token.pool`]?.result)[0]);
    const poolAddress = WCI_LIVE_CONFIG.isAddress(poolFromToken) && poolFromToken !== WCI_LIVE_ZERO_ADDRESS
      ? poolFromToken
      : deployment.v3PoolAddress;
    const priceWETH = wciLivePriceFromSlot0(results[`country.${code}.pool.slot0`]?.result || '0x', deployment.tokenAddress, factoryWeth);
    const marketCapRaw = wciLiveNumber(`0x${wciLiveWords(results[`country.${code}.marketCap`]?.result)[0] || '0'}`);
    const marketCapWETH = marketCapRaw || (priceWETH * 1_000_000_000);
    countries[code] = {
      tokenAddress: deployment.tokenAddress || (hasFactoryCountryData ? countryData.tokenAddress : WCI_LIVE_ZERO_ADDRESS),
      contractTokenAddress: hasFactoryCountryData ? countryData.tokenAddress : null,
      lpTokenId: hasFactoryCountryData ? countryData.lpTokenId : deployment.lpTokenId,
      totalFeesWETH: hasFactoryCountryData ? countryData.totalFeesWETH : 0,
      totalVolumeWETH: hasFactoryCountryData ? countryData.totalVolumeWETH : 0,
      active: hasFactoryCountryData ? countryData.active : true,
      onchainIsoCode: deployment.onchainIsoCode,
      name: wciLiveDecodeString(results[`country.${code}.token.name`]?.result) || deployment.name,
      symbol: wciLiveDecodeString(results[`country.${code}.token.symbol`]?.result) || deployment.ticker,
      totalSupply: wciLiveTokenFromWei(`0x${wciLiveWords(results[`country.${code}.token.totalSupply`]?.result)[0] || '0'}`),
      poolAddress,
      configuredPoolAddress: deployment.v3PoolAddress,
      pendingWETH: wciLiveFromWei(`0x${wciLiveWords(results[`country.${code}.pendingWETH`]?.result)[0] || '0'}`),
      remainingAllocations: decodeLiveRemainingAllocations(results[`country.${code}.allocations`]?.result || '0x'),
      marketCapWETH,
      priceWETH: marketCapWETH ? marketCapWETH / 1_000_000_000 : priceWETH,
      poolLiquidity: wciLiveNumber(`0x${wciLiveWords(results[`country.${code}.pool.liquidity`]?.result)[0] || '0'}`),
      poolTokenBalance: wciLiveTokenFromWei(`0x${wciLiveWords(results[`country.${code}.pool.tokenBalance`]?.result)[0] || '0'}`),
      poolWethBalance: wciLiveFromWei(`0x${wciLiveWords(results[`country.${code}.pool.wethBalance`]?.result)[0] || '0'}`),
      recentSwapCount: liveEvents.recentSwapCount || 0,
      recentBuyCount: liveEvents.recentBuyCount || 0,
      recentSellCount: liveEvents.recentSellCount || 0,
      recentSwapVolumeWETH: liveEvents.recentSwapVolumeWETH || 0,
      recentBuyVolumeWETH: liveEvents.recentBuyVolumeWETH || 0,
      recentSellVolumeWETH: liveEvents.recentSellVolumeWETH || 0,
      buysPerMinute: liveEvents.buysPerMinute || 0,
      minuteBuyVolumeWETH: liveEvents.minuteBuyVolumeWETH || 0,
      lastTradeBlockNumber: liveEvents.lastTradeBlockNumber || 0,
      lastTradeTxHash: liveEvents.lastTradeTxHash || null,
      holders: Number(liveHolders.holders || 0),
      indexedTransfers: Number(liveHolders.indexedTransfers || 0),
      holderDataState: liveHolders.holderDataState || 'transfer-log-pending',
      dataState: 'sepolia-live',
      factoryCountryReadState: hasFactoryCountryData ? 'live' : 'deployment-fallback',
    };
  });
  return {
    config,
    readiness,
    dataState: 'sepolia-live',
    lastRefreshAt: Date.now(),
    lastError: null,
    global,
    countries,
    events: events || [],
  };
};

const makeEmptySnapshot = (config, readiness) => ({
  config,
  readiness,
  dataState: readiness.mode === 'live-ready' ? 'sepolia-live-loading' : readiness.mode,
  lastRefreshAt: null,
  lastError: null,
  global: {
    chainId: config.chainId,
    blockNumber: null,
    countryCount: 0,
    initialized: false,
    totalBuybackPressureWETH: 0,
    executorPendingETH: 0,
    totalETHBought: 0,
    buybackCount: 0,
    activeCountries: 0,
    eliminatedCountries: 0,
  },
  countries: {},
  events: [],
});

const makeLiveAdapter = (configInput = {}) => {
  const config = WCI_LIVE_CONFIG.mergeConfig(configInput);
  const readiness = WCI_LIVE_CONFIG.validateConfig(config);
  let snapshot = makeEmptySnapshot(config, readiness);
  const listeners = new Set();
  let refreshPromise = null;
  let refreshEventsPromise = null;

  const notify = () => listeners.forEach((listener) => {
    try { listener(snapshot); } catch {}
  });

  const decorateCountries = () => {
    const rows = buildLiveBaseCountries(config).map((country) => {
      const deployment = config.countries?.[country.code] || {};
      const status = readiness.countryStatus?.[country.code] || { ready: false, missing: [] };
      const live = snapshot.countries?.[country.code] || {};
      const totalFeesWETH = Number(live.totalFeesWETH || 0);
      const contractVolumeWETH = Number(live.totalVolumeWETH || 0);
      const recentSwapVolumeWETH = Number(live.recentSwapVolumeWETH || 0);
      const totalVolumeWETH = contractVolumeWETH || recentSwapVolumeWETH;
      const pendingWETH = Number(live.pendingWETH || 0);
      const buybackThresholdWETH = 0.1;
      const buybackProgressPct = Math.max(0, Math.min(100, (pendingWETH / buybackThresholdWETH) * 100));
      const active = live.active !== undefined ? live.active : true;
      const allocation = wciLiveAllocations(live.remainingAllocations);
      const marketCapWETH = Number(live.marketCapWETH || 0);
      const priceWETH = Number(live.priceWETH || 0);
      const totalSupply = Number(live.totalSupply || 1_000_000_000);
      const initialMarketCapWETH = wciLiveFirstPositive(
        deployment.initialMarketCapWETH,
        config.initialCountryMarketCapWETH,
        WCI_LIVE_DEFAULT_INITIAL_MARKET_CAP_WETH
      );
      const change24h = deriveLiveCountryChangePct(
        {
          marketCapWETH,
          priceWETH,
          totalSupply,
          initialMarketCapWETH,
          recentBuyVolumeWETH: Number(live.recentBuyVolumeWETH || 0),
          recentSwapVolumeWETH,
          totalVolumeWETH,
        },
        { initialMarketCapWETH }
      );
      return {
        ...country,
        name: live.name || deployment.name || country.name,
        ticker: live.symbol || deployment.ticker || country.ticker,
        symbol: live.symbol || deployment.ticker || country.symbol,
        tokenSymbol: `$${live.symbol || deployment.ticker || country.symbol}`,
        tokenAddress: deployment.tokenAddress || live.tokenAddress || WCI_LIVE_PENDING_LABEL,
        contractTokenAddress: live.contractTokenAddress || null,
        poolAddress: live.poolAddress || deployment.v3PoolAddress || WCI_LIVE_PENDING_LABEL,
        lpTokenId: live.lpTokenId || deployment.lpTokenId || WCI_LIVE_PENDING_LABEL,
        poolFeeTier: deployment.poolFeeTier || 10000,
        deploymentBlock: deployment.deploymentBlock,
        onchainIsoCode: deployment.onchainIsoCode,
        active,
        totalFeesWETH,
        totalVolumeWETH,
        contractVolumeWETH,
        recentSwapCount: Number(live.recentSwapCount || 0),
        recentBuyCount: Number(live.recentBuyCount || 0),
        recentSellCount: Number(live.recentSellCount || 0),
        recentSwapVolumeWETH,
        recentBuyVolumeWETH: Number(live.recentBuyVolumeWETH || 0),
        recentSellVolumeWETH: Number(live.recentSellVolumeWETH || 0),
        buysPerMinute: Number(live.buysPerMinute || 0),
        minuteBuyVolumeWETH: Number(live.minuteBuyVolumeWETH || 0),
        lastTradeBlockNumber: Number(live.lastTradeBlockNumber || 0),
        lastTradeTxHash: live.lastTradeTxHash || null,
        volume24h: recentSwapVolumeWETH,
        pendingWETH,
        price: priceWETH,
        priceWETH,
        change24h,
        changeBasis: 'live-market-cap-vs-launch',
        holders: Number(live.holders || 0),
        indexedTransfers: Number(live.indexedTransfers || 0),
        holderDataState: live.holderDataState || 'transfer-log-pending',
        mcap: marketCapWETH,
        marketCapWETH,
        buys1m: Number(live.buysPerMinute || 0),
        momentum: totalVolumeWETH || pendingWETH ? Math.min(1.2, Math.max(0.1, totalVolumeWETH / 100 || pendingWETH)) : 0.1,
        totalSupply,
        initialMarketCapWETH,
        poolLiquidity: live.poolLiquidity || 0,
        poolTokenBalance: live.poolTokenBalance || 0,
        poolWethBalance: live.poolWethBalance || 0,
        lastCollectionAt: null,
        cooldownReady: true,
        buybackThresholdWETH,
        buybackProgressPct,
        buybackReady: pendingWETH >= buybackThresholdWETH,
        minTriggerWETH: 0.01,
        weeklyFeesDeltaWETH: 0,
        weeklyFeesBaselineWETH: totalFeesWETH,
        nationalPower: Math.round(totalVolumeWETH * 100 + totalFeesWETH * 120 + pendingWETH * 1200 + (active ? 25 : 0)),
        allocation,
        dashboardDataState: live.dataState || snapshot.dataState,
        liveDataState: live.dataState || snapshot.dataState,
        liveDeployment: {
          ...deployment,
          ready: status.ready,
          missing: status.missing || [],
        },
        liveDataGaps: ['Browser volume is recent pool-log volume; true 24h windows need an indexer', 'USD price needs an oracle or pricing backend'],
        contractLoopLabel: 'Sepolia country activity -> V3 swaps -> WCI26 strength',
      };
    });
    rows.sort((a, b) => (
      (b.totalVolumeWETH - a.totalVolumeWETH)
      || (b.pendingWETH - a.pendingWETH)
      || (b.marketCapWETH - a.marketCapWETH)
      || a.code.localeCompare(b.code)
    ));
    rows.forEach((country, index) => { country.rank = index + 1; });
    return rows;
  };

  const adapter = {
    config,
    getReadiness: () => readiness,
    getSnapshot: () => snapshot,
    getDataState: () => ({
      mode: readiness.mode,
      dataState: snapshot.dataState,
      lastRefreshAt: snapshot.lastRefreshAt,
      lastError: snapshot.lastError,
      blockNumber: snapshot.global?.blockNumber || null,
    }),
    subscribe: (listener) => {
      listeners.add(listener);
      return () => listeners.delete(listener);
    },
    refresh: async () => {
      if (refreshPromise) return refreshPromise;
      refreshPromise = (async () => {
        const rpcUrls = wciLiveRpcUrls(config);
        if (!rpcUrls.length || readiness.mode !== 'live-ready') {
          snapshot = { ...snapshot, dataState: readiness.mode, lastError: 'Sepolia live config is incomplete' };
          notify();
          return snapshot;
        }
        let lastError = null;
        for (const rpcUrl of rpcUrls) {
          try {
            const liveConfig = { ...config, rpcHttpUrl: rpcUrl };
            const [chainIdHex, latestBlockHex] = await Promise.all([
              wciLiveRpc(rpcUrl, 'eth_chainId', []),
              wciLiveRpc(rpcUrl, 'eth_blockNumber', []),
            ]);
            const results = await wciLiveBatch(rpcUrl, buildLiveCalls(liveConfig));
            const latestBlock = wciLiveNumber(latestBlockHex);
            const [events, holderSummaries] = await Promise.all([
              fetchRecentLiveEvents(liveConfig, latestBlock),
              fetchLiveHolderCounts(liveConfig, latestBlock),
            ]);
            snapshot = buildSnapshotFromResults(liveConfig, readiness, chainIdHex, latestBlockHex, results, events, holderSummaries);
            notify();
            return snapshot;
          } catch (error) {
            lastError = error;
          }
        }
        if (lastError) {
          snapshot = {
            ...snapshot,
            dataState: 'sepolia-live-error',
            lastError: lastError?.message || String(lastError),
            lastRefreshAt: Date.now(),
          };
          notify();
          return snapshot;
        }
        return snapshot;
      })().finally(() => {
          refreshPromise = null;
      });
      return refreshPromise;
    },
    refreshEvents: async () => {
      if (refreshEventsPromise) return refreshEventsPromise;
      refreshEventsPromise = (async () => {
        const rpcUrls = wciLiveRpcUrls(config);
        if (!rpcUrls.length || readiness.mode !== 'live-ready') return snapshot;
        let lastError = null;
        for (const rpcUrl of rpcUrls) {
          try {
            const liveConfig = { ...config, rpcHttpUrl: rpcUrl };
            const latestBlockHex = await wciLiveRpc(rpcUrl, 'eth_blockNumber', []);
            const latestBlock = wciLiveNumber(latestBlockHex);
            const previousBlock = Number(snapshot.global?.blockNumber || 0);
            const fromBlock = previousBlock
              ? Math.max(Number(config.poolStartBlock || config.startBlock || 0), previousBlock - 12)
              : Math.max(Number(config.poolStartBlock || config.startBlock || 0), latestBlock - 5_000);
            const events = await fetchRecentLiveEvents(liveConfig, latestBlock, {
              fromBlock,
              poolFromBlock: fromBlock,
              limit: 240,
            });
            const mergedEvents = mergeLiveEvents(snapshot.events || [], events, 500);
            snapshot = applyEventMetricsToSnapshot({
              ...snapshot,
              dataState: 'sepolia-live',
              lastRefreshAt: Date.now(),
              lastError: null,
              global: {
                ...snapshot.global,
                blockNumber: latestBlock,
              },
            }, mergedEvents);
            notify();
            return snapshot;
          } catch (error) {
            lastError = error;
          }
        }
        if (lastError) {
          snapshot = {
            ...snapshot,
            dataState: snapshot.dataState || 'sepolia-live-error',
            lastError: lastError?.message || String(lastError),
            lastRefreshAt: Date.now(),
          };
          notify();
        }
        return snapshot;
      })().finally(() => {
        refreshEventsPromise = null;
      });
      return refreshEventsPromise;
    },
    getCountries: () => decorateCountries(),
    getCountry: (isoCode) => adapter.getCountries()
      .find((country) => country.isoCode === String(isoCode || '').toUpperCase() || country.code === String(isoCode || '').toUpperCase()) || null,
    getLeaderboard: (mode = 'nationalPower') => {
      const scoreFor = (country) => {
        if (mode === 'fees') return country.totalFeesWETH;
        if (mode === 'volume') return country.totalVolumeWETH;
        if (mode === 'pendingBuyback') return country.pendingWETH;
        if (mode === 'weeklyMomentum') return country.weeklyFeesDeltaWETH;
        if (mode === 'rewards') return country.allocation?.rewards?.remainingTokens || 0;
        return country.nationalPower;
      };
      return [...adapter.getCountries()]
        .sort((a, b) => scoreFor(b) - scoreFor(a) || a.rank - b.rank)
        .map((country, index) => ({ ...country, rankByMode: index + 1, leaderboardMode: mode, leaderboardScore: scoreFor(country) }));
    },
    getGlobalBuybackPressure: () => {
      const countries = adapter.getCountries();
      const activeCountries = countries.filter((country) => country.active !== false).length;
      const pendingWETH = Number(snapshot.global.totalBuybackPressureWETH || countries.reduce((sum, country) => sum + (country.pendingWETH || 0), 0));
      return {
        pendingWETH,
        buybackReadyCount: countries.filter((country) => country.buybackReady).length,
        activeCountries,
        eliminatedCountries: countries.length - activeCountries,
        executorPendingETH: Number(snapshot.global.executorPendingETH || 0),
        totalETHBought: Number(snapshot.global.totalETHBought || 0),
        buybackCount: Number(snapshot.global.buybackCount || 0),
        thresholdWETH: 0.1,
        dataState: snapshot.dataState,
        blockNumber: snapshot.global.blockNumber,
      };
    },
    getBuybackPoolValue: () => Number(snapshot.global.totalBuybackPressureWETH || snapshot.global.executorPendingETH || 0),
    getCountryBuybackState: (isoCode) => {
      const country = adapter.getCountry(isoCode);
      if (!country) return null;
      return {
        isoCode: country.isoCode,
        name: country.name,
        pendingWETH: country.pendingWETH,
        thresholdWETH: country.buybackThresholdWETH,
        minTriggerWETH: country.minTriggerWETH,
        progressPct: country.buybackProgressPct,
        buybackReady: country.buybackReady,
        cooldownReady: country.cooldownReady,
        lastCollectionAt: country.lastCollectionAt,
        stateLabel: country.buybackReady ? 'Buy flow active' : 'Accumulating activity',
      };
    },
    getRewardAllocations: (isoCode) => adapter.getCountry(isoCode)?.allocation || null,
    getRecentEvents: () => {
      if (snapshot.events?.length) return snapshot.events;
      return [{
        id: 'sepolia-sync-pending',
        type: snapshot.lastError ? 'SepoliaRpcError' : 'SepoliaSync',
        isoCode: null,
        countryName: 'WCI26',
        timestamp: snapshot.lastRefreshAt || Date.now(),
        message: snapshot.lastError || 'Sync pending',
        simulated: false,
      }];
    },
    getTickerEvents: () => {
      const buys = buildLiveTickerEvents(adapter.getRecentEvents(), config, (isoCode) => adapter.getCountry(isoCode)).slice(0, 24);
      if (buys.length) return buys;
      return [{
        id: 'country-buys-pending',
        code: null,
        name: 'Country buys',
        ticker: 'BUYS',
        tokenSymbol: '$WCI26',
        color: 'var(--fifa-teal)',
        amount: 0,
        amountLabel: snapshot.lastError ? 'Buy feed retrying' : 'No country buys indexed yet',
        eventType: 'RecentBuyPending',
        isCountryBuy: false,
        tradeSide: null,
        txHash: null,
        ts: snapshot.lastRefreshAt || Date.now(),
      }];
    },
    getLiveActivitySummary: () => summarizeLiveActivity(snapshot.events || [], { latestBlock: snapshot.global?.blockNumber }),
    getSeasonSnapshot: () => {
      const leaderboard = adapter.getLeaderboard('fees');
      const champion = leaderboard[0] || null;
      return {
        snapshotAt: snapshot.lastRefreshAt || Date.now(),
        baselineAt: null,
        weeklyChampion: champion ? { ...champion, basedOn: 'live all-time fees until weekly indexer is connected', rewardBps: 0, rewardState: 'Cosmetic only until reward mechanism exists' } : null,
        weeklyMomentum: leaderboard.map((country) => ({ ...country, weeklyFeesDeltaWETH: 0 })),
        championHistory: [],
      };
    },
    getTournamentState: () => {
      const countries = adapter.getCountries();
      const activeCountries = countries.filter((country) => country.active !== false);
      const eliminatedCountries = countries.filter((country) => country.active === false);
      const groupLeaders = Object.values(countries.reduce((acc, country) => {
        if (!acc[country.group] || country.nationalPower > acc[country.group].nationalPower) acc[country.group] = country;
        return acc;
      }, {}));
      const groupStageResults = adapter.getRecentEvents()
        .filter((event) => event.type === 'GroupStageResult')
        .map((event, index) => ({ matchId: index + 1, winner: event.isoCode, loser: null, timestamp: event.timestamp, simulated: false }));
      return {
        activeCount: activeCountries.length,
        eliminatedCount: eliminatedCountries.length,
        activeCountries: activeCountries.map((country) => country.isoCode),
        eliminatedCountries: eliminatedCountries.map((country) => country.isoCode),
        groupLeaders,
        groupStageResults,
      };
    },
    buildReadPlan: (isoCode) => buildReadPlan(config, isoCode),
    buildWatcherPlan: () => buildWatcherPlan(config),
    getIndexerPlan: () => WCI_INDEXER_PLAN,
    getModeLabel: () => {
      if (readiness.mode === 'live-ready') return snapshot.dataState === 'sepolia-live' ? 'Sepolia live' : 'Sepolia ready';
      if (readiness.mode === 'partial-live-ready') return 'Partial live ready';
      return 'Addresses pending';
    },
    withConfig: (nextConfig) => makeLiveAdapter(nextConfig),
  };

  return adapter;
};

const WCI_LIVE_ADAPTER = makeLiveAdapter(
  typeof WCI_LIVE_CONFIG !== 'undefined' ? WCI_LIVE_CONFIG.loadConfig() : {}
);

Object.assign(window, {
  WCI_INDEXER_PLAN,
  WCI_LIVE_SELECTORS,
  WCI_LIVE_EVENT_TOPICS,
  WCI_LIVE_TESTING: {
    parseLiveEvents,
    summarizeLiveEventMetrics,
    summarizeLiveHolderCounts,
    summarizeLiveActivity,
    deriveLiveCountryChangePct,
    buildLiveTickerEvents,
    mergeLiveEvents,
  },
  WCI_LIVE_ADAPTER,
  makeLiveAdapter,
});
