const axios = require("axios");

function resolveConfig(bru) {
  return {
    baseUrl: bru.getEnvVar("baseUrl") || bru.getVar("baseUrl"),
    playerId: bru.getEnvVar("playerId") || bru.getVar("playerId"),
    jsonHeaders: { headers: { "Content-Type": "application/json" } },
  };
}

function inventoryUrl(baseUrl, playerId) {
  return `${baseUrl}/game/players/${playerId}/inventory`;
}

function sumItemQuantity(inventory, itemId) {
  const slots = [...inventory.bagSlots, ...inventory.equipmentSlots];
  return slots
    .filter((slot) => slot.itemId === itemId)
    .reduce((total, slot) => total + slot.quantity, 0);
}

async function getInventory(bru) {
  const { baseUrl, playerId } = resolveConfig(bru);
  const response = await axios.get(inventoryUrl(baseUrl, playerId));
  if (response.status !== 200) {
    throw new Error(`GET inventory failed: ${response.status}`);
  }

  return response.data;
}

async function postMutation(bru, body) {
  const { baseUrl, playerId, jsonHeaders } = resolveConfig(bru);
  return axios.post(inventoryUrl(baseUrl, playerId), body, jsonHeaders);
}

async function ensureItemQuantity(bru, itemId, minQuantity) {
  const inventory = await getInventory(bru);
  const current = sumItemQuantity(inventory, itemId);
  if (current >= minQuantity) {
    return current;
  }

  const response = await postMutation(bru, {
    schemaVersion: 1,
    mutationKind: "add",
    itemId,
    quantity: minQuantity - current,
  });
  if (response.status !== 200 || response.data?.applied !== true) {
    throw new Error(
      `seed add ${itemId} failed: ${response.status} ${JSON.stringify(response.data)}`,
    );
  }

  const after = await getInventory(bru);
  return sumItemQuantity(after, itemId);
}

module.exports = {
  sumItemQuantity,
  getInventory,
  postMutation,
  ensureItemQuantity,
};
