import { tryBuyEgg, tryBuyBaby, tryBuyAnimal } from "./zoo.js";
import { pickSaleTargetZoo } from "./conveyor.js";
import { sellAnimalToNpc, addMatureBabyToSale, addReceptionAnimalToSale } from "./trade.js";
import { playSound } from "./audio.js";
import { t, errorMessage } from "./texts-fr.js";
import { getApiBase, createSale } from "./api-client.js";

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
 * @returns {boolean}
 */
function handleTruckDropBaby(e, setup) {
  const babyOffer = e.dataTransfer.getData("application/x-builazoo-baby-offer");
  if (!babyOffer) return false;
  const [animalId, priceStr] = babyOffer.split(":");
  const price = Number(priceStr) || 80;
  const [ok, result] = tryBuyBaby(setup.state, animalId, price);
  if (!ok) setup.setError(String(t.buyFailed).replace("%s", errorMessage[result] ?? result));
  else setup.setError("");
  playSound(ok ? "buy" : "error");
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
 * @returns {boolean}
 */
function handleTruckDropAnimal(e, setup) {
  const animalOffer = e.dataTransfer.getData("application/x-builazoo-animal-offer");
  if (!animalOffer) return false;
  const [animalId, priceStr] = animalOffer.split(":");
  const price = Number(priceStr) || 120;
  const [ok, result] = tryBuyAnimal(setup.state, animalId, price);
  if (!ok) setup.setError(String(t.buyFailed).replace("%s", errorMessage[result] ?? result));
  else setup.setError("");
  playSound(ok ? "buy" : "error");
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
 * @returns {boolean}
 */
function handleTruckDropEgg(e, setup) {
  const eggType = e.dataTransfer.getData("application/x-builazoo-eggtype");
  if (!eggType) return false;
  const toZooId = e.dataTransfer.getData("application/x-builazoo-offer-zooid") || "player";
  const [ok, result] = tryBuyEgg(setup.state, eggType);
  if (!ok) {
    setup.setError(String(t.buyFailed).replace("%s", errorMessage[result] ?? result));
    playSound("error");
  } else {
    setup.setError("");
    playSound("buy");
    setup.state.eggPurchaseTruck = { eggType, fromZooId: "player", toZooId, startAt: Date.now() };
  }
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
 * @returns {void}
 */
export function handleWorldMapTruckDrop(e, setup) {
  e.preventDefault();
  const el = e.currentTarget;
  if (el && el instanceof HTMLElement) el.classList.remove("dragover");
  if (handleTruckDropBaby(e, setup)) return;
  if (handleTruckDropAnimal(e, setup)) return;
  handleTruckDropEgg(e, setup);
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, lastActionWasDropRef: { current: boolean } }} setup
 * @returns {boolean}
 */
function applyNurseryDrop(e, setup) {
  const nurseryCellKey = e.dataTransfer.getData("application/x-builazoo-nursery-cell-key");
  if (!nurseryCellKey) return false;
  const [ok, result] = addMatureBabyToSale(setup.state, nurseryCellKey);
  if (!ok) {
    setup.setError(String(t.errorPrefix).replace("%s", errorMessage[result] ?? result));
    playSound("error");
  } else {
    setup.setError("");
    playSound("sell");
    const listing = setup.state.saleListings[setup.state.saleListings.length - 1];
    if (getApiBase() && listing) {
      createSale({ animalId: listing.animalId, isBaby: true, price: listing.price, endAt: new Date(listing.endAt * 1000).toISOString(), reproductionScoreAtSale: listing.reproductionScoreAtSale }).then(({ id }) => { listing.serverId = id; setup.setState(); }).catch(() => {});
    }
  }
  setup.lastActionWasDropRef.current = true;
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, lastActionWasDropRef: { current: boolean } }} setup
 * @returns {boolean}
 */
function applyReceptionDrop(e, setup) {
  const receptionCellKey = e.dataTransfer.getData("application/x-builazoo-reception-cell-key");
  if (!receptionCellKey) return false;
  const [ok, result] = addReceptionAnimalToSale(setup.state, receptionCellKey);
  if (!ok) {
    setup.setError(String(t.errorPrefix).replace("%s", errorMessage[result] ?? result));
    playSound("error");
  } else {
    setup.setError("");
    playSound("sell");
    const listing = setup.state.saleListings[setup.state.saleListings.length - 1];
    if (getApiBase() && listing) {
      createSale({ animalId: listing.animalId, isBaby: false, price: listing.price, endAt: new Date(listing.endAt * 1000).toISOString(), reproductionScoreAtSale: listing.reproductionScoreAtSale }).then(({ id }) => { listing.serverId = id; setup.setState(); }).catch(() => {});
    }
  }
  setup.lastActionWasDropRef.current = true;
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, lastActionWasDropRef: { current: boolean } }} setup
 * @returns {boolean}
 */
function applyGridCellSell(e, setup) {
  const raw = e.dataTransfer.getData("text/plain");
  if (!raw || !/^\d+_\d+$/.test(raw)) return false;
  const [sx, sy] = raw.split("_").map(Number);
  const [ok, result] = sellAnimalToNpc(setup.state, sx, sy);
  if (!ok) {
    setup.setError(String(t.sellFailed).replace("%s", errorMessage[result] ?? result));
    playSound("error");
  } else {
    setup.setError("");
    playSound("sell");
    setup.state.truckSale = { toZooId: pickSaleTargetZoo(setup.state), startAt: Date.now() };
  }
  setup.lastActionWasDropRef.current = true;
  setup.setState();
  return true;
}

/**
 * @param {DragEvent} e
 * @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, lastActionWasDropRef: { current: boolean }, sellZoneJustDroppedRef: { current: boolean } }} setup
 * @returns {void}
 */
export function handleSellZoneDrop(e, setup) {
  e.preventDefault();
  const el = e.currentTarget;
  if (el && el instanceof HTMLElement) el.classList.remove("dragover");
  setup.sellZoneJustDroppedRef.current = true;
  if (applyNurseryDrop(e, setup)) return;
  if (applyReceptionDrop(e, setup)) return;
  applyGridCellSell(e, setup);
}
