// codes.jsx — the single source of truth for valid codes.
//
// LOTTERY_CODES are generated algorithmically below from the STICKER_POOL.
// Each lottery code is four space-separated emojis the kid sees on the win
// screen and types into the redeem box. The code maps deterministically to a
// sticker (the 1st emoji of the code) and a media reward (label-only by
// default; add a `url` to render it inline in the RewardModal).
//
// SECRET_CODES are short ALL-CAPS tokens an adult can hand out off-platform
// (birthday, weekend, special events). Add new entries by hand.
//
// To attach real media to any reward, set `media.url` and pick a `media.type`
// of 'YouTube', 'GIF', 'Bilde', or 'Video' so RewardModal renders the right
// element. Until then, the label-only reveal shows a celebratory placeholder.

// 50 deterministic lottery codes. Same code always maps to the same reward.
// We walk lexicographic 4-element combinations of the sticker pool and skip
// ahead by a fixed stride between picks so the first emoji varies between
// codes. C(24, 4) is 10626, so 50 codes always fit with room to spare.
const LOTTERY_CODES = (() => {
  const pool = STICKER_POOL;
  const idx = [0, 1, 2, 3];
  const advance = () => {
    let i = 3;
    while (i >= 0 && idx[i] === pool.length - 4 + i) i--;
    if (i < 0) return false;
    idx[i]++;
    for (let j = i + 1; j < 4; j++) idx[j] = idx[j - 1] + 1;
    return true;
  };
  const STRIDE = 211;          // ~ floor(C(24,4) / 50), spreads codes evenly.
  const SAFETY = 12000;        // hard cap so a bug here can never hang the page.
  const out = [];
  let safety = 0;
  while (out.length < 50 && safety++ < SAFETY) {
    const a = pool[idx[0]], b = pool[idx[1]], c = pool[idx[2]], d = pool[idx[3]];
    out.push({
      code: `${a} ${b} ${c} ${d}`,
      sticker: a,
      media: { type: 'YouTube', label: 'Hemmelig overraskelse' /* , url: '...' */ },
    });
    let stepped = 0;
    while (stepped < STRIDE && advance()) stepped++;
    if (stepped < STRIDE) break;
  }
  return out;
})();

const SECRET_CODES = [
  { code: 'BURSDAG2026', sticker: '🎂', media: { type: 'GIF',
      label: 'Bursdagsmagi' } },
  { code: 'GODHELG',     sticker: '🌈', media: { type: 'YouTube',
      label: 'Helgevideo' } },
  { code: 'JULENISSEN',  sticker: '🎁', media: { type: 'Bilde',
      label: 'Julestjernen' } },
  { code: 'SOMMERFERIE', sticker: '🌻', media: { type: 'GIF',
      label: 'Solsikkedans' } },
  { code: 'SUPERSTJERNE',sticker: '⭐', media: { type: 'YouTube',
      label: 'Stjernesang' } },
];

// Whitespace-insensitive for emoji codes; case-insensitive for ALL-CAPS.
function normalizeCode(input) {
  return String(input || '').replace(/\s+/g, '').trim();
}

function findCode(input) {
  const want = normalizeCode(input);
  if (!want) return null;
  const wantUpper = want.toUpperCase();
  for (const entry of LOTTERY_CODES) {
    if (normalizeCode(entry.code) === want) return { ...entry, source: 'lottery' };
  }
  for (const entry of SECRET_CODES) {
    if (normalizeCode(entry.code).toUpperCase() === wantUpper) {
      return { ...entry, source: 'secret' };
    }
  }
  return null;
}

// Used by lottery.jsx to draw a fresh code the kid has not yet won.
function pickUnwonLotteryCode(profile) {
  const won = new Set(profile.wonCodes || []);
  const available = LOTTERY_CODES.filter(c => !won.has(c.code));
  if (!available.length) return null;
  return available[Math.floor(Math.random() * available.length)];
}

Object.assign(window, {
  LOTTERY_CODES,
  SECRET_CODES,
  findCode,
  normalizeCode,
  pickUnwonLotteryCode,
});
