/**
 * BE mirror of the frontend `calcTotals` in itinerary-helpers.ts.
 * Recomputes a hotel stay's `subtotal` from its child periods + extras
 * so the persisted headline number always matches the sum of children.
 *
 * Keep the math in sync with the frontend — if either drifts, quotes
 * and bookings will show different totals for the same data.
 */

export interface HotelPeriodInput {
  nights?: number[];
  num_rooms: number;
  rate_per_night: number;
}

export interface HotelExtraInput {
  quantity: number;
  rate: number;
  nights?: number[];
  scale_by_rooms?: boolean;
}

function periodTotal(p: HotelPeriodInput): number {
  const rooms = Math.max(1, Number(p.num_rooms) || 1);
  const rate = Number(p.rate_per_night) || 0;
  const n = Array.isArray(p.nights) ? p.nights.length : 0;
  return rate * n * rooms;
}

function extraTotal(e: HotelExtraInput, totalRooms: number): number {
  const qty = Number(e.quantity) || 0;
  const rate = Number(e.rate) || 0;
  const n = Array.isArray(e.nights) ? e.nights.length : 0;
  const scale = e.scale_by_rooms ? Math.max(1, totalRooms) : 1;
  return qty * rate * n * scale;
}

export function computeHotelStayTotal(
  periods: HotelPeriodInput[] | undefined | null,
  extras: HotelExtraInput[] | undefined | null,
): number {
  const ps = Array.isArray(periods) ? periods : [];
  const es = Array.isArray(extras) ? extras : [];
  const periodsTotal = ps.reduce((s, p) => s + periodTotal(p), 0);
  const totalRooms = ps.reduce(
    (s, p) => s + (Math.max(1, Number(p.num_rooms) || 1)),
    0,
  );
  const extrasTotal = es.reduce((s, e) => s + extraTotal(e, totalRooms), 0);
  // Round to 2 decimals — same as decimal(12,2) column precision.
  return Math.round((periodsTotal + extrasTotal) * 100) / 100;
}
