// wci26/game-loop.jsx - simulated matchday game logic

const WCI_GAME_MODES = [
  { k: 'live', label: 'Live Race', sub: 'top movers' },
  { k: 'buyback', label: 'Buy Flow', sub: 'recent buys' },
  { k: 'leaders', label: 'Leaders', sub: 'top mcap' },
];

const wciClamp = (value, min, max) => Math.max(min, Math.min(max, value));

const wciFmt = (value) => {
  if (typeof fmtVol === 'function') return fmtVol(value);
  if (value >= 1e6) return `$${(value / 1e6).toFixed(2)}M`;
  if (value >= 1e3) return `$${(value / 1e3).toFixed(1)}K`;
  return `$${Math.round(value)}`;
};

const getCountryLevel = (country) => {
  if (!country) return { label: 'Scout', level: 1, xp: 0 };
  const level = wciClamp(Math.round(country.momentum * 8 + (49 - country.rank) / 5), 1, 20);
  const label =
    country.rank === 1 ? 'World Leader' :
    country.rank <= 4 ? 'Final Four' :
    country.rank <= 12 ? 'Knockout Seed' :
    country.rank <= 24 ? 'Group Threat' :
    'Underdog';
  const xp = wciClamp(Math.round((country.volume24h / 3_500_000) * 100), 0, 100);
  return { label, level, xp };
};

const getCountryMilestone = (country) => {
  if (!country) return { previous: 0, next: 250_000, remaining: 250_000, progress: 0 };
  const step = country.volume24h >= 2_500_000 ? 500_000 : 250_000;
  const next = Math.ceil((country.volume24h + 1) / step) * step;
  const previous = next - step;
  const progress = wciClamp(((country.volume24h - previous) / step) * 100, 0, 100);
  return {
    previous,
    next,
    remaining: Math.max(0, next - country.volume24h),
    progress,
  };
};

const getRankPressure = (country, countries, amount = 0) => {
  if (!country || !countries?.length) return { label: 'No rank target', gap: 0, progress: 0 };
  const projectedVolume = country.volume24h + amount;

  if (country.rank === 1) {
    const challenger = countries[1];
    const defendGap = challenger ? projectedVolume - challenger.volume24h : 0;
    return {
      label: challenger ? `Defend #1 vs ${challenger.code}` : 'Defend #1',
      gap: Math.max(0, defendGap),
      progress: 100,
    };
  }

  const target = countries[country.rank - 2];
  if (!target) return { label: 'No rank target', gap: 0, progress: 0 };
  const gap = Math.max(0, target.volume24h - country.volume24h);
  const progress = gap === 0 ? 100 : wciClamp((amount / gap) * 100, 0, 100);
  return {
    label: `Chase #${target.rank} ${target.code}`,
    gap,
    progress,
  };
};

const buildTodayMatch = (countries) => {
  const byCode = Object.fromEntries((countries || []).map(c => [c.code, c]));
  const matches = [
    ...((window.MATCHES_DATA && window.MATCHES_DATA.live) || []),
    ...((window.MATCHES_DATA && window.MATCHES_DATA.upcoming) || []),
  ];

  const candidates = matches
    .map((match) => {
      const a = byCode[match.teams?.[0]];
      const b = byCode[match.teams?.[1]];
      if (!a || !b) return null;

      const total = a.volume24h + b.volume24h;
      const gap = Math.abs(a.volume24h - b.volume24h);
      const closeness = 1 - wciClamp(gap / Math.max(1, total), 0, 1);
      const liveBoost = match.minute ? 1.35 : 1;
      const score = total * (0.45 + closeness) * liveBoost;
      return { match, a, b, total, gap, closeness, score };
    })
    .filter(Boolean)
    .sort((x, y) => y.score - x.score);

  const picked = candidates[0];
  if (!picked) {
    const a = countries?.[0];
    const b = countries?.[1];
    if (!a || !b) return null;
    const total = a.volume24h + b.volume24h;
    return {
      id: 'synthetic',
      a,
      b,
      status: 'LIVE MARKET',
      stage: 'Top 2 token race',
      venue: 'WCI26 Arena',
      total,
      gap: Math.abs(a.volume24h - b.volume24h),
      leader: a.volume24h >= b.volume24h ? a : b,
      trailing: a.volume24h >= b.volume24h ? b : a,
      aPct: total ? (a.volume24h / total) * 100 : 50,
      bPct: total ? (b.volume24h / total) * 100 : 50,
    };
  }

  const { match, a, b, total, gap } = picked;
  const leader = a.volume24h >= b.volume24h ? a : b;
  const trailing = leader.code === a.code ? b : a;
  return {
    id: match.id,
    a,
    b,
    status: match.minute ? `LIVE ${match.minute}'` : `KICKOFF ${match.kick}`,
    stage: `${match.md || 'MD'} Group ${match.group}`,
    venue: match.venue,
    score: match.score,
    total,
    gap,
    leader,
    trailing,
    aPct: total ? (a.volume24h / total) * 100 : 50,
    bPct: total ? (b.volume24h / total) * 100 : 50,
  };
};

const buildDailyMissions = (countries, buybackPool) => {
  const topFiveGate = countries?.[4];
  const chaser = countries?.[5];
  const leader = countries?.[0];
  const liveBuyVolume = (countries || []).reduce((sum, country) => sum + Number(country.recentBuyVolumeWETH || country.volume24h || 0), 0);
  const buyTarget = Math.max(1, Number(leader?.volume24h || 0) * 1.4 || liveBuyVolume * 1.4 || 1);
  const buyProgress = wciClamp((liveBuyVolume / buyTarget) * 100, 0, 100);

  const missions = [];
  if (topFiveGate && chaser) {
    const gap = Math.max(0, topFiveGate.volume24h - chaser.volume24h);
    missions.push({
      id: 'top-five',
      label: 'Top 5 Chase',
      title: `${chaser.code} needs a push`,
      body: `${wciFmt(gap)} behind ${topFiveGate.code}`,
      progress: topFiveGate.volume24h ? (chaser.volume24h / topFiveGate.volume24h) * 100 : 0,
      accent: chaser.color,
      reward: 'Captain Badge',
    });
  }

  missions.push({
    id: 'buy-flow',
    label: 'Buy Flow Sprint',
    title: `${leader?.code || 'TOP'} buy wave`,
    body: `${(countries || []).reduce((sum, country) => sum + Number(country.recentBuyCount || 0), 0)} recent buys`,
    progress: buyProgress,
    accent: '#9FD634',
    reward: 'Buy Flow XP',
  });

  return missions.slice(0, 3);
};

const getBuyImpact = (country, amount, countries = []) => {
  const safeAmount = Math.max(0, Number(amount) || 0);
  const fee = safeAmount * 0.01;
  const tokens = country && country.priceWETH > 0 ? Math.round(safeAmount / country.priceWETH) : 0;
  const milestone = getCountryMilestone(country);
  const afterProgress = country
    ? wciClamp(((country.volume24h + safeAmount - milestone.previous) / Math.max(1, milestone.next - milestone.previous)) * 100, 0, 100)
    : 0;
  const rankPressure = getRankPressure(country, countries, safeAmount);

  return {
    amount: safeAmount,
    fee,
    tokens,
    milestone,
    afterProgress,
    milestoneLift: Math.max(0, afterProgress - milestone.progress),
    rankPressure,
  };
};

const getGlobeFocusCodes = (mode, countries) => {
  if (!countries?.length) return [];
  if (mode === 'buyback') {
    return [...countries]
      .sort((a, b) => (b.volume24h * b.momentum + b.buys1m * 18_000) - (a.volume24h * a.momentum + a.buys1m * 18_000))
      .slice(0, 8)
      .map(c => c.code);
  }
  if (mode === 'leaders') {
    return [...countries]
      .sort((a, b) => (b.marketCapWETH - a.marketCapWETH) || (b.poolWethBalance - a.poolWethBalance))
      .slice(0, 8)
      .map(c => c.code);
  }
  return countries.slice(0, 8).map(c => c.code);
};

const buildSeasonTrophies = (countries, buybackPool) => {
  const leader = countries?.[0];
  const streak = [...(countries || [])].sort((a, b) => b.change24h - a.change24h)[0];
  const buyFlow = (countries || []).reduce((sum, country) => sum + Number(country.recentBuyVolumeWETH || country.volume24h || 0), 0);
  const buyFlowTarget = Math.max(1, buyFlow * 1.8 || Number(leader?.volume24h || 0) * 1.8 || 1);
  return [
    {
      id: 'golden-boot',
      label: 'Golden Boot',
      title: leader ? leader.name : 'No leader',
      meta: leader ? `${wciFmt(leader.volume24h)} today` : 'Waiting',
      progress: leader ? getCountryMilestone(leader).progress : 0,
      accent: '#F5D020',
      code: leader?.code,
    },
    {
      id: 'market-cap-cup',
      label: 'Market Cap Cup',
      title: leader ? leader.name : 'No market leader',
      meta: leader && typeof wciFormatCountryMarketCap === 'function' ? `${wciFormatCountryMarketCap(leader)} mcap` : 'Waiting',
      progress: leader ? getCountryMilestone(leader).progress : 0,
      accent: leader?.color || '#4ED1E6',
      code: leader?.code,
    },
    {
      id: 'buy-flow-ball',
      label: 'Buy Flow Ball',
      title: wciFmt(buyFlow),
      meta: `${(countries || []).reduce((sum, country) => sum + Number(country.recentBuyCount || 0), 0)} recent buys`,
      progress: wciClamp((buyFlow / buyFlowTarget) * 100, 0, 100),
      accent: '#9FD634',
    },
    {
      id: 'streak-cup',
      label: 'Streak Cup',
      title: streak ? streak.name : 'No streak',
      meta: streak ? `+${Math.max(0, streak.change24h).toFixed(1)}% 24h` : 'Waiting',
      progress: streak ? wciClamp(streak.change24h * 4, 0, 100) : 0,
      accent: streak?.color || '#E637A8',
      code: streak?.code,
    },
  ];
};

Object.assign(window, {
  WCI_GAME_MODES,
  getCountryLevel,
  getCountryMilestone,
  getRankPressure,
  buildTodayMatch,
  buildDailyMissions,
  getBuyImpact,
  getGlobeFocusCodes,
  buildSeasonTrophies,
});
