/* Game definitions and shared utilities — i18n-driven */

const GAME_META = [
  { id: 'robotek',    num: '01', age: '2013-2017', duration: 180, maxScore: 200, scoring: ['g1.s1','g1.s2','g1.s3','g1.s4'], scoringV: ['+10','+5','-5','-5'], scoringK: ['plus','plus','minus','minus'], tutCount: 3 },
  { id: 'inverse',    num: '02', age: '2013-2017', duration: 180, maxScore: 120, scoring: ['g2.s1','g2.s2','g2.s3'], scoringV: ['+10','+120','DQ'], scoringK: ['plus','plus','minus'], tutCount: 3 },
  { id: 'delivery',   num: '03', age: '2013-2017', duration: 120, maxScore: 50,  scoring: ['g3.s1','g3.s2','g3.s3','g3.s4','g3.s5'], scoringV: ['+10','+5','+10','-5','50'], scoringK: ['plus','plus','plus','minus',''], tutCount: 3 },
  { id: 'mergen',     num: '04', age: '2009-2012', duration: 120, maxScore: 40,  scoring: ['g4.s1','g4.s2','g4.s3','g4.s4','g4.s5'], scoringV: ['+10','+5','+5','-5','40'], scoringK: ['plus','plus','plus','minus',''], tutCount: 3 },
  { id: 'flag',       num: '05', age: '2009-2012', duration: 120, maxScore: 105, scoring: ['g5.s1','g5.s2','g5.s3','g5.s4','g5.s5','g5.s6','g5.s7','g5.s8','g5.s9'], scoringV: ['+10','+10','+10','+10','+10','+20','+5','-5','-5'], scoringK: ['plus','plus','plus','plus','plus','plus','plus','minus','minus'], tutCount: 3 },
  { id: 'sorting',    num: '06', age: '2009-2012', duration: 120, maxScore: 50,  scoring: ['g6.s1','g6.s2','g6.s3','g6.s4','g6.s5'], scoringV: ['+10','+5','-5','-5','50'], scoringK: ['plus','plus','minus','minus',''], tutCount: 3 },
  { id: 'basketball', num: '07', age: '2009-2017', duration: 120, maxScore: 24,  scoring: ['g7.s1','g7.s2','g7.s3','g7.s4'], scoringV: ['+3','+1','+5','g7.s4_v'], scoringK: ['plus','plus','plus','minus'], tutCount: 3 },
];

/* Build the GAMES array using current locale. Re-call after setLocale. */
function buildGames() {
  return GAME_META.map((m, idx) => {
    const i = idx + 1;
    return {
      id: m.id,
      num: m.num,
      age: m.age,
      duration: m.duration,
      maxScore: m.maxScore,
      name: t(`g${i}.name`),
      tagline: t(`g${i}.tagline`),
      blurb: t(`g${i}.blurb`),
      tutorial: Array.from({ length: m.tutCount }).map((_, k) => ({ t: tx(`g${i}.tut${k+1}`) })),
      scoring: m.scoring.map((sk, k) => ({
        k: t(sk),
        v: m.scoringK[k] === 'minus' && m.scoringV[k].startsWith('g') ? t(m.scoringV[k]) : m.scoringV[k],
        kind: m.scoringK[k],
      })),
    };
  });
}

let GAMES = buildGames();

const STORAGE_KEY = 'rgt-progress-v1';
const PROFILE_KEY = 'rgt-profile-v1';
const LB_KEY = 'rgt-leaderboard-v1';

function loadProgress() {
  try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || {}; }
  catch { return {}; }
}
function saveProgress(p) { localStorage.setItem(STORAGE_KEY, JSON.stringify(p)); }

function loadProfile() {
  try {
    const p = JSON.parse(localStorage.getItem(PROFILE_KEY));
    if (p && typeof p.name === 'string' && p.name.trim().length >= 2) return p;
  } catch {}
  return null;
}

/* Pre-filled default for the first-visit prompt. Random 4-digit suffix gives
   ~1/10k collision odds against another fresh visitor on the same leaderboard.
   Server-side de-dup is the upsert on player_name (existing best score wins),
   so a collision just means two players share a row — not a hard failure. */
function generateGuestName() {
  const n = 1000 + Math.floor(Math.random() * 9000);
  return `Guest-${n}`;
}

function saveProfile(name) {
  const trimmed = String(name || '').trim();
  if (trimmed.length < 2) return null;
  // Stable color from name hash so the same person always gets the same avatar tint.
  const palette = ['#bdf26e','#ff7a59','#5cc8ff','#ffd23f','#a78bfa','#34d399'];
  let h = 0;
  for (let i = 0; i < trimmed.length; i++) h = (h * 31 + trimmed.charCodeAt(i)) | 0;
  const color = palette[Math.abs(h) % palette.length];
  const profile = { name: trimmed, color };
  try { localStorage.setItem(PROFILE_KEY, JSON.stringify(profile)); } catch {}
  return profile;
}

/* Remote leaderboard via Next.js API route. Falls back to localStorage seed if API is unavailable. */
const ARENA_API_BASE = '/api/arena/leaderboard';

async function fetchLeaderboard() {
  try {
    const r = await fetch(ARENA_API_BASE, { method: 'GET', cache: 'no-store' });
    if (!r.ok) throw new Error('lb fetch failed: ' + r.status);
    const data = await r.json();
    if (Array.isArray(data?.entries)) return data.entries;
  } catch (e) {
    /* swallow - fall back to local seed */
  }
  return loadLeaderboardLocal();
}

async function postLeaderboard(payload) {
  try {
    await fetch(ARENA_API_BASE, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
      keepalive: true,
    });
  } catch {}
}

function loadLeaderboardLocal() {
  try {
    const lb = JSON.parse(localStorage.getItem(LB_KEY));
    if (Array.isArray(lb)) return lb;
  } catch {}
  const seed = [
    { who: 'TerraBot',    score: 145 },
    { who: 'Lumen-9',     score: 110 },
    { who: 'KazRover',    score: 105 },
    { who: 'NovaBot',     score: 95  },
    { who: 'IronCog',     score: 85  },
    { who: 'PixelPilot',  score: 80  },
    { who: 'GearSparrow', score: 70  },
    { who: 'AstraBee',    score: 65  },
    { who: 'MonoCircuit', score: 60  },
    { who: 'Quasar',      score: 55  },
  ];
  localStorage.setItem(LB_KEY, JSON.stringify(seed));
  return seed;
}
function saveLeaderboardLocal(lb) { localStorage.setItem(LB_KEY, JSON.stringify(lb)); }

function fmtTime(s) {
  s = Math.max(0, Math.round(s));
  const m = Math.floor(s / 60);
  const r = s % 60;
  return `${m}:${String(r).padStart(2,'0')}`;
}

function RobotGlyph({ color = 'currentColor', size = 32, variant = 0 }) {
  const eyes = variant % 3;
  const antenna = variant % 2;
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      {antenna === 0 ? <line x1="16" y1="3" x2="16" y2="7" /> : <><line x1="13" y1="3" x2="13" y2="7" /><line x1="19" y1="3" x2="19" y2="7" /></>}
      <circle cx="16" cy="4" r="1.2" fill={color} stroke="none" />
      <rect x="6" y="8" width="20" height="14" rx="3" />
      {eyes === 0 && <><circle cx="12" cy="14" r="1.6" fill={color} stroke="none" /><circle cx="20" cy="14" r="1.6" fill={color} stroke="none" /></>}
      {eyes === 1 && <rect x="10" y="13" width="12" height="3" rx="1.5" fill={color} stroke="none" />}
      {eyes === 2 && <><circle cx="11" cy="14" r="2" fill={color} stroke="none" /><circle cx="21" cy="14" r="2" fill={color} stroke="none" /></>}
      <line x1="11" y1="19" x2="21" y2="19" />
      <line x1="3" y1="14" x2="6" y2="14" /><line x1="26" y1="14" x2="29" y2="14" />
      <rect x="9" y="22" width="5" height="6" rx="1" />
      <rect x="18" y="22" width="5" height="6" rx="1" />
    </svg>
  );
}

window.GAME_META = GAME_META;
window.GAMES = GAMES;
window.buildGames = buildGames;
window.rebuildGames = () => { GAMES = buildGames(); window.GAMES = GAMES; return GAMES; };
window.loadProgress = loadProgress;
window.saveProgress = saveProgress;
window.loadProfile = loadProfile;
window.saveProfile = saveProfile;
window.generateGuestName = generateGuestName;
window.fetchLeaderboard = fetchLeaderboard;
window.postLeaderboard = postLeaderboard;
window.loadLeaderboardLocal = loadLeaderboardLocal;
window.saveLeaderboardLocal = saveLeaderboardLocal;
window.fmtTime = fmtTime;
window.RobotGlyph = RobotGlyph;
