/**
 * Server-side bot tick: load bot zoos, run same logic as client tickBotZoos, persist.
 * Uses web/js/bot-zoo.js so bot rules stay in one place.
 */

import { getBotZoosForTick, updateBotZooState, expireSaleListings, getActiveSaleListings, placeBid } from "./db.js";
import { tickBotZoos } from "../web/js/bot-zoo.js";

const BOT_TICK_INTERVAL_MS = 15 * 1000;
let lastTickAt = 0;

/**
 * Run one bot tick and persist all bot zoos.
 * @returns {Promise<void>}
 */
export async function runBotTick() {
  const nowUnix = Math.floor(Date.now() / 1000);
  const nowMs = Date.now();
  const dt = lastTickAt > 0 ? Math.min((nowMs - lastTickAt) / 1000, 60) : 10;
  lastTickAt = nowMs;

  await expireSaleListings();

  const botZoos = await getBotZoosForTick();
  if (botZoos.length === 0) return;

  const activeListings = await getActiveSaleListings();
  for (const listing of activeListings) {
    const minBid = (listing.best_bid_amount ?? listing.initial_price) + 1;
    const bidders = botZoos.filter(
      (z) => z.id !== listing.seller_zoo_id && (z.botState?.coins ?? 0) >= minBid
    );
    if (bidders.length > 0) {
      const bidder = bidders[Math.floor(Math.random() * bidders.length)];
      const result = await placeBid(listing.id, bidder.id, minBid);
      if (result.ok) break;
    }
  }

  const state = { worldZoos: botZoos };
  tickBotZoos(state, nowUnix, dt);

  for (const zoo of botZoos) {
    await updateBotZooState(zoo.id, zoo.animalWeights, zoo.botState);
  }
}

/**
 * Start the periodic bot tick (call after server listen).
 * @returns {void}
 */
export function startBotTickInterval() {
  setInterval(() => {
    runBotTick().catch((err) => {
      console.error("bot tick failed", err);
    });
  }, BOT_TICK_INTERVAL_MS);
}
