import { GameConfig } from "./config.js";
import { LootTables, getColorNames } from "./loot-tables.js";

const truckMs = () => (GameConfig.WorldMap && GameConfig.WorldMap.TruckAnimationMs) || 2500;
const npcIntervalMs = () => (GameConfig.WorldMap && GameConfig.WorldMap.NpcTruckIntervalMs) || 8000;

/**
 * Remove expired truck sales (player and NPC).
 * @param {import("./types.js").GameState} state
 * @param {number} now
 */
export function pruneTruckSales(state, now) {
  const ms = truckMs();
  if (state.truckSale && state.truckSale.startAt && now - state.truckSale.startAt >= ms) {
    delete state.truckSale;
  }
  if (state.worldTruckSales && state.worldTruckSales.length > 0) {
    state.worldTruckSales = state.worldTruckSales.filter(
      (t) => t.startAt && now - t.startAt < ms
    );
  }
}

/**
 * Add one NPC truck sale between two random zoos (can include player as destination).
 * @param {import("./types.js").GameState} state
 * @param {number} now
 */
export function addNpcTruckSale(state, now) {
  const zoos = state.worldZoos ?? [];
  if (zoos.length < 2) return;
  const fromIdx = Math.floor(Math.random() * zoos.length);
  let toIdx = Math.floor(Math.random() * zoos.length);
  if (toIdx === fromIdx) toIdx = (toIdx + 1) % zoos.length;
  const fromZooId = zoos[fromIdx].id;
  const toZooId = zoos[toIdx].id;
  if (!state.worldTruckSales) state.worldTruckSales = [];
  state.worldTruckSales.push({ fromZooId, toZooId, startAt: now });
}

/**
 * @param {import("./types.js").GameState} state
 * @param {number} nowUnix
 */
export function tickWorldMap(state, nowUnix) {
  const nowMs = nowUnix * 1000;
  pruneTruckSales(state, nowMs);
}

/**
 * Should we add an NPC truck this tick? Call from game loop with a lastNpcTruckAt tracker.
 * @param {number} nowMs
 * @param {number} lastNpcTruckAt
 * @returns {boolean}
 */
export function shouldAddNpcTruck(nowMs, lastNpcTruckAt) {
  return nowMs - lastNpcTruckAt >= npcIntervalMs();
}

/**
 * Laboratory offer duration in seconds.
 */
const LAB_OFFER_DURATION = 45;

/**
 * Chance per refresh (0-1) that the lab has a special offer.
 */
const LAB_OFFER_CHANCE = 0.25;

/**
 * Refresh or expire laboratory offer. Special egg = one of Basic, Ocean, Mountain with a price modifier.
 * @param {import("./types.js").GameState} state
 * @param {number} nowUnix
 * @param {() => number} rng
 */
export function tickLaboratory(state, nowUnix, rng = Math.random) {
  const lab = state.laboratoryOffer;
  if (lab && nowUnix >= lab.endAt) {
    state.laboratoryOffer = null;
  }
  if (!lab && rng() < LAB_OFFER_CHANCE) {
    const types = getColorNames();
    const eggType = types[Math.floor(rng() * types.length)];
    const eggDef = LootTables.EggTypes[eggType];
    const base = eggDef ? eggDef.price : 50;
    const price = Math.floor(base * (0.8 + rng() * 0.4));
    state.laboratoryOffer = { eggType, price, endAt: nowUnix + LAB_OFFER_DURATION };
  }
}
