// wci26/contract-data.jsx - contract-shaped mock adapter for WCI26 V3 dashboard logic
// Depends on country-tokens.jsx for geography, color, and base country roster helpers.

const WCI_CONTRACT_CONSTANTS = {
  buybackThresholdWETH: 0.1,
  collectionCooldownMs: 60 * 60 * 1000,
  minTriggerWETH: 0.01,
  feeTierBps: 10000,
  impliedVolumeMultiplier: 100,
  allocationCaps: {
    reserve: 200_000_000,
    airdrop: 150_000_000,
    treasury: 100_000_000,
    rewards: 50_000_000,
  },
  championRewardBps: 0,
};

const WCI_DEPLOYMENT_PENDING = 'Pending deployment';
const WCI_EVENT_TIME_BASE = Date.UTC(2026, 4, 16, 10, 0, 0);

const wciContractClamp = (value, min, max) => Math.max(min, Math.min(max, value));
const clampPct = (value) => wciContractClamp(Number(value) || 0, 0, 100);
const deriveVolumeFromFees = (totalFeesWETH) =>
  Number((Number(totalFeesWETH || 0) * WCI_CONTRACT_CONSTANTS.impliedVolumeMultiplier).toFixed(6));

const hashIso = (isoCode) => {
  const code = String(isoCode || '---');
  return code.split('').reduce((sum, char, index) => sum + char.charCodeAt(0) * (index + 7), 0);
};

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

const deriveContractMetrics = (country, index) => {
  const seed = hashIso(country.code);
  const rankWeight = (49 - country.rank) / 48;
  const seedWeight = (seed % 29) / 28;
  const totalFeesWETH = Number((0.16 + rankWeight * 2.35 + country.momentum * 0.42 + seedWeight * 0.16).toFixed(6));
  const weeklyFeesDeltaWETH = Number((0.005 + rankWeight * 0.18 + ((seed % 17) / 16) * 0.055).toFixed(6));
  const pendingWETH = Number((0.006 + rankWeight * 0.095 + ((seed % 13) / 12) * 0.035).toFixed(6));
  const now = WCI_EVENT_TIME_BASE;
  const lastCollectionAt = now - ((index % 8) * 13 + 18) * 60 * 1000;
  const cooldownReady = now >= lastCollectionAt + WCI_CONTRACT_CONSTANTS.collectionCooldownMs;
  const buybackProgressPct = clampPct((pendingWETH / WCI_CONTRACT_CONSTANTS.buybackThresholdWETH) * 100);
  const buybackReady = pendingWETH >= WCI_CONTRACT_CONSTANTS.buybackThresholdWETH;
  const activityBonus = Math.round(country.buys1m * 0.8);
  const nationalPower = Math.round(
    totalFeesWETH * 120
    + deriveVolumeFromFees(totalFeesWETH) * 0.55
    + pendingWETH * 1200
    + weeklyFeesDeltaWETH * 1600
    + (country.rank <= 16 ? 90 : 20)
    + activityBonus
  );
  const statusCycle = seed % 19;
  const active = statusCycle !== 0 && statusCycle !== 7;
  const caps = WCI_CONTRACT_CONSTANTS.allocationCaps;
  const allocationLoad = 0.05 + rankWeight * 0.38 + seedWeight * 0.08;
  const allocation = {
    reserve: getAllocationBucket(caps.reserve, caps.reserve * allocationLoad * 0.64, 'Operational reserve'),
    airdrop: getAllocationBucket(caps.airdrop, caps.airdrop * allocationLoad * 0.72, 'Community allocation'),
    treasury: getAllocationBucket(caps.treasury, caps.treasury * allocationLoad * 0.46, 'Operations allocation'),
    rewards: getAllocationBucket(caps.rewards, caps.rewards * allocationLoad * 0.38, 'Future rewards allocation'),
  };

  return {
    isoCode: country.code,
    ticker: country.ticker,
    symbol: country.symbol || country.ticker || `${country.code}26`,
    tokenSymbol: country.tokenSymbol || `$${country.ticker || `${country.code}26`}`,
    tokenAddress: WCI_DEPLOYMENT_PENDING,
    poolAddress: WCI_DEPLOYMENT_PENDING,
    lpTokenId: WCI_DEPLOYMENT_PENDING,
    active,
    totalFeesWETH,
    totalVolumeWETH: deriveVolumeFromFees(totalFeesWETH),
    pendingWETH,
    lastCollectionAt,
    cooldownReady,
    buybackThresholdWETH: WCI_CONTRACT_CONSTANTS.buybackThresholdWETH,
    buybackProgressPct,
    buybackReady,
    minTriggerWETH: WCI_CONTRACT_CONSTANTS.minTriggerWETH,
    weeklyFeesDeltaWETH,
    weeklyFeesBaselineWETH: Number(Math.max(0, totalFeesWETH - weeklyFeesDeltaWETH).toFixed(6)),
    nationalPower,
    allocation,
    dashboardDataState: 'simulated-contract-shaped',
  };
};

const buildContractCountries = (marketState = 'live') => {
  const marketRows = typeof buildCountryTokens === 'function' ? buildCountryTokens(marketState) : [];
  return marketRows.map((country, index) => {
    const metrics = deriveContractMetrics(country, index);
    return {
      ...country,
      ...metrics,
      code: country.code,
      rank: country.rank,
      contractLoopLabel: 'Country activity -> live buy flow -> WCI26 strength',
    };
  });
};

const getAdapterCountries = () => buildContractCountries('live');

const withModeRanks = (rows, mode) => {
  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 === 'tournament') return country.active ? 1000 - country.rank : -country.rank;
    if (mode === 'rewards') return country.allocation.rewards.remainingTokens;
    return country.nationalPower;
  };

  return [...rows]
    .sort((a, b) => scoreFor(b) - scoreFor(a) || a.rank - b.rank)
    .map((country, index) => ({
      ...country,
      rankByMode: index + 1,
      leaderboardMode: mode,
      leaderboardScore: scoreFor(country),
    }));
};

const getCountries = () => getAdapterCountries();

const getCountry = (isoCode) => {
  const normalized = String(isoCode || '').toUpperCase();
  return getCountries().find((country) => country.isoCode === normalized || country.code === normalized) || null;
};

const getLeaderboard = (mode = 'nationalPower') => withModeRanks(getCountries(), mode);

const getCountryBuybackState = (isoCode) => {
  const country = getCountry(isoCode);
  if (!country) return null;
  return {
    isoCode: country.isoCode,
    name: country.name,
    pendingWETH: country.pendingWETH,
    thresholdWETH: WCI_CONTRACT_CONSTANTS.buybackThresholdWETH,
    minTriggerWETH: WCI_CONTRACT_CONSTANTS.minTriggerWETH,
    progressPct: country.buybackProgressPct,
    buybackReady: country.buybackReady,
    cooldownReady: country.cooldownReady,
    lastCollectionAt: country.lastCollectionAt,
    stateLabel: country.buybackReady ? 'Buy flow active' : 'Accumulating activity',
  };
};

const getRewardAllocations = (isoCode) => {
  const country = getCountry(isoCode);
  if (!country) return null;
  return country.allocation;
};

const getGlobalBuybackPressure = () => {
  const countries = getCountries();
  const pendingWETH = Number(countries.reduce((sum, country) => sum + country.pendingWETH, 0).toFixed(6));
  const buybackReadyCount = countries.filter((country) => country.buybackReady).length;
  return {
    pendingWETH,
    buybackReadyCount,
    activeCountries: countries.filter((country) => country.active).length,
    eliminatedCountries: countries.filter((country) => !country.active).length,
    executorPendingETH: Number((pendingWETH * 0.18).toFixed(6)),
    totalETHBought: Number((countries.reduce((sum, country) => sum + country.totalFeesWETH, 0) * 0.42).toFixed(6)),
    buybackCount: 42 + buybackReadyCount,
    thresholdWETH: WCI_CONTRACT_CONSTANTS.buybackThresholdWETH,
    dataState: 'simulated-contract-shaped',
  };
};

const makeEvent = (type, country, offsetMinutes, payload = {}) => ({
  id: `${type}-${country?.isoCode || 'GLOBAL'}-${offsetMinutes}`,
  type,
  isoCode: country?.isoCode || null,
  countryName: country?.name || 'WCI26',
  timestamp: WCI_EVENT_TIME_BASE - offsetMinutes * 60 * 1000,
  simulated: true,
  ...payload,
});

const getRecentEvents = () => {
  const countries = getCountries();
  const ready = countries.filter((country) => country.buybackReady).slice(0, 4);
  const top = getLeaderboard('weeklyMomentum').slice(0, 5);
  const distribution = getLeaderboard('rewards').slice(0, 3);
  return [
    ...ready.map((country, index) => makeEvent('BuybackReady', country, 7 + index * 6, {
      wethOwed: country.pendingWETH,
      thresholdWETH: WCI_CONTRACT_CONSTANTS.buybackThresholdWETH,
    })),
    ...top.map((country, index) => makeEvent(index % 2 ? 'VolumeRecorded' : 'FeesCollected', country, 33 + index * 8, {
      wethAmount: country.weeklyFeesDeltaWETH,
      wethVolume: deriveVolumeFromFees(country.weeklyFeesDeltaWETH),
    })),
    ...distribution.map((country, index) => makeEvent(['ReserveDistributed', 'AirdropDistributed', 'RewardsDistributed'][index], country, 80 + index * 18, {
      totalDistributed: Object.values(country.allocation)[index].distributedTokens,
    })),
  ].slice(0, 12);
};

const getSeasonSnapshot = () => {
  const weeklyMomentum = getLeaderboard('weeklyMomentum').map((country) => ({
    isoCode: country.isoCode,
    name: country.name,
    weeklyFeesDeltaWETH: country.weeklyFeesDeltaWETH,
    totalFeesWETH: country.totalFeesWETH,
    rankByMode: country.rankByMode,
  }));
  const weeklyChampion = {
    ...weeklyMomentum[0],
    basedOn: 'snapshot-delta',
    rewardBps: WCI_CONTRACT_CONSTANTS.championRewardBps,
    rewardState: 'Cosmetic only until reward mechanism exists',
  };
  return {
    snapshotAt: WCI_EVENT_TIME_BASE,
    baselineAt: WCI_EVENT_TIME_BASE - 7 * 24 * 60 * 60 * 1000,
    weeklyChampion,
    weeklyMomentum,
    championHistory: weeklyMomentum.slice(0, 4).map((country, index) => ({
      isoCode: country.isoCode,
      name: country.name,
      weeklyFeesDeltaWETH: country.weeklyFeesDeltaWETH,
      crownedAt: WCI_EVENT_TIME_BASE - index * 7 * 24 * 60 * 60 * 1000,
      basedOn: 'snapshot-delta',
    })),
  };
};

const getTournamentState = () => {
  const countries = getCountries();
  const activeCountries = countries.filter((country) => country.active);
  const eliminatedCountries = countries.filter((country) => !country.active);
  const topByGroup = {};
  countries.forEach((country) => {
    if (!topByGroup[country.group] || country.nationalPower > topByGroup[country.group].nationalPower) {
      topByGroup[country.group] = country;
    }
  });
  const groupLeaders = Object.values(topByGroup).sort((a, b) => a.group.localeCompare(b.group));
  const groupStageResults = groupLeaders.slice(0, 8).map((winner, index) => {
    const loser = countries.find((country) => country.group === winner.group && country.isoCode !== winner.isoCode) || countries[index + 8];
    return {
      matchId: index + 1,
      winner: winner.isoCode,
      loser: loser?.isoCode || null,
      timestamp: WCI_EVENT_TIME_BASE - (index + 1) * 90 * 60 * 1000,
      simulated: true,
    };
  });
  return {
    activeCount: activeCountries.length,
    eliminatedCount: eliminatedCountries.length,
    activeCountries: activeCountries.map((country) => country.isoCode),
    eliminatedCountries: eliminatedCountries.map((country) => country.isoCode),
    groupLeaders,
    groupStageResults,
  };
};

const WCI_CONTRACT_ADAPTER = {
  getCountries,
  getCountry,
  getLeaderboard,
  getGlobalBuybackPressure,
  getCountryBuybackState,
  getRewardAllocations,
  getRecentEvents,
  getSeasonSnapshot,
  getTournamentState,
};

Object.assign(window, {
  WCI_CONTRACT_CONSTANTS,
  WCI_CONTRACT_ADAPTER,
  buildContractCountries,
});
