/*
  levels.js — Save Pet
  ---------------------------------------------------------------
  Generates every level's design from a deterministic seeded RNG:
  the same level id always produces the exact same hive layout,
  timings and difficulty — so "100 levels" means 100 fixed,
  reproducible boards with a real hand-tuned difficulty curve
  (spawn rate, bee speed/type mix, ink budget, hive count all
  scale with level index), not random chaos on every attempt.
  Daily Challenge and Random Challenge reuse the same generator
  with different seeds so they stay fair and balanced too.
*/
window.SP = window.SP || {};

SP.Levels = (function () {
  "use strict";
  const U = SP.Utils, CFG = SP.Config;

  const WORLDS = [
    { id: 1, name: "Sunny Meadow", theme: "hills", sky: ["#BEEBFF", "#EAFBEF"], ground: "#8FE39A", accent: "#FFD54F" },
    { id: 2, name: "Garden Grove", theme: "hills", sky: ["#CFF7E3", "#F3FFE9"], ground: "#7BD48A", accent: "#FF8FB1" },
    { id: 3, name: "Orchard Hills", theme: "hills", sky: ["#FFE3C2", "#FFF6E0"], ground: "#C98B4B", accent: "#FF7A59" },
    { id: 4, name: "Whispering Forest", theme: "hills", sky: ["#BFE8D9", "#E6F5EC"], ground: "#4C8F63", accent: "#F4D35E" },
    { id: 5, name: "Golden Beach", theme: "open", sky: ["#FFE9A8", "#FFF6DE"], ground: "#F2CB7B", accent: "#3AC7C0" },
    { id: 6, name: "Desert Dunes", theme: "open", sky: ["#FFD9A0", "#FFF0D6"], ground: "#E3A85C", accent: "#C96A3E" },
    { id: 7, name: "Misty Mountains", theme: "hills", sky: ["#D4E3F5", "#F1F6FC"], ground: "#8FA6C2", accent: "#FFFFFF" },
    { id: 8, name: "Starlit Night", theme: "night", sky: ["#1B2247", "#3A3F7A"], ground: "#232A55", accent: "#FFD86B" },
    { id: 9, name: "Storm Coast", theme: "night", sky: ["#3B4252", "#6B7B94"], ground: "#2E3646", accent: "#8FD8FF" },
    { id: 10, name: "Royal Hive", theme: "golden", sky: ["#4A2E12", "#B8791E"], ground: "#7A4A16", accent: "#FFD54F" }
  ];

  function worldOf(id) { return U.clamp(Math.ceil(id / CFG.LEVELS_PER_WORLD), 1, CFG.TOTAL_WORLDS); }
  function indexInWorld(id) { return ((id - 1) % CFG.LEVELS_PER_WORLD) + 1; }
  function worldMeta(w) { return WORLDS[U.clamp(w, 1, WORLDS.length) - 1]; }

  function buildHives(rng, count) {
    const hives = [];
    for (let i = 0; i < count; i++) {
      const t = count === 1 ? 0.5 : i / (count - 1);
      const x = U.clamp(U.lerp(0.14, 0.86, t) + U.rngRange(rng, -0.05, 0.05), 0.08, 0.92);
      const y = U.rngRange(rng, 0.08, 0.24);
      hives.push({ x: x, y: y });
    }
    return hives;
  }

  function generateLevel(id) {
    const world = worldOf(id);
    const meta = worldMeta(world);
    const levelInWorld = indexInWorld(id);
    const isBoss = levelInWorld === CFG.LEVELS_PER_WORLD;
    const seed = (id * 7919 + 13) >>> 0;
    const rng = U.mulberry32(seed);
    const t = (id - 1) / (CFG.TOTAL_LEVELS - 1);

    let hiveCount = U.clamp(1 + Math.floor(t * 2.4) + (isBoss ? 1 : 0), 1, 4);
    const hives = buildHives(rng, hiveCount);

    const spawnIntervalMax = U.lerp(2.6, 1.1, t);
    const spawnIntervalMin = Math.min(U.lerp(1.6, 0.55, t) - (isBoss ? 0.15 : 0), spawnIntervalMax - 0.15);
    const beeSpeedMin = U.lerp(0.085, 0.15, t);
    const beeSpeedMax = U.lerp(0.13, 0.23, t) + (isBoss ? 0.015 : 0);
    const inkBudgetRef = Math.round(U.lerp(950, 560, t) - (isBoss ? 40 : 0));
    const tankChance = id > 40 ? U.clamp(U.lerp(0, 0.35, (id - 40) / 60), 0, 0.35) : 0;
    const fastChance = id > 20 ? U.clamp(U.lerp(0, 0.4, (id - 20) / 80), 0, 0.4) : 0;
    const windEnabled = id > 60;
    const burstChance = U.clamp(U.lerp(0.05, 0.3, t), 0, 0.3);
    const surviveTime = Math.max(15, Math.round(U.lerp(18, 72, t) + (isBoss ? 6 : 0) + U.rngRange(rng, -1.5, 1.5)));
    const petX = U.clamp(0.5 + U.rngRange(rng, -0.12, 0.12), 0.2, 0.8);

    return {
      id: id, world: world, worldName: meta.name, theme: meta.theme, sky: meta.sky, ground: meta.ground, accent: meta.accent,
      levelInWorld: levelInWorld, isBoss: isBoss,
      surviveTime: surviveTime,
      petPos: { x: petX, y: 0.84 },
      hives: hives,
      spawnIntervalMin: Math.max(0.35, spawnIntervalMin),
      spawnIntervalMax: spawnIntervalMax,
      beeSpeedMin: beeSpeedMin, beeSpeedMax: beeSpeedMax,
      inkBudgetRef: inkBudgetRef,
      inkRegenPerSecond: 0,
      tankChance: tankChance, fastChance: fastChance, burstChance: burstChance,
      windEnabled: windEnabled,
      seed: seed
    };
  }

  const cache = {};
  function getLevel(id) {
    id = U.clamp(id, 1, CFG.TOTAL_LEVELS);
    if (!cache[id]) cache[id] = generateLevel(id);
    return cache[id];
  }

  function reskin(base, rng) {
    const world = WORLDS[Math.floor(rng() * WORLDS.length)];
    base.theme = world.theme; base.sky = world.sky; base.ground = world.ground; base.accent = world.accent;
    return base;
  }

  function getDailyLevel(dateStr) {
    dateStr = dateStr || U.todayKey();
    const seed = U.dateSeed("daily-" + dateStr);
    const rng = U.mulberry32(seed);
    const virtualId = 55 + Math.floor(rng() * 20);
    const base = JSON.parse(JSON.stringify(generateLevel(virtualId)));
    reskin(base, rng);
    base.worldName = "Daily Challenge";
    base.id = "daily-" + dateStr;
    base.isDaily = true;
    base.dateStr = dateStr;
    return base;
  }

  function getRandomLevel() {
    const seed = (Math.random() * 4294967295) >>> 0;
    const rng = U.mulberry32(seed);
    const virtualId = 35 + Math.floor(rng() * 55);
    const base = JSON.parse(JSON.stringify(generateLevel(virtualId)));
    reskin(base, rng);
    base.worldName = "Random Challenge";
    base.id = "random-" + seed;
    base.isRandom = true;
    return base;
  }

  function getEndlessConfig() {
    const rng = U.mulberry32(4242);
    const world = WORLDS[7];
    return {
      id: "endless", worldName: "Endless Mode", theme: world.theme, sky: world.sky, ground: world.ground, accent: world.accent,
      petPos: { x: 0.5, y: 0.84 },
      hives: buildHives(rng, 2),
      inkBudgetRef: 700, inkRegenPerSecond: 26,
      spawnIntervalMin: 1.5, spawnIntervalMax: 2.3,
      beeSpeedMin: 0.10, beeSpeedMax: 0.15,
      tankChance: 0.04, fastChance: 0.06, burstChance: 0.06, windEnabled: false,
      isEndless: true
    };
  }

  return {
    WORLDS: WORLDS, worldOf: worldOf, indexInWorld: indexInWorld, worldMeta: worldMeta,
    getLevel: getLevel, generateLevel: generateLevel,
    getDailyLevel: getDailyLevel, getRandomLevel: getRandomLevel, getEndlessConfig: getEndlessConfig
  };
})();
