import type { GameSliceSession, SliceCargoItem } from "./types";

export const SLICE_MINERAL_PRICES: Record<string, number> = {
  Veldspar: 12,
  Tritanium: 5,
  Pyerite: 9,
  "Damaged Railgun": 1800,
};

export function getCargoUsed(session: Pick<GameSliceSession, "cargo">) {
  return session.cargo.reduce((sum, item) => sum + item.quantity, 0);
}

export function getCargoItem(session: Pick<GameSliceSession, "cargo">, item: string) {
  return session.cargo.find((entry) => entry.item === item) ?? null;
}

export function upsertCargo(cargo: SliceCargoItem[], incoming: SliceCargoItem): SliceCargoItem[] {
  const existing = cargo.find((entry) => entry.item === incoming.item && entry.category === incoming.category);
  if (!existing) return [...cargo, { ...incoming }];
  return cargo.map((entry) =>
    entry.item === incoming.item && entry.category === incoming.category
      ? { ...entry, quantity: entry.quantity + incoming.quantity, unitPrice: incoming.unitPrice }
      : entry,
  );
}

export function removeCargo(cargo: SliceCargoItem[], item: string, quantity: number): SliceCargoItem[] {
  let remaining = quantity;
  return cargo
    .map((entry) => {
      if (entry.item !== item || remaining <= 0) return entry;
      const removed = Math.min(entry.quantity, remaining);
      remaining -= removed;
      return { ...entry, quantity: entry.quantity - removed };
    })
    .filter((entry) => entry.quantity > 0);
}

export function addCargoClamped(session: GameSliceSession, incoming: SliceCargoItem): { session: GameSliceSession; added: number } {
  const free = Math.max(0, session.cargoCapacity - getCargoUsed(session));
  const added = Math.min(free, incoming.quantity);
  if (added <= 0) return { session, added: 0 };
  return {
    session: { ...session, cargo: upsertCargo(session.cargo, { ...incoming, quantity: added }) },
    added,
  };
}

export function refineVeldspar(quantity: number): SliceCargoItem[] {
  const batches = Math.floor(quantity / 333);
  const tritanium = Math.floor(batches * 415 * 0.7);
  const pyerite = Math.floor(batches * 42 * 0.7);
  return [
    { item: "Tritanium", category: "mineral", quantity: tritanium, unitPrice: SLICE_MINERAL_PRICES.Tritanium },
    { item: "Pyerite", category: "mineral", quantity: pyerite, unitPrice: SLICE_MINERAL_PRICES.Pyerite },
  ].filter((item) => item.quantity > 0) as SliceCargoItem[];
}

export function sellableCargo(cargo: SliceCargoItem[]) {
  return cargo.filter((item) => item.category === "mineral" || item.category === "ore" || item.category === "loot");
}
