import { randomUUID } from "crypto";
import { SalesOrderLine, SalesShipmentItem } from "../../data/entities.js";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
const cloneJson = (value) => {
  if (value === null || value === void 0) return value;
  return JSON.parse(JSON.stringify(value));
};
const coerceShipmentQuantity = (value) => {
  if (typeof value === "number" && Number.isFinite(value)) return value;
  if (typeof value === "string" && value.trim().length) {
    const parsed = Number(value);
    if (!Number.isNaN(parsed)) return parsed;
  }
  return 0;
};
const extractOrderLineId = (entry) => {
  const raw = typeof entry.orderLine === "string" ? entry.orderLine : entry.orderLine?.id ?? entry.orderLineId ?? null;
  return typeof raw === "string" ? raw : null;
};
const ensureLineMap = async (em, items, lineMap) => {
  const map = lineMap ?? /* @__PURE__ */ new Map();
  const missing = [];
  items.forEach((item) => {
    const lineId = extractOrderLineId(item);
    if (!lineId || map.has(lineId)) return;
    missing.push(lineId);
  });
  if (!missing.length) return map;
  const lines = await em.find(SalesOrderLine, { id: { $in: missing } });
  lines.forEach((line) => map.set(line.id, line));
  return map;
};
const buildShipmentItemSnapshots = (items, options) => {
  const map = options?.lineMap ?? /* @__PURE__ */ new Map();
  return items.map((item) => {
    const orderLineId = extractOrderLineId(item);
    if (!orderLineId) return null;
    const line = map.get(orderLineId) ?? null;
    const id = typeof item.id === "string" ? item.id : randomUUID();
    const quantity = coerceShipmentQuantity(item.quantity);
    const metadata = item.metadata && typeof item.metadata === "object" ? cloneJson(item.metadata) : null;
    return {
      id,
      orderLineId,
      orderLineName: line?.name ?? null,
      orderLineNumber: line?.lineNumber ?? null,
      quantity,
      metadata
    };
  }).filter((entry) => Boolean(entry));
};
const readShipmentItemsSnapshot = (raw) => {
  if (!Array.isArray(raw)) return [];
  return raw.map((entry) => {
    if (!entry || typeof entry !== "object") return null;
    const orderLineId = typeof entry.orderLineId === "string" ? entry.orderLineId : typeof entry.order_line_id === "string" ? entry.order_line_id : null;
    if (!orderLineId) return null;
    const quantity = coerceShipmentQuantity(entry.quantity);
    const orderLineNumberRaw = entry.orderLineNumber ?? entry.order_line_number;
    const orderLineNumber = typeof orderLineNumberRaw === "number" && Number.isFinite(orderLineNumberRaw) ? orderLineNumberRaw : typeof orderLineNumberRaw === "string" && orderLineNumberRaw.trim().length ? Number(orderLineNumberRaw) : null;
    const metadata = entry.metadata && typeof entry.metadata === "object" ? cloneJson(entry.metadata) : null;
    const orderLineName = typeof entry.orderLineName === "string" ? entry.orderLineName : typeof entry.order_line_name === "string" ? entry.order_line_name : null;
    const id = typeof entry.id === "string" && entry.id.length ? entry.id : randomUUID();
    return {
      id,
      orderLineId,
      orderLineName,
      orderLineNumber: Number.isFinite(orderLineNumber) ? Number(orderLineNumber) : null,
      quantity,
      metadata
    };
  }).filter((entry) => Boolean(entry));
};
const refreshShipmentItemsSnapshot = async (em, shipment, options) => {
  const items = options?.items ?? await findWithDecryption(
    em,
    SalesShipmentItem,
    { shipment },
    { populate: ["orderLine"] },
    { tenantId: shipment.tenantId ?? null, organizationId: shipment.organizationId ?? null }
  );
  const map = await ensureLineMap(em, items, options?.lineMap);
  const snapshot = buildShipmentItemSnapshots(items, { lineMap: map });
  shipment.itemsSnapshot = snapshot.length ? snapshot : null;
  return snapshot;
};
export {
  buildShipmentItemSnapshots,
  coerceShipmentQuantity,
  readShipmentItemsSnapshot,
  refreshShipmentItemsSnapshot
};
//# sourceMappingURL=snapshots.js.map
