/**
 * 15 color nuances, 5 rarity levels per color = 75 animals.
 * Rarity levels scaled by Fibonacci: F(1)=1, F(2)=1, F(3)=2, F(4)=3, F(5)=5.
 */

const NUM_COLORS = 15;
const NUM_RARITY_LEVELS = 5;

const FIBONACCI = [0, 1, 1, 2, 3, 5];

export function getFibonacciRarity(rarityLevel) {
  const n = Math.max(1, Math.min(NUM_RARITY_LEVELS, Math.floor(rarityLevel)));
  return FIBONACCI[n] ?? 1;
}

const BIOMES = ["Meadow", "Ocean", "Mountain"];

function getBiomeForColorIndex(colorIndex) {
  return BIOMES[Math.floor((colorIndex % NUM_COLORS) / 5)] ?? "Meadow";
}

function buildAnimalId(colorIndex, rarityIndex) {
  return `c${colorIndex}_r${rarityIndex}`;
}

const EggTypes = {};
const Animals = {};

for (let c = 0; c < NUM_COLORS; c++) {
  const eggTypeKey = `Color_${c + 1}`;
  const loot = [];
  for (let r = 0; r < NUM_RARITY_LEVELS; r++) {
    const animalId = buildAnimalId(c, r);
    const rarityLevel = r + 1;
    const fib = getFibonacciRarity(rarityLevel);
    const biome = getBiomeForColorIndex(c);
    const reproductionScoreByBiome = {};
    const survivalScoreByBiome = {};
    for (const b of BIOMES) {
      reproductionScoreByBiome[b] = b === biome ? 1 : 0.5;
      survivalScoreByBiome[b] = b === biome ? 1 : 0.6;
    }
    Animals[animalId] = {
      baseIncomePerSecond: 0.4 * fib,
      rarity: String(rarityLevel),
      biome,
      sellFactor: 12 + fib * 6,
      rarityLevel,
      cellsWide: (c === 7 && r === 1) ? 2 : 1,
      cellsHigh: (c === 7 && r === 1) ? 2 : 1,
      idealTemperature: 18 + (c % 5),
      temperatureTolerance: 5,
      reproductionScoreByBiome,
      survivalScoreByBiome,
    };
    const weight = 60 - r * 12;
    loot.push({ id: animalId, weight: Math.max(10, weight) });
  }
  EggTypes[eggTypeKey] = {
    price: 35 + c * 12 + (c % 5) * 5,
    hatchSeconds: 18 + c * 2,
    minConveyorLevel: 1 + Math.floor(c / 5),
    loot,
  };
}

export const LootTables = {
  EggTypes,
  Animals,
};

export function getAnimalToEggTypeMap() {
  const map = {};
  for (let c = 0; c < NUM_COLORS; c++) {
    const eggTypeKey = `Color_${c + 1}`;
    for (let r = 0; r < NUM_RARITY_LEVELS; r++) {
      map[buildAnimalId(c, r)] = eggTypeKey;
    }
  }
  return map;
}

export function getColorNames() {
  const names = [];
  for (let i = 0; i < NUM_COLORS; i++) {
    names.push(`Color_${i + 1}`);
  }
  return names;
}

/** All color keys with value 0. Use for initial weights or aggregation.
 * @returns {Record<string, number>}
 */
export function zeroAnimalWeights() {
  return Object.fromEntries(getColorNames().map((c) => [c, 0]));
}

export function getRarityLevelFromAnimalId(animalId) {
  const def = Animals[animalId];
  return def?.rarityLevel ?? 1;
}

/**
 * Hatch time multiplier from egg type rarity (rarer eggs take longer). Used when placing egg from nursery.
 * @param {string} eggType
 * @returns {number}
 */
export function getRarityHatchMultiplierForEggType(eggType) {
  const def = EggTypes[eggType];
  if (!def || !def.loot || def.loot.length === 0) return 1;
  let maxRarity = 1;
  for (const entry of def.loot) {
    const r = getRarityLevelFromAnimalId(entry.id);
    if (r > maxRarity) maxRarity = r;
  }
  return 1 + (maxRarity - 1) * 0.2;
}
