"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { MapPin, Truck } from "lucide-react";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
import { useDialogKeyHandler } from "@open-mercato/ui/hooks/useDialogKeyHandler";
import { Input } from "@open-mercato/ui/primitives/input";
import { Textarea } from "@open-mercato/ui/primitives/textarea";
import { Label } from "@open-mercato/ui/primitives/label";
import { Switch } from "@open-mercato/ui/primitives/switch";
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
import { LookupSelect } from "@open-mercato/ui/backend/inputs";
import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
import { createCrud, updateCrud } from "@open-mercato/ui/backend/utils/crud";
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
import { handleSectionMutationError } from "./optimisticLock.js";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { cn } from "@open-mercato/shared/lib/utils";
import { E } from "../../../../generated/entities.ids.generated.js";
import { emitSalesDocumentTotalsRefresh } from "@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { formatMoney, normalizeNumber } from "./lineItemUtils.js";
import { formatAddressString } from "@open-mercato/core/modules/customers/utils/addressFormat";
import { normalizeCustomFieldSubmitValue, extractCustomFieldValues } from "./customFieldHelpers.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sales");
function mergeShippingMethodOptions(options, selected) {
  if (!selected) return options;
  if (options.some((option) => option.id === selected.id)) return options;
  return [selected, ...options];
}
function mergeStatusOptions(options, selected) {
  if (!selected) return options;
  if (options.some((option) => option.id === selected.id)) return options;
  return [selected, ...options];
}
function mapStatusOption(entry) {
  const id = typeof entry.id === "string" ? entry.id : null;
  const value = typeof entry.value === "string" ? entry.value : null;
  if (!id || !value) return null;
  const label = typeof entry.label === "string" && entry.label.trim().length ? entry.label : value;
  const color = typeof entry.color === "string" && entry.color.trim().length ? entry.color : null;
  return { id, value, label, color };
}
const ADDRESS_SNAPSHOT_KEY = "shipmentAddressSnapshot";
const ADDRESS_FORMAT = "line_first";
const SHIPPING_ADJUSTMENT_TOGGLE_ID = "shipment-add-shipping-adjustment";
const SHIPPING_ADJUSTMENT_LABEL_ID = "shipment-add-shipping-adjustment-label";
const SHIPPING_ADJUSTMENT_HELP_ID = "shipment-add-shipping-adjustment-help";
const parseTrackingNumbers = (value) => (value ?? "").split(/[\n,]/g).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
const normalizePrice = (value) => {
  const parsed = normalizeNumber(value, NaN);
  if (!Number.isFinite(parsed)) return null;
  if (parsed <= 0) return null;
  return parsed;
};
const roundAmount = (value) => Math.round((value + Number.EPSILON) * 100) / 100;
const readStringField = (input, keys) => {
  for (const key of keys) {
    const value = input[key];
    if (typeof value === "string" && value.trim().length) return value.trim();
  }
  return null;
};
const normalizeAddressSnapshot = (input) => {
  if (!input || typeof input !== "object") return null;
  const normalized = {};
  const assignString = (target, ...sourceKeys) => {
    const value = readStringField(input, sourceKeys);
    if (value) normalized[target] = value;
  };
  const assignOther = (target, value) => {
    if (typeof value === "boolean") {
      normalized[target] = value;
    } else if (typeof value === "number" && Number.isFinite(value)) {
      normalized[target] = value;
    }
  };
  const id = readStringField(input, ["customerAddressId", "customer_address_id"]) ?? readStringField(input, ["id"]);
  if (id) normalized.id = id;
  const documentAddressId = readStringField(input, ["documentAddressId", "document_address_id"]);
  if (documentAddressId && documentAddressId !== id) normalized.documentAddressId = documentAddressId;
  assignString("name", "name");
  assignString("purpose", "purpose");
  assignString("companyName", "companyName", "company_name");
  assignString("addressLine1", "addressLine1", "address_line1");
  assignString("addressLine2", "addressLine2", "address_line2");
  assignString("buildingNumber", "buildingNumber", "building_number");
  assignString("flatNumber", "flatNumber", "flat_number");
  assignString("city", "city");
  assignString("region", "region");
  assignString("postalCode", "postalCode", "postal_code");
  assignString("country", "country");
  assignOther("latitude", input.latitude ?? null);
  assignOther("longitude", input.longitude ?? null);
  assignOther("isPrimary", input.isPrimary ?? input.is_primary ?? false);
  return Object.keys(normalized).length ? normalized : null;
};
const mapSnapshotToAddressValue = (snapshot) => ({
  addressLine1: readStringField(snapshot, ["addressLine1"]),
  addressLine2: readStringField(snapshot, ["addressLine2"]),
  buildingNumber: readStringField(snapshot, ["buildingNumber"]),
  flatNumber: readStringField(snapshot, ["flatNumber"]),
  city: readStringField(snapshot, ["city"]),
  region: readStringField(snapshot, ["region"]),
  postalCode: readStringField(snapshot, ["postalCode"]),
  country: readStringField(snapshot, ["country"]),
  companyName: readStringField(snapshot, ["companyName"])
});
const snapshotKey = (snapshot) => {
  if (!snapshot || typeof snapshot !== "object") return null;
  const normalized = {};
  Object.keys(snapshot).sort((a, b) => a.localeCompare(b)).forEach((key) => {
    normalized[key] = snapshot[key];
  });
  return JSON.stringify(normalized);
};
const fallbackAddressId = (id) => id ?? "address";
const buildAddressOption = (snapshot, opts) => {
  const normalized = normalizeAddressSnapshot(snapshot);
  if (!normalized) return null;
  const value = mapSnapshotToAddressValue(normalized);
  const summary = formatAddressString(value, ADDRESS_FORMAT);
  const label = opts?.label ?? normalized.name ?? normalized.purpose ?? summary ?? normalized.companyName ?? fallbackAddressId(opts?.id);
  const normalizedId = typeof normalized.documentAddressId === "string" && normalized.documentAddressId || typeof normalized.id === "string" && normalized.id || null;
  const id = opts?.id ?? normalizedId ?? fallbackAddressId(opts?.id);
  return {
    id,
    label: label || id,
    summary: summary || label || id,
    snapshot: normalized
  };
};
const dedupeAddressOptions = (options) => {
  const seen = /* @__PURE__ */ new Set();
  return options.reduce((acc, option) => {
    const key = snapshotKey(option.snapshot) ?? option.id;
    if (seen.has(key)) return acc;
    seen.add(key);
    acc.push(option);
    return acc;
  }, []);
};
const extractShipmentAddressSnapshot = (metadata) => {
  if (!metadata || typeof metadata !== "object") return null;
  const raw = metadata[ADDRESS_SNAPSHOT_KEY];
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
  return normalizeAddressSnapshot(raw);
};
const addressOptionsSignature = (options) => options.map((option) => `${snapshotKey(option.snapshot) ?? ""}::${option.id}`).join("||");
function useStableAddressOptions(options) {
  const signature = addressOptionsSignature(options);
  const stableRef = React.useRef(options);
  const signatureRef = React.useRef(signature);
  if (signatureRef.current !== signature) {
    signatureRef.current = signature;
    stableRef.current = options;
  }
  return stableRef.current;
}
function ShipmentDialog({
  open,
  mode,
  shipment,
  lines,
  orderId,
  currencyCode,
  organizationId,
  tenantId,
  documentUpdatedAt,
  computeAvailable,
  shippingAddressSnapshot,
  onClose,
  onSaved,
  onAddComment
}) {
  const t = useT();
  const [formResetKey, setFormResetKey] = React.useState(0);
  const [shippingMethods, setShippingMethods] = React.useState([]);
  const [shippingMethodLoading, setShippingMethodLoading] = React.useState(false);
  const [addressOptions, setAddressOptions] = React.useState([]);
  const [addressLoading, setAddressLoading] = React.useState(false);
  const [addressError, setAddressError] = React.useState(null);
  const [documentStatuses, setDocumentStatuses] = React.useState([]);
  const [lineStatuses, setLineStatuses] = React.useState([]);
  const [shipmentStatuses, setShipmentStatuses] = React.useState([]);
  const [documentStatusLoading, setDocumentStatusLoading] = React.useState(false);
  const [lineStatusLoading, setLineStatusLoading] = React.useState(false);
  const [shipmentStatusLoading, setShipmentStatusLoading] = React.useState(false);
  const dialogContentRef = React.useRef(null);
  const itemErrorSetterRef = React.useRef(null);
  const baseItems = React.useMemo(
    () => lines.reduce((acc, line) => {
      acc[line.id] = "";
      return acc;
    }, {}),
    [lines]
  );
  const shipmentAddressSnapshot = React.useMemo(
    () => extractShipmentAddressSnapshot(shipment?.metadata),
    [shipment?.metadata]
  );
  const normalizedShippingAddressSnapshot = React.useMemo(
    () => normalizeAddressSnapshot(shippingAddressSnapshot ?? null),
    [shippingAddressSnapshot]
  );
  const shippingAddressOption = React.useMemo(
    () => buildAddressOption(normalizedShippingAddressSnapshot ?? null, {
      id: "shipping-address",
      label: t("sales.documents.shipments.shippingAddressLabel", "Shipping address")
    }),
    [normalizedShippingAddressSnapshot, t]
  );
  const shipmentAddressOption = React.useMemo(
    () => buildAddressOption(shipmentAddressSnapshot ?? null, {
      id: "shipment-address",
      label: t("sales.documents.shipments.shipmentAddressLabel", "Shipment address")
    }),
    [shipmentAddressSnapshot, t]
  );
  const computedBaseAddressOptions = React.useMemo(
    () => dedupeAddressOptions(
      [shippingAddressOption, shipmentAddressOption].filter(
        (entry) => Boolean(entry)
      )
    ),
    [shipmentAddressOption, shippingAddressOption]
  );
  const baseAddressOptions = useStableAddressOptions(computedBaseAddressOptions);
  const preferredAddressId = React.useMemo(() => {
    const shipmentKey = snapshotKey(shipmentAddressSnapshot);
    if (shipmentKey) {
      const match = baseAddressOptions.find(
        (option) => snapshotKey(option.snapshot) === shipmentKey
      );
      if (match) return match.id;
    }
    if (normalizedShippingAddressSnapshot) {
      const shippingKey = snapshotKey(normalizedShippingAddressSnapshot);
      const match = baseAddressOptions.find(
        (option) => snapshotKey(option.snapshot) === shippingKey
      );
      if (match) return match.id;
    }
    return baseAddressOptions[0]?.id ?? "";
  }, [baseAddressOptions, shipmentAddressSnapshot, normalizedShippingAddressSnapshot]);
  const initialValues = React.useMemo(
    () => ({
      shipmentNumber: shipment?.shipmentNumber ?? "",
      carrierName: shipment?.carrierName ?? "",
      shippingMethodId: shipment?.shippingMethodId ?? "",
      shipmentAddressId: preferredAddressId,
      shippedAt: shipment?.shippedAt ? shipment.shippedAt.slice(0, 10) : "",
      deliveredAt: shipment?.deliveredAt ? shipment.deliveredAt.slice(0, 10) : "",
      trackingNumbers: shipment?.trackingNumbers?.join("\n") ?? "",
      notes: shipment?.notes ?? "",
      statusEntryId: shipment?.statusEntryId ?? "",
      documentStatusEntryId: "",
      lineStatusEntryId: "",
      postComment: true,
      addShippingAdjustment: !shipment,
      items: lines.reduce((acc, line) => {
        const found = shipment?.items.find((item) => item.orderLineId === line.id);
        acc[line.id] = found ? String(found.quantity) : "";
        return acc;
      }, baseItems),
      ...extractCustomFieldValues(shipment)
    }),
    [
      baseItems,
      lines,
      mode,
      preferredAddressId,
      shipment?.carrierName,
      shipment?.customValues,
      shipment?.deliveredAt,
      shipment?.items,
      shipment?.metadata,
      shipment?.notes,
      shipment?.shipmentNumber,
      shipment?.shippedAt,
      shipment?.shippingMethodId,
      shipment?.statusEntryId,
      shipment?.trackingNumbers,
      shippingAddressSnapshot,
      shipmentAddressSnapshot
    ]
  );
  const addressOptionsMap = React.useMemo(() => {
    const map = /* @__PURE__ */ new Map();
    addressOptions.forEach((option) => map.set(option.id, option));
    return map;
  }, [addressOptions]);
  const registerItemErrors = React.useCallback((updater) => {
    itemErrorSetterRef.current = updater;
  }, []);
  const clearItemErrors = React.useCallback(() => {
    itemErrorSetterRef.current?.({});
  }, []);
  const ensureShippingMethodOption = React.useCallback(
    (option) => {
      if (!option) return;
      setShippingMethods((prev) => {
        if (prev.some((entry) => entry.id === option.id)) return prev;
        return [...prev, option];
      });
    },
    []
  );
  const mapDocumentAddressOption = React.useCallback(
    (item) => {
      const snapshot = normalizeAddressSnapshot({
        documentAddressId: readStringField(item, ["id"]),
        customerAddressId: readStringField(item, ["customer_address_id", "customerAddressId"]),
        name: readStringField(item, ["name"]),
        purpose: readStringField(item, ["purpose"]),
        companyName: readStringField(item, ["company_name", "companyName"]),
        addressLine1: readStringField(item, ["address_line1", "addressLine1"]),
        addressLine2: readStringField(item, ["address_line2", "addressLine2"]),
        buildingNumber: readStringField(item, ["building_number", "buildingNumber"]),
        flatNumber: readStringField(item, ["flat_number", "flatNumber"]),
        city: readStringField(item, ["city"]),
        region: readStringField(item, ["region"]),
        postalCode: readStringField(item, ["postal_code", "postalCode"]),
        country: readStringField(item, ["country"])
      });
      if (!snapshot) return null;
      const label = snapshot.name ?? snapshot.purpose ?? t("sales.documents.shipments.addressFallback", "Document address");
      const id = readStringField(item, ["id"]) ?? readStringField(item, ["customer_address_id", "customerAddressId"]) ?? void 0;
      return buildAddressOption(snapshot, { id, label });
    },
    [t]
  );
  const mergeAddressOptions = React.useCallback(
    (options) => setAddressOptions((prev) => {
      const next = dedupeAddressOptions([...prev, ...options]);
      return next.length === prev.length ? prev : next;
    }),
    []
  );
  const loadAddressOptions = React.useCallback(async () => {
    setAddressLoading(true);
    try {
      const params = new URLSearchParams({
        page: "1",
        pageSize: "100",
        documentId: orderId,
        documentKind: "order"
      });
      const response = await apiCall(
        `/api/sales/document-addresses?${params.toString()}`,
        void 0,
        { fallback: { items: [] } }
      );
      const items = Array.isArray(response.result?.items) ? response.result.items : [];
      const mapped = items.map((item) => mapDocumentAddressOption(item)).filter((entry) => Boolean(entry));
      mergeAddressOptions(mapped);
      setAddressError(null);
      return mapped;
    } catch (err) {
      logger.error("sales.shipments.addresses.load", { err });
      setAddressError(
        t("sales.documents.shipments.addressLoadError", "Failed to load addresses.")
      );
      return [];
    } finally {
      setAddressLoading(false);
    }
  }, [mapDocumentAddressOption, mergeAddressOptions, orderId, t]);
  const buildPriceSubtitle = React.useCallback(
    (option) => {
      const currency = option.currencyCode ?? currencyCode ?? void 0;
      const parts = [];
      if (option.avgPrice !== null) {
        parts.push(
          t("sales.documents.shipments.shippingMethodAvg", "Avg {{price}}", {
            price: formatMoney(option.avgPrice, currency ?? null)
          })
        );
      }
      if (option.minPrice !== null) {
        parts.push(
          t("sales.documents.shipments.shippingMethodMin", "Min {{price}}", {
            price: formatMoney(option.minPrice, currency ?? null)
          })
        );
      }
      if (parts.length === 0) return void 0;
      return parts.join(" \xB7 ");
    },
    [currencyCode, t]
  );
  const mapShippingMethod = React.useCallback(
    (item) => {
      const id = typeof item.id === "string" ? item.id : null;
      const name = typeof item.name === "string" ? item.name : null;
      const code = typeof item.code === "string" ? item.code : null;
      if (!id || !name) return null;
      const baseRateNet = normalizePrice(item.baseRateNet ?? item.base_rate_net);
      const baseRateGross = normalizePrice(item.baseRateGross ?? item.base_rate_gross);
      const prices = [baseRateNet, baseRateGross].filter((value) => Number.isFinite(value));
      const minPrice = prices.length ? Math.min(...prices) : null;
      const avgPrice = prices.length ? prices.reduce((acc, value) => acc + value, 0) / prices.length : null;
      return {
        id,
        name,
        code: code ?? id,
        currencyCode: typeof item.currencyCode === "string" ? item.currencyCode : null,
        baseRateNet,
        baseRateGross,
        minPrice,
        avgPrice
      };
    },
    []
  );
  const loadShippingMethods = React.useCallback(
    async (query, opts) => {
      const applyLoadingState = opts?.applyLoadingState !== false;
      if (applyLoadingState) setShippingMethodLoading(true);
      try {
        const params = new URLSearchParams({ page: "1", pageSize: "50" });
        if (query && query.trim().length) params.set("search", query.trim());
        const response = await apiCall(
          `/api/sales/shipping-methods?${params.toString()}`,
          void 0,
          { fallback: { items: [] } }
        );
        const items = Array.isArray(response.result?.items) ? response.result.items : [];
        const options = items.map((item) => mapShippingMethod(item)).filter((entry) => !!entry);
        if (!query) {
          setShippingMethods(
            (current) => current.reduce(
              (next, selected) => mergeShippingMethodOptions(next, selected),
              options
            )
          );
        }
        return options;
      } catch (err) {
        logger.error("sales.shipments.shipping-methods.load", { err });
        return [];
      } finally {
        if (applyLoadingState) setShippingMethodLoading(false);
      }
    },
    [mapShippingMethod]
  );
  const fetchShippingMethodItems = React.useCallback(
    async (query) => {
      if (!query || !query.trim()) {
        const options2 = shippingMethods.length > 0 ? shippingMethods : await loadShippingMethods(void 0, { applyLoadingState: true });
        return options2.map((option) => ({
          id: option.id,
          title: option.name,
          subtitle: [option.code, buildPriceSubtitle(option)].filter(Boolean).join(" \u2022 ") || void 0,
          icon: /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Truck, { className: "h-4 w-4" }) })
        }));
      }
      const options = await loadShippingMethods(query, { applyLoadingState: false });
      const needle = query?.trim().toLowerCase() ?? "";
      const filtered = options.filter(
        (opt) => !needle || opt.name.toLowerCase().includes(needle) || opt.code.toLowerCase().includes(needle)
      );
      return filtered.map((option) => ({
        id: option.id,
        title: option.name,
        subtitle: [option.code, buildPriceSubtitle(option)].filter(Boolean).join(" \u2022 ") || void 0,
        icon: /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Truck, { className: "h-4 w-4" }) })
      }));
    },
    [buildPriceSubtitle, loadShippingMethods, shippingMethods]
  );
  const renderStatusIcon = React.useCallback(
    (color) => /* @__PURE__ */ jsx(
      "span",
      {
        className: "h-2.5 w-2.5 rounded-full border border-border/70",
        style: color ? { backgroundColor: color, borderColor: color } : void 0
      }
    ),
    []
  );
  const shippingMethodLookupOptions = React.useMemo(
    () => shippingMethods.map((option) => ({
      id: option.id,
      title: option.name,
      subtitle: [option.code, buildPriceSubtitle(option)].filter(Boolean).join(" \u2022 ") || void 0,
      icon: /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Truck, { className: "h-4 w-4" }) })
    })),
    [buildPriceSubtitle, shippingMethods]
  );
  const loadDocumentStatuses = React.useCallback(async () => {
    setDocumentStatusLoading(true);
    try {
      const params = new URLSearchParams({ page: "1", pageSize: "100" });
      const response = await apiCall(
        `/api/sales/order-statuses?${params.toString()}`,
        void 0,
        { fallback: { items: [] } }
      );
      const items = Array.isArray(response.result?.items) ? response.result.items : [];
      const mapped = items.map((entry) => {
        const id = typeof entry.id === "string" ? entry.id : null;
        const value = typeof entry.value === "string" ? entry.value : null;
        if (!id || !value) return null;
        const label = typeof entry.label === "string" && entry.label.trim().length ? entry.label : value;
        const color = typeof entry.color === "string" && entry.color.trim().length ? entry.color : null;
        return { id, value, label, color };
      }).filter((entry) => Boolean(entry));
      setDocumentStatuses(mapped);
      return mapped;
    } catch (err) {
      logger.error("sales.shipments.statuses.load", { err });
      setDocumentStatuses([]);
      return [];
    } finally {
      setDocumentStatusLoading(false);
    }
  }, []);
  const loadLineStatuses = React.useCallback(async () => {
    setLineStatusLoading(true);
    try {
      const params = new URLSearchParams({ page: "1", pageSize: "100" });
      const response = await apiCall(
        `/api/sales/order-line-statuses?${params.toString()}`,
        void 0,
        { fallback: { items: [] } }
      );
      const items = Array.isArray(response.result?.items) ? response.result.items : [];
      const mapped = items.map((entry) => {
        const id = typeof entry.id === "string" ? entry.id : null;
        const value = typeof entry.value === "string" ? entry.value : null;
        if (!id || !value) return null;
        const label = typeof entry.label === "string" && entry.label.trim().length ? entry.label : value;
        const color = typeof entry.color === "string" && entry.color.trim().length ? entry.color : null;
        return { id, value, label, color };
      }).filter((entry) => Boolean(entry));
      setLineStatuses(mapped);
      return mapped;
    } catch (err) {
      logger.error("sales.shipments.line-statuses.load", { err });
      setLineStatuses([]);
      return [];
    } finally {
      setLineStatusLoading(false);
    }
  }, []);
  const loadShipmentStatuses = React.useCallback(async () => {
    setShipmentStatusLoading(true);
    try {
      const params = new URLSearchParams({ page: "1", pageSize: "100" });
      const response = await apiCall(
        `/api/sales/shipment-statuses?${params.toString()}`,
        void 0,
        { fallback: { items: [] } }
      );
      const items = Array.isArray(response.result?.items) ? response.result.items : [];
      const mapped = items.map((entry) => mapStatusOption(entry)).filter((entry) => Boolean(entry));
      setShipmentStatuses(
        (current) => current.reduce(
          (next, selected) => mergeStatusOptions(next, selected),
          mapped
        )
      );
      return mapped;
    } catch (err) {
      logger.error("sales.shipments.statuses.load", { err });
      setShipmentStatuses([]);
      return [];
    } finally {
      setShipmentStatusLoading(false);
    }
  }, []);
  const loadShipmentStatusById = React.useCallback(async (statusEntryId) => {
    const response = await apiCall(
      `/api/sales/shipment-statuses?id=${encodeURIComponent(statusEntryId)}&pageSize=1`,
      void 0,
      { fallback: { items: [] } }
    );
    const items = Array.isArray(response.result?.items) ? response.result.items : [];
    return items.map((entry) => mapStatusOption(entry)).find((entry) => entry?.id === statusEntryId) ?? null;
  }, []);
  const fetchDocumentStatusItems = React.useCallback(
    async (query) => {
      const options = documentStatuses.length && !query ? documentStatuses : await loadDocumentStatuses();
      const term = query?.trim().toLowerCase() ?? "";
      return options.filter(
        (option) => !term.length || option.label.toLowerCase().includes(term) || option.value.toLowerCase().includes(term)
      ).map((option) => ({
        id: option.id,
        title: option.label,
        subtitle: option.value,
        icon: renderStatusIcon(option.color)
      }));
    },
    [documentStatuses, loadDocumentStatuses, renderStatusIcon]
  );
  const fetchLineStatusItems = React.useCallback(
    async (query) => {
      const options = lineStatuses.length && !query ? lineStatuses : await loadLineStatuses();
      const term = query?.trim().toLowerCase() ?? "";
      return options.filter(
        (option) => !term.length || option.label.toLowerCase().includes(term) || option.value.toLowerCase().includes(term)
      ).map((option) => ({
        id: option.id,
        title: option.label,
        subtitle: option.value,
        icon: renderStatusIcon(option.color)
      }));
    },
    [lineStatuses, loadLineStatuses, renderStatusIcon]
  );
  const fetchShipmentStatusItems = React.useCallback(
    async (query) => {
      const options = shipmentStatuses.length && !query ? shipmentStatuses : await loadShipmentStatuses();
      const term = query?.trim().toLowerCase() ?? "";
      return options.filter(
        (option) => !term.length || option.label.toLowerCase().includes(term) || option.value.toLowerCase().includes(term)
      ).map((option) => ({
        id: option.id,
        title: option.label,
        subtitle: option.value,
        icon: renderStatusIcon(option.color)
      }));
    },
    [loadShipmentStatuses, renderStatusIcon, shipmentStatuses]
  );
  const shipmentStatusLookupOptions = React.useMemo(
    () => shipmentStatuses.map((option) => ({
      id: option.id,
      title: option.label,
      subtitle: option.value,
      icon: renderStatusIcon(option.color)
    })),
    [renderStatusIcon, shipmentStatuses]
  );
  React.useEffect(() => {
    if (!open) return;
    setFormResetKey((prev) => prev + 1);
    if (!shippingMethods.length) {
      void loadShippingMethods();
    }
    setAddressOptions(baseAddressOptions);
    setAddressError(null);
    if (!addressOptions.length) {
      void loadAddressOptions();
    }
    if (!shipmentStatuses.length) {
      void loadShipmentStatuses();
    }
    if (!documentStatuses.length && mode === "create") {
      void loadDocumentStatuses();
    }
    if (!lineStatuses.length && mode === "create") {
      void loadLineStatuses();
    }
  }, [
    addressOptions.length,
    baseAddressOptions,
    documentStatuses.length,
    loadAddressOptions,
    loadDocumentStatuses,
    loadShipmentStatuses,
    loadLineStatuses,
    loadShippingMethods,
    mode,
    open,
    lineStatuses.length,
    shipmentStatuses.length,
    shippingMethods.length
  ]);
  React.useEffect(() => {
    if (shipment?.shippingMethodId) {
      ensureShippingMethodOption(
        mapShippingMethod({
          id: shipment.shippingMethodId,
          name: shipment.shippingMethodName ?? shipment.shippingMethodCode ?? shipment.shippingMethodId,
          code: shipment.shippingMethodCode ?? shipment.shippingMethodId,
          currencyCode: currencyCode ?? null
        })
      );
    }
  }, [
    currencyCode,
    ensureShippingMethodOption,
    mapShippingMethod,
    shipment?.shippingMethodCode,
    shipment?.shippingMethodId,
    shipment?.shippingMethodName
  ]);
  React.useEffect(() => {
    const statusEntryId = shipment?.statusEntryId;
    if (!statusEntryId || shipmentStatuses.some((status) => status.id === statusEntryId)) return;
    const fallback = shipment.status || shipment.statusLabel ? {
      id: statusEntryId,
      value: shipment.status ?? statusEntryId,
      label: shipment.statusLabel ?? shipment.status ?? statusEntryId,
      color: null
    } : null;
    setShipmentStatuses((current) => mergeStatusOptions(current, fallback));
    loadShipmentStatusById(statusEntryId).then((selected) => {
      setShipmentStatuses((current) => mergeStatusOptions(current, selected));
    }).catch(() => {
    });
  }, [
    loadShipmentStatusById,
    shipment?.status,
    shipment?.statusEntryId,
    shipment?.statusLabel,
    shipmentStatuses
  ]);
  React.useEffect(() => {
    if (!open) return;
    mergeAddressOptions(baseAddressOptions);
  }, [baseAddressOptions, mergeAddressOptions, open]);
  const fetchAddressItems = React.useCallback(
    async (query) => {
      if (!addressOptions.length && !addressLoading) {
        await loadAddressOptions();
      }
      const needle = query?.trim().toLowerCase() ?? "";
      return addressOptions.filter((option) => {
        if (!needle) return true;
        return option.label.toLowerCase().includes(needle) || option.summary.toLowerCase().includes(needle);
      }).map((option) => ({
        id: option.id,
        title: option.label,
        subtitle: option.summary,
        icon: /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }) })
      }));
    },
    [addressLoading, addressOptions, loadAddressOptions]
  );
  const validateItems = React.useCallback(
    (itemsValue) => {
      const entries = Object.entries(itemsValue ?? {}).map(([lineId, value]) => ({ lineId, quantity: Number(value) })).filter((entry) => Number.isFinite(entry.quantity) && entry.quantity > 0);
      if (!entries.length) {
        clearItemErrors();
        throw createCrudFormError(
          t("sales.documents.shipments.errorItems", "Ship at least one line item."),
          { items: t("sales.documents.shipments.errorItems", "Ship at least one line item.") }
        );
      }
      const errors = {};
      entries.forEach((entry) => {
        const available = computeAvailable(entry.lineId, shipment?.id ?? null);
        if (entry.quantity > available + 1e-6) {
          errors[entry.lineId] = t("sales.documents.shipments.errorQuantity", "Quantity exceeds remaining available.");
        }
      });
      if (Object.keys(errors).length) {
        itemErrorSetterRef.current?.(errors);
        throw createCrudFormError(
          t("sales.documents.shipments.errorQuantity", "Quantity exceeds remaining available."),
          { items: t("sales.documents.shipments.errorQuantity", "Quantity exceeds remaining available.") }
        );
      }
      clearItemErrors();
      return entries;
    },
    [clearItemErrors, computeAvailable, shipment?.id, t]
  );
  const handleSubmit = React.useCallback(
    async (values) => {
      const shipmentNumber = typeof values.shipmentNumber === "string" ? values.shipmentNumber.trim() : "";
      if (!shipmentNumber.length) {
        throw createCrudFormError(
          t("sales.documents.shipments.errorNumber", "Shipment number is required."),
          { shipmentNumber: t("sales.documents.shipments.errorNumber", "Shipment number is required.") }
        );
      }
      const shippingMethodId = typeof values.shippingMethodId === "string" && values.shippingMethodId.trim().length ? values.shippingMethodId : "";
      if (!shippingMethodId) {
        throw createCrudFormError(
          t("sales.documents.shipments.errorShippingMethod", "Select a shipping method."),
          { shippingMethodId: t("sales.documents.shipments.errorShippingMethod", "Select a shipping method.") }
        );
      }
      const items = validateItems(values.items);
      const shipmentAddressId = typeof values.shipmentAddressId === "string" ? values.shipmentAddressId : "";
      const addressOption = shipmentAddressId ? addressOptionsMap.get(shipmentAddressId) ?? null : null;
      const fallbackAddress = addressOptions.length === 1 ? addressOptions[0] : null;
      const addressSnapshot = addressOption?.snapshot ?? fallbackAddress?.snapshot ?? null;
      if (!addressSnapshot) {
        const message = addressOptions.length ? t("sales.documents.shipments.errorAddress", "Select an address to ship to.") : t(
          "sales.documents.shipments.addressMissing",
          "Add an address to this document before creating a shipment."
        );
        throw createCrudFormError(message, { shipmentAddressId: message });
      }
      const payload = {
        orderId,
        organizationId: organizationId ?? void 0,
        tenantId: tenantId ?? void 0,
        shipmentNumber,
        shippingMethodId,
        statusEntryId: typeof values.statusEntryId === "string" && values.statusEntryId.trim().length ? values.statusEntryId : void 0,
        carrierName: typeof values.carrierName === "string" && values.carrierName.trim().length ? values.carrierName.trim() : void 0,
        trackingNumbers: parseTrackingNumbers(
          typeof values.trackingNumbers === "string" ? values.trackingNumbers : ""
        ),
        shippedAt: typeof values.shippedAt === "string" && values.shippedAt.trim().length ? new Date(values.shippedAt) : void 0,
        deliveredAt: typeof values.deliveredAt === "string" && values.deliveredAt.trim().length ? new Date(values.deliveredAt) : void 0,
        notes: typeof values.notes === "string" && values.notes.trim().length ? values.notes.trim() : void 0,
        items: items.map((item) => ({
          orderLineId: item.lineId,
          quantity: item.quantity
        }))
      };
      payload.shipmentAddressSnapshot = addressSnapshot;
      const customFields = collectCustomFieldValues(values, { transform: normalizeCustomFieldSubmitValue });
      if (Object.keys(customFields).length) {
        payload.customFields = customFields;
      }
      if (mode === "create") {
        const documentStatusEntryId = typeof values.documentStatusEntryId === "string" && values.documentStatusEntryId.trim().length ? values.documentStatusEntryId : null;
        const lineStatusEntryId = typeof values.lineStatusEntryId === "string" && values.lineStatusEntryId.trim().length ? values.lineStatusEntryId : null;
        if (documentStatusEntryId) {
          payload.documentStatusEntryId = documentStatusEntryId;
        }
        if (lineStatusEntryId) {
          payload.lineStatusEntryId = lineStatusEntryId;
        }
      }
      const action = shipment?.id ? updateCrud : createCrud;
      let result;
      try {
        result = await withScopedApiRequestHeaders(
          // The server guards the PARENT order's aggregate version (Gap B) for
          // both create and update, so send the order's `updated_at`.
          buildOptimisticLockHeader(documentUpdatedAt ?? void 0),
          () => action(
            "sales/shipments",
            shipment?.id ? { id: shipment.id, ...payload } : payload,
            {
              errorMessage: t("sales.documents.shipments.errorSave", "Failed to save shipment.")
            }
          )
        );
      } catch (err) {
        if (handleSectionMutationError(err, t, () => void onSaved())) {
          return;
        }
        throw err;
      }
      if (result.ok) {
        const shipmentId = result.result?.id ?? shipment?.id ?? null;
        const shouldAddShippingAdjustment = mode === "create" && Boolean(values.addShippingAdjustment) && shipmentId;
        if (shouldAddShippingAdjustment) {
          const method = shippingMethods.find((entry) => entry.id === shippingMethodId) ?? null;
          const totalQuantity = items.reduce((acc, item) => acc + item.quantity, 0);
          const unitGross = method?.baseRateGross ?? method?.avgPrice ?? method?.minPrice ?? (method?.baseRateNet ?? null);
          const unitNet = method?.baseRateNet ?? null;
          const amountGross = typeof unitGross === "number" && Number.isFinite(unitGross) && totalQuantity > 0 ? roundAmount(Math.max(unitGross * totalQuantity, 0)) : null;
          const amountNet = typeof unitNet === "number" && Number.isFinite(unitNet) && totalQuantity > 0 ? roundAmount(Math.max(unitNet * totalQuantity, 0)) : null;
          const currency = typeof method?.currencyCode === "string" && method.currencyCode.trim().length ? method.currencyCode.trim().toUpperCase() : typeof currencyCode === "string" && currencyCode.trim().length ? currencyCode.trim().toUpperCase() : null;
          if (amountGross !== null || amountNet !== null) {
            try {
              await createCrud(
                "sales/order-adjustments",
                {
                  orderId,
                  organizationId: organizationId ?? void 0,
                  tenantId: tenantId ?? void 0,
                  scope: "order",
                  kind: "shipping",
                  label: method?.name ?? t("sales.documents.shipments.shippingAdjustmentLabel", "Shipping cost"),
                  code: shipmentNumber ? `ship-${shipmentNumber}` : void 0,
                  amountGross: amountGross ?? void 0,
                  amountNet: amountNet ?? void 0,
                  currencyCode: currency ?? void 0,
                  metadata: {
                    shipmentId,
                    shippingMethodId,
                    calculation: "per_item_base_rate",
                    quantity: totalQuantity
                  }
                },
                {
                  errorMessage: t(
                    "sales.documents.shipments.shippingAdjustmentError",
                    "Failed to add shipping cost adjustment."
                  )
                }
              );
              emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: "order" });
            } catch (err) {
              logger.warn("sales.shipments.adjustment.create", { err });
              flash(
                t(
                  "sales.documents.shipments.shippingAdjustmentError",
                  "Failed to add shipping cost adjustment."
                ),
                "warning"
              );
            }
          }
        }
        if (values.postComment && onAddComment) {
          const lineTitles = items.map((item) => {
            const line = lines.find((entry) => entry.id === item.lineId);
            return `${item.quantity}\xD7 ${line?.title ?? item.lineId}`;
          }).join(", ");
          const commentNotes = typeof values.notes === "string" && values.notes.trim().length ? values.notes.trim() : "";
          const label = shipmentNumber.length > 0 ? `#${shipmentNumber}` : shipment?.id ? `#${shipment.id.slice(0, 6)}` : "";
          const noteParts = [
            t("sales.documents.shipments.comment", "Shipment {{number}} updated: {{summary}}", {
              number: label || String(result.result?.id ?? ""),
              summary: lineTitles
            })
          ];
          if (commentNotes) {
            noteParts.push(
              t("sales.documents.shipments.commentNotes", "Notes: {{notes}}", { notes: commentNotes })
            );
          }
          const note = noteParts.join("\n\n");
          try {
            await onAddComment(note);
          } catch (err) {
            logger.warn("sales.shipments.comment", { err });
          }
        }
        await onSaved();
      }
    },
    [
      currencyCode,
      documentUpdatedAt,
      lines,
      mode,
      onAddComment,
      onSaved,
      orderId,
      organizationId,
      shipment?.id,
      addressOptions,
      addressOptionsMap,
      shippingMethods,
      t,
      tenantId,
      validateItems
    ]
  );
  const handleSubmitForm = React.useCallback(
    () => dialogContentRef.current?.querySelector("form")?.requestSubmit(),
    []
  );
  const handleKeyDown = useDialogKeyHandler({
    onConfirm: handleSubmitForm,
    onCancel: onClose
  });
  const fields = React.useMemo(() => {
    const shippingAdjustmentLabel = t(
      "sales.documents.shipments.addShippingAdjustment",
      "Add shipping cost adjustment for this shipment"
    );
    const shippingAdjustmentHelp = t(
      "sales.documents.shipments.addShippingAdjustmentHelp",
      "Create a shipping adjustment using this carrier\u2019s calculated cost."
    );
    function ShipmentItemsField({ value, setValue }) {
      const quantities = value ?? {};
      const [lineErrors, setLineErrors] = React.useState({});
      React.useEffect(() => {
        registerItemErrors(setLineErrors);
        return () => {
          if (itemErrorSetterRef.current === setLineErrors) {
            itemErrorSetterRef.current = null;
          }
        };
      }, []);
      if (lines.length === 0) {
        return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("sales.documents.shipments.noLines", "No order lines available.") });
      }
      return /* @__PURE__ */ jsx("div", { className: "space-y-2 rounded-lg border p-3", children: lines.map((line) => {
        const available = computeAvailable(line.id, shipment?.id ?? null);
        const rawValue = quantities[line.id];
        const valueString = typeof rawValue === "number" ? rawValue.toString() : typeof rawValue === "string" ? rawValue : "";
        const disabled = available <= 0 && !valueString;
        const lineError = lineErrors[line.id];
        return /* @__PURE__ */ jsxs(
          "div",
          {
            className: cn(
              "grid gap-3 md:grid-cols-[1fr,140px]",
              disabled ? "opacity-60" : null
            ),
            children: [
              /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
                line.thumbnail ? /* @__PURE__ */ jsx(
                  "img",
                  {
                    src: line.thumbnail,
                    alt: line.title,
                    className: "h-12 w-12 rounded-md border object-cover"
                  }
                ) : /* @__PURE__ */ jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-md border bg-muted text-xs text-muted-foreground", children: "N/A" }),
                /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
                  /* @__PURE__ */ jsxs("p", { className: "text-sm font-medium", children: [
                    line.lineNumber ? `#${line.lineNumber} \xB7 ` : null,
                    line.title
                  ] }),
                  /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.documents.shipments.available", "{{count}} available", {
                    count: available
                  }) })
                ] })
              ] }),
              /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
                /* @__PURE__ */ jsx(
                  Input,
                  {
                    type: "number",
                    step: "1",
                    min: "0",
                    value: valueString,
                    disabled,
                    onChange: (event) => {
                      const next = event.target.value;
                      setValue({ ...quantities ?? {}, [line.id]: next });
                      setLineErrors((prev) => ({ ...prev, [line.id]: void 0 }));
                    }
                  }
                ),
                lineError ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: lineError }) : null
              ] })
            ]
          },
          line.id
        );
      }) });
    }
    function ShipmentAddressField({ value, setValue }) {
      const currentValue = typeof value === "string" ? value : "";
      React.useEffect(() => {
        if (!currentValue && addressOptions.length) {
          setValue(addressOptions[0].id);
        }
      }, [addressOptions, currentValue, setValue]);
      const disabled = addressLoading || !addressOptions.length;
      return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
        /* @__PURE__ */ jsx(
          LookupSelect,
          {
            value: currentValue || null,
            onChange: (next) => setValue(next ?? ""),
            fetchItems: fetchAddressItems,
            placeholder: t("sales.documents.shipments.addressPlaceholder", "Select address"),
            searchPlaceholder: t("sales.documents.shipments.addressSearch", "Search address"),
            minQuery: 0,
            disabled,
            loading: addressLoading,
            defaultOpen: true
          }
        ),
        !addressLoading && !addressOptions.length ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: t(
          "sales.documents.shipments.addressMissing",
          "Add an address to this document before creating a shipment."
        ) }) : null,
        addressError ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: addressError }) : null
      ] });
    }
    const itemsField = {
      id: "items",
      label: t("sales.documents.shipments.items", "Items to ship"),
      type: "custom",
      component: ShipmentItemsField
    };
    return [
      {
        id: "shipmentNumber",
        label: t("sales.documents.shipments.number", "Shipment number"),
        type: "custom",
        required: true,
        component: ({ value, setValue }) => /* @__PURE__ */ jsx(
          Input,
          {
            value: typeof value === "string" ? value : "",
            onChange: (event) => setValue(event.target.value)
          }
        )
      },
      {
        id: "carrierName",
        label: t("sales.documents.shipments.carrier", "Carrier"),
        type: "custom",
        component: ({ value, setValue }) => /* @__PURE__ */ jsx(
          Input,
          {
            value: typeof value === "string" ? value : "",
            onChange: (event) => setValue(event.target.value)
          }
        )
      },
      {
        id: "shippingMethodId",
        label: t("sales.documents.shipments.shippingMethod", "Shipping method"),
        type: "custom",
        required: true,
        component: ({ value, setValue }) => {
          const currentValue = typeof value === "string" && value.length ? value : null;
          return /* @__PURE__ */ jsx(
            LookupSelect,
            {
              value: currentValue,
              onChange: (next) => setValue(next ?? ""),
              fetchItems: fetchShippingMethodItems,
              options: shippingMethodLookupOptions,
              placeholder: t("sales.documents.shipments.shippingMethodPlaceholder", "Select method"),
              loading: shippingMethodLoading,
              minQuery: 0
            }
          );
        }
      },
      {
        id: "statusEntryId",
        label: t("sales.documents.shipments.status", "Shipment status"),
        type: "custom",
        component: ({ value, setValue }) => {
          const currentValue = typeof value === "string" && value.length ? value : null;
          return /* @__PURE__ */ jsx(
            LookupSelect,
            {
              value: currentValue,
              onChange: (next) => setValue(next ?? ""),
              fetchItems: fetchShipmentStatusItems,
              options: shipmentStatusLookupOptions,
              placeholder: t("sales.documents.shipments.statusPlaceholder", "Select shipment status"),
              loading: shipmentStatusLoading,
              minQuery: 0
            }
          );
        }
      },
      ...mode === "create" ? [
        {
          id: "documentStatusEntryId",
          label: t("sales.documents.status.changeDocument", "Change order/quote status"),
          type: "custom",
          component: ({ value, setValue }) => {
            const currentValue = typeof value === "string" && value.length ? value : null;
            return /* @__PURE__ */ jsx(
              LookupSelect,
              {
                value: currentValue,
                onChange: (next) => setValue(next ?? ""),
                fetchItems: fetchDocumentStatusItems,
                placeholder: t(
                  "sales.documents.status.documentPlaceholder",
                  "Select new order/quote status"
                ),
                loading: documentStatusLoading,
                minQuery: 0
              }
            );
          }
        },
        {
          id: "lineStatusEntryId",
          label: t("sales.documents.status.changeLine", "Change order/quote item status"),
          type: "custom",
          component: ({ value, setValue }) => {
            const currentValue = typeof value === "string" && value.length ? value : null;
            return /* @__PURE__ */ jsx(
              LookupSelect,
              {
                value: currentValue,
                onChange: (next) => setValue(next ?? ""),
                fetchItems: fetchLineStatusItems,
                placeholder: t(
                  "sales.documents.status.linePlaceholder",
                  "Select item status"
                ),
                loading: lineStatusLoading,
                minQuery: 0
              }
            );
          }
        }
      ] : [],
      {
        id: "shipmentAddressId",
        label: t("sales.documents.shipments.address", "Ship to"),
        type: "custom",
        required: true,
        component: ShipmentAddressField
      },
      {
        id: "shippedAt",
        label: t("sales.documents.shipments.shippedAt", "Shipped date"),
        type: "date"
      },
      {
        id: "deliveredAt",
        label: t("sales.documents.shipments.deliveredAt", "Delivered date"),
        type: "date"
      },
      {
        id: "trackingNumbers",
        label: t("sales.documents.shipments.trackingNumbers", "Tracking numbers"),
        type: "custom",
        component: ({ value, setValue }) => /* @__PURE__ */ jsx(
          Textarea,
          {
            rows: 2,
            placeholder: t(
              "sales.documents.shipments.trackingPlaceholder",
              "One per line or comma separated"
            ),
            value: typeof value === "string" ? value : "",
            onChange: (event) => setValue(event.target.value)
          }
        )
      },
      {
        id: "notes",
        label: t("sales.documents.shipments.notes", "Notes"),
        type: "custom",
        component: ({ value, setValue }) => /* @__PURE__ */ jsx(
          Textarea,
          {
            rows: 3,
            value: typeof value === "string" ? value : "",
            onChange: (event) => setValue(event.target.value)
          }
        )
      },
      {
        id: "addShippingAdjustment",
        label: shippingAdjustmentLabel,
        type: "custom",
        component: ({ value, setValue }) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
          /* @__PURE__ */ jsx(
            Switch,
            {
              id: SHIPPING_ADJUSTMENT_TOGGLE_ID,
              checked: Boolean(value),
              onCheckedChange: (checked) => setValue(Boolean(checked)),
              "aria-labelledby": SHIPPING_ADJUSTMENT_LABEL_ID,
              "aria-describedby": SHIPPING_ADJUSTMENT_HELP_ID
            }
          ),
          /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
            /* @__PURE__ */ jsx(
              Label,
              {
                htmlFor: SHIPPING_ADJUSTMENT_TOGGLE_ID,
                id: SHIPPING_ADJUSTMENT_LABEL_ID,
                className: "sr-only",
                children: shippingAdjustmentLabel
              }
            ),
            /* @__PURE__ */ jsx("p", { id: SHIPPING_ADJUSTMENT_HELP_ID, className: "text-xs text-muted-foreground", children: shippingAdjustmentHelp })
          ] })
        ] })
      },
      itemsField,
      {
        id: "postComment",
        label: t("sales.documents.shipments.addComment", "Add note to comments"),
        type: "custom",
        component: ({ value, setValue }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
          /* @__PURE__ */ jsx(
            Switch,
            {
              id: "shipment-comment",
              checked: Boolean(value),
              onCheckedChange: (checked) => setValue(Boolean(checked))
            }
          ),
          /* @__PURE__ */ jsx(Label, { htmlFor: "shipment-comment", className: "cursor-pointer", children: t("sales.documents.shipments.addComment", "Add note to comments") })
        ] })
      }
    ];
  }, [
    addressError,
    addressLoading,
    addressOptions,
    computeAvailable,
    documentStatusLoading,
    fetchAddressItems,
    fetchDocumentStatusItems,
    fetchLineStatusItems,
    fetchShipmentStatusItems,
    fetchShippingMethodItems,
    lineStatusLoading,
    lines,
    mode,
    registerItemErrors,
    shipment?.id,
    shipmentStatusLoading,
    t
  ]);
  const groups = React.useMemo(
    () => {
      const base = [
        {
          id: "shipmentDetails",
          title: mode === "edit" ? t("sales.documents.shipments.editTitle", "Edit shipment") : t("sales.documents.shipments.addTitle", "Add shipment"),
          column: 1,
          fields: ["shipmentNumber", "carrierName", "shippingMethodId", "statusEntryId", "shipmentAddressId"]
        }
      ];
      if (mode === "create") {
        base.push({
          id: "statusChanges",
          title: t("sales.documents.status.sectionTitle", "Status changes"),
          column: 2,
          fields: ["documentStatusEntryId", "lineStatusEntryId"]
        });
      }
      base.push(
        {
          id: "tracking",
          title: t("sales.documents.shipments.trackingGroup", "Tracking information"),
          column: 2,
          fields: ["shippedAt", "deliveredAt", "trackingNumbers", "notes"]
        },
        {
          id: "items",
          column: 1,
          fields: ["items", "addShippingAdjustment", "postComment"]
        },
        {
          id: "shipmentCustomFields",
          title: t("entities.customFields.title", "Custom fields"),
          column: 2,
          kind: "customFields"
        }
      );
      return base;
    },
    [mode, t]
  );
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next ? onClose() : void 0, children: /* @__PURE__ */ jsxs(
    DialogContent,
    {
      ref: dialogContentRef,
      className: "sm:max-w-5xl",
      onKeyDown: handleKeyDown,
      children: [
        /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: mode === "edit" ? t("sales.documents.shipments.editTitle", "Edit shipment") : t("sales.documents.shipments.addTitle", "Add shipment") }) }),
        /* @__PURE__ */ jsx(
          CrudForm,
          {
            embedded: true,
            entityId: E.sales.sales_shipment,
            fields,
            groups,
            initialValues,
            submitLabel: t("sales.documents.shipments.saveShortcut", "Save (\u2318/Ctrl+Enter)"),
            onSubmit: handleSubmit,
            loadingMessage: t("sales.documents.shipments.loading", "Loading shipments\u2026"),
            customFieldsLoadingMessage: t("ui.forms.loading", "Loading data..."),
            isLoading: shippingMethodLoading || addressLoading
          },
          formResetKey
        )
      ]
    }
  ) });
}
export {
  ShipmentDialog
};
//# sourceMappingURL=ShipmentDialog.js.map
