import type { DemandWindows, EnvironmentContext } from "@/lib/inventoryRl/types";

function isInHours(hour: number, values: number[]): boolean {
  return values.includes(hour);
}

function clamp(v: number, min: number, max: number): number {
  if (!Number.isFinite(v)) return min;
  return Math.max(min, Math.min(max, v));
}

export function buildInventoryObservation(args: {
  inventory: number[];
  context: EnvironmentContext;
  demandWindows: DemandWindows;
}): number[] {
  const { inventory, context, demandWindows } = args;
  const skuCount = inventory.length;
  const invNorm = inventory.map((v) => clamp(v / (context.capacity / skuCount + 1e-6), 0, 2));
  const weekdayOneHot = new Array<number>(7).fill(0);
  weekdayOneHot[context.weekday] = 1;
  const sales7d = context.sales7d.length === skuCount ? context.sales7d : new Array<number>(skuCount).fill(0);
  const lost7d = context.lost7d.length === skuCount ? context.lost7d : new Array<number>(skuCount).fill(0);
  const waste7d = context.waste7d.length === skuCount ? context.waste7d : new Array<number>(skuCount).fill(0);

  const maxSales = Math.max(1, ...sales7d);
  const maxLost = Math.max(1, ...lost7d);
  const maxWaste = Math.max(1, ...waste7d);
  const salesNorm = sales7d.map((v) => clamp(v / maxSales, 0, 2));
  const lostNorm = lost7d.map((v) => clamp(v / maxLost, 0, 2));
  const wasteNorm = waste7d.map((v) => clamp(v / maxWaste, 0, 2));

  return [
    ...invNorm,
    context.hour / 24,
    ...weekdayOneHot,
    Number(context.isWeekend),
    Number(context.isHoliday),
    context.temp / 100,
    context.precip,
    Number(isInHours(context.hour, demandWindows.pickupMorning)),
    Number(
      isInHours(context.hour, demandWindows.highDemandMorning) ||
        isInHours(context.hour, demandWindows.highDemandLunch)
    ),
    Number(isInHours(context.hour, demandWindows.slowAfternoon)),
    ...salesNorm,
    ...lostNorm,
    ...wasteNorm,
  ];
}
