"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
import { createCrud, updateCrud, deleteCrud } from "@open-mercato/ui/backend/utils/crud";
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
import { readApiResultOrThrow, apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader, extractOptimisticLockConflict } from "@open-mercato/ui/backend/utils/optimisticLock";
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { ErrorMessage, RecordNotFoundState } from "@open-mercato/ui/backend/detail";
import { Button } from "@open-mercato/ui/primitives/button";
import { Input } from "@open-mercato/ui/primitives/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from "@open-mercato/ui/primitives/select";
import { Loader2, Search, Image as ImageIcon, Trash2 } from "lucide-react";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { extractCustomFieldEntries } from "@open-mercato/shared/lib/crud/custom-fields-client";
import { E } from "../../../../generated/entities.ids.generated.js";
import { buildAttachmentImageUrl, slugifyAttachmentFileName } from "@open-mercato/core/modules/attachments/lib/imageUrls";
import { cn } from "@open-mercato/shared/lib/utils";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sales");
const UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/;
const MAX_LIST_PAGE_SIZE = 100;
function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }) {
  const t = useT();
  const router = useRouter();
  const [initialValues, setInitialValues] = React.useState(mode === "create" ? {
    channelId: lockedChannelId ?? null,
    productId: null,
    title: "",
    description: "",
    defaultMediaId: null,
    isActive: true,
    priceOverrides: []
  } : null);
  const [loading, setLoading] = React.useState(mode === "edit");
  const [error, setError] = React.useState(null);
  const [isNotFound, setIsNotFound] = React.useState(false);
  const [priceKinds, setPriceKinds] = React.useState([]);
  const [mediaOptions, setMediaOptions] = React.useState([]);
  const attachmentCache = React.useRef(/* @__PURE__ */ new Map());
  const productCache = React.useRef(/* @__PURE__ */ new Map());
  const [productSummary, setProductSummary] = React.useState(null);
  const [variantPreviews, setVariantPreviews] = React.useState([]);
  const variantCache = React.useRef(/* @__PURE__ */ new Map());
  const variantMediaCache = React.useRef(/* @__PURE__ */ new Map());
  const [selectedChannelId, setSelectedChannelId] = React.useState(lockedChannelId ?? null);
  const manualMediaSelections = React.useRef(/* @__PURE__ */ new Set());
  const initialPriceVersionsRef = React.useRef(/* @__PURE__ */ new Map());
  const [currentProductId, setCurrentProductId] = React.useState(null);
  React.useEffect(() => {
    if (initialValues) {
      initialPriceVersionsRef.current = collectPriceVersions(initialValues.priceOverrides);
    } else {
      initialPriceVersionsRef.current = /* @__PURE__ */ new Map();
    }
  }, [initialValues]);
  const channelOffersHref = React.useMemo(
    () => buildChannelOffersHref(lockedChannelId),
    [lockedChannelId]
  );
  React.useEffect(() => {
    if (lockedChannelId) {
      setSelectedChannelId(lockedChannelId);
    } else if (initialValues?.channelId) {
      setSelectedChannelId(initialValues.channelId);
    }
  }, [initialValues?.channelId, lockedChannelId]);
  React.useEffect(() => {
    if (typeof initialValues?.productId === "string") {
      setCurrentProductId(initialValues.productId);
    }
  }, [initialValues?.productId]);
  React.useEffect(() => {
    if (typeof initialValues?.productId === "string" && initialValues?.defaultMediaId === null) {
      manualMediaSelections.current.add(initialValues.productId);
    }
  }, [initialValues?.defaultMediaId, initialValues?.productId]);
  React.useEffect(() => {
    if (mode !== "edit") return;
    const productId = typeof initialValues?.productId === "string" ? initialValues.productId : null;
    if (!productId) return;
    const resolvedProductId = productId;
    const hydrationChannelId = selectedChannelId ?? lockedChannelId ?? (typeof initialValues?.channelId === "string" ? initialValues.channelId : null);
    let cancelled = false;
    async function hydrateExistingProduct() {
      try {
        const [summary, attachments, variants] = await Promise.all([
          resolveProductSummaryWithCache({
            productId: resolvedProductId,
            channelId: hydrationChannelId ?? null,
            productCache
          }),
          resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),
          resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache })
        ]);
        if (!cancelled) {
          setProductSummary(summary ?? null);
          const mergedMedia = buildMediaOptionsFromSources({
            attachments,
            variants,
            summary
          });
          attachmentCache.current.set(resolvedProductId, mergedMedia);
          setMediaOptions(mergedMedia);
          setVariantPreviews(variants);
        }
      } catch (err) {
        logger.error("sales.channels.offer.initialHydrate", { err });
      }
    }
    void hydrateExistingProduct();
    return () => {
      cancelled = true;
    };
  }, [
    attachmentCache,
    initialValues?.channelId,
    initialValues?.productId,
    lockedChannelId,
    mode,
    productCache,
    selectedChannelId,
    setMediaOptions,
    setProductSummary,
    setVariantPreviews,
    variantCache,
    variantMediaCache
  ]);
  React.useEffect(() => {
    async function loadKinds() {
      const mapItems = (items) => items.map((item) => {
        const displayMode = item.displayMode === "including-tax" || item.display_mode === "including-tax" ? "including-tax" : "excluding-tax";
        return {
          id: typeof item.id === "string" ? item.id : "",
          code: typeof item.code === "string" ? item.code : null,
          title: typeof item.title === "string" ? item.title : null,
          currencyCode: typeof item.currencyCode === "string" ? item.currencyCode : typeof item.currency_code === "string" ? item.currency_code : null,
          displayMode
        };
      });
      const endpoints = [
        `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,
        `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`
      ];
      try {
        for (const endpoint of endpoints) {
          try {
            const payload = await readApiResultOrThrow(
              endpoint,
              void 0,
              { fallback: { items: [] } }
            );
            const items = Array.isArray(payload.items) ? payload.items : [];
            setPriceKinds(mapItems(items));
            return;
          } catch (err) {
            logger.error("sales.channels.price-kinds.fetch", { endpoint, err });
          }
        }
        setPriceKinds([]);
      } catch (err) {
        logger.error("catalog.price-kinds.list", { err });
      }
    }
    void loadKinds();
  }, []);
  React.useEffect(() => {
    if (mode !== "edit" || !offerId) return;
    const offerKey = offerId;
    let cancelled = false;
    async function loadOffer() {
      setLoading(true);
      setError(null);
      setIsNotFound(false);
      try {
        const payload = await readApiResultOrThrow(
          `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,
          void 0,
          { errorMessage: t("sales.channels.offers.errors.loadOffer", "Failed to load offer.") }
        );
        const offer = Array.isArray(payload.items) ? payload.items[0] : null;
        if (!offer) {
          if (!cancelled) setIsNotFound(true);
          return;
        }
        const values = mapOfferToFormValues(offer, lockedChannelId);
        const pricePayload = await readApiResultOrThrow(
          `/api/catalog/prices?offerId=${encodeURIComponent(offer.id)}&pageSize=${MAX_LIST_PAGE_SIZE}`,
          void 0,
          { fallback: { items: [] } }
        );
        const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : [];
        values.priceOverrides = priceItems.map(mapPriceRow);
        let preloadedMedia = [];
        let preloadedVariants = [];
        let preloadedSummary = null;
        const productId = typeof values.productId === "string" ? values.productId : null;
        if (productId) {
          try {
            const hydrationChannelId = selectedChannelId ?? lockedChannelId ?? (typeof values.channelId === "string" ? values.channelId : null);
            const [summary, attachments, variants] = await Promise.all([
              resolveProductSummaryWithCache({
                productId,
                channelId: hydrationChannelId ?? null,
                productCache
              }),
              loadProductMedia(productId),
              resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache })
            ]);
            preloadedSummary = summary ?? null;
            preloadedVariants = variants;
            preloadedMedia = buildMediaOptionsFromSources({
              attachments,
              variants,
              summary
            });
            attachmentCache.current.set(productId, preloadedMedia);
          } catch (err) {
            logger.error("sales.channels.offer.media.preload", { err });
          }
        }
        if (!cancelled) {
          setInitialValues(values);
          setProductSummary(preloadedSummary);
          setVariantPreviews(preloadedVariants);
          setMediaOptions(preloadedMedia);
        }
      } catch (err) {
        logger.error("sales.channels.offer.load", { err });
        if (!cancelled) setError(t("sales.channels.offers.errors.loadOffer", "Failed to load offer."));
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    void loadOffer();
    return () => {
      cancelled = true;
    };
  }, [
    attachmentCache,
    lockedChannelId,
    mode,
    offerId,
    productCache,
    selectedChannelId,
    setMediaOptions,
    setProductSummary,
    setVariantPreviews,
    t,
    variantCache,
    variantMediaCache
  ]);
  const fields = React.useMemo(() => [
    {
      id: "channelId",
      label: t("sales.channels.offers.form.channel", "Channel"),
      type: "custom",
      required: true,
      component: ({ value, setValue }) => /* @__PURE__ */ jsx(
        ChannelSelectInput,
        {
          value: value ?? lockedChannelId ?? null,
          onChange: (next) => {
            setValue(next ?? null);
            setSelectedChannelId(next ?? null);
          },
          disabled: !!lockedChannelId,
          showDetailsLink: true
        }
      )
    },
    {
      id: "productId",
      label: t("sales.channels.offers.form.product", "Product"),
      type: "custom",
      required: true,
      component: ({ value, setValue }) => /* @__PURE__ */ jsx(
        ProductSelectInput,
        {
          value: value ?? null,
          onChange: (next) => setValue(next),
          channelId: selectedChannelId,
          currentOfferId: offerId ?? null
        }
      )
    },
    {
      id: "defaultMediaId",
      label: t("sales.channels.offers.form.defaultMedia", "Default media"),
      type: "custom",
      component: ({ value, setValue }) => /* @__PURE__ */ jsx(
        DefaultMediaSelect,
        {
          value: value ?? null,
          onChange: (next) => {
            setValue(next);
            if (!currentProductId) return;
            if (next === null || next === void 0) {
              manualMediaSelections.current.add(currentProductId);
            } else {
              manualMediaSelections.current.delete(currentProductId);
            }
          },
          options: mediaOptions,
          productThumbnail: productSummary?.defaultMediaUrl ?? null,
          hasProduct: Boolean(productSummary),
          productDefaultMediaId: productSummary?.defaultMediaId ?? null
        }
      )
    },
    {
      id: "title",
      label: t("sales.channels.offers.form.title", "Title"),
      type: "text",
      required: true
    },
    {
      id: "description",
      label: t("sales.channels.offers.form.description", "Description"),
      type: "textarea"
    },
    {
      id: "isActive",
      label: t("sales.channels.offers.form.active", "Active"),
      type: "checkbox"
    }
  ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId]);
  const handleOverrideRemove = React.useCallback(async (draft) => {
    const priceId = typeof draft?.priceId === "string" ? draft.priceId : null;
    if (!priceId) return true;
    if (mode !== "edit") return true;
    try {
      await withScopedApiRequestHeaders(
        buildOptimisticLockHeader(draft.updatedAt),
        () => deleteCrud("catalog/prices", priceId, {
          errorMessage: t("sales.channels.offers.errors.removePrice", "Failed to remove price override.")
        })
      );
      initialPriceVersionsRef.current.delete(priceId);
      return true;
    } catch (err) {
      if (surfaceRecordConflict(err, t)) return false;
      logger.error("sales.channels.pricing.remove", { err });
      flash(t("sales.channels.offers.errors.removePrice", "Failed to remove price override."), "error");
      return false;
    }
  }, [mode, t]);
  const groups = React.useMemo(() => [
    { id: "associations", column: 1, title: t("sales.channels.offers.form.groups.associations", "Associations"), fields: ["channelId"] },
    {
      id: "product",
      column: 1,
      title: t("sales.channels.offers.form.productGroup", "Product"),
      description: t("sales.channels.offers.form.productGroupHelp", "Search the catalog and pick the product you want to customize for this channel."),
      fields: ["productId"]
    },
    {
      id: "productSummary",
      column: 2,
      title: t("sales.channels.offers.form.productSummaryTitle", "Product summary"),
      component: () => /* @__PURE__ */ jsx(ProductOverviewCard, { summary: productSummary, variants: variantPreviews })
    },
    {
      id: "media",
      column: 1,
      title: t("sales.channels.offers.form.mediaGroupTitle", "Default media override"),
      fields: ["defaultMediaId"]
    },
    { id: "content", column: 1, title: t("sales.channels.offers.form.groups.content", "Content"), fields: ["title", "description", "isActive"] },
    {
      id: "pricing",
      column: 1,
      title: t("sales.channels.offers.form.groups.pricing", "Price overrides"),
      component: ({ values, setValue }) => /* @__PURE__ */ jsx(
        PriceOverridesEditor,
        {
          values: Array.isArray(values.priceOverrides) ? values.priceOverrides : [],
          onChange: (next) => setValue("priceOverrides", next),
          priceKinds,
          basePrice: productSummary?.pricing ?? null,
          onRemoveDraft: handleOverrideRemove
        }
      )
    },
    {
      id: "customFields",
      column: 2,
      title: t("entities.customFields.title", "Custom attributes"),
      kind: "customFields"
    },
    {
      id: "watchers",
      column: 1,
      bare: true,
      component: ({ values, setValue, errors }) => /* @__PURE__ */ jsx(
        OfferFormWatchers,
        {
          values,
          setValue,
          errors,
          productCache,
          attachmentCache,
          setMediaOptions,
          setProductSummary,
          setVariantPreviews,
          variantCache,
          variantMediaCache,
          channelId: selectedChannelId,
          manualMediaSelections,
          setCurrentProductId
        }
      )
    }
  ], [
    attachmentCache,
    handleOverrideRemove,
    manualMediaSelections,
    priceKinds,
    productCache,
    productSummary,
    selectedChannelId,
    setMediaOptions,
    setCurrentProductId,
    t,
    variantPreviews
  ]);
  const handleSubmit = React.useCallback(async (values) => {
    const channelId = typeof values.channelId === "string" && values.channelId.length ? values.channelId : selectedChannelId ?? lockedChannelId;
    const productId = typeof values.productId === "string" ? values.productId : null;
    if (!channelId || !productId) {
      throw new Error(t("sales.channels.offers.errors.requiredFields", "Choose a channel and product."));
    }
    const resolvedDefaultMediaId = typeof values.defaultMediaId === "string" && values.defaultMediaId.trim().length ? values.defaultMediaId : values.defaultMediaId === null ? null : void 0;
    const basePayload = {
      channelId,
      productId,
      title: values.title?.trim() || void 0,
      description: values.description?.trim() || void 0,
      isActive: values.isActive !== false
    };
    if (resolvedDefaultMediaId !== void 0) {
      basePayload.defaultMediaId = resolvedDefaultMediaId;
    }
    const attachmentLookup = attachmentCache.current.get(productId) ?? [];
    const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]));
    if (typeof resolvedDefaultMediaId === "string" && mediaMap.has(resolvedDefaultMediaId)) {
      const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null;
      basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {
        slug: slugifyAttachmentFileName(fileName)
      });
    } else if (resolvedDefaultMediaId === null) {
      basePayload.defaultMediaUrl = null;
    }
    const customFields = collectCustomFieldValues(values);
    if (Object.keys(customFields).length) basePayload.customFields = customFields;
    const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides : [];
    const priceWithoutKind = overrides.find((entry) => {
      const amount = typeof entry.amount === "string" ? entry.amount.trim() : entry.amount;
      const hasAmount = typeof amount === "string" ? amount.length > 0 : amount !== void 0 && amount !== null;
      const hasExistingPrice = typeof entry.priceId === "string" && entry.priceId.length > 0;
      const hasCurrency = typeof entry.currencyCode === "string" && entry.currencyCode.length > 0;
      return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency);
    });
    if (priceWithoutKind) {
      throw createCrudFormError(t("sales.channels.offers.errors.priceKindRequired", "Select a price kind for each override."), {});
    }
    const duplicateKind = (() => {
      const seen = /* @__PURE__ */ new Set();
      for (const entry of overrides) {
        const kindId = typeof entry.priceKindId === "string" ? entry.priceKindId : null;
        if (!kindId) continue;
        if (seen.has(kindId)) return kindId;
        seen.add(kindId);
      }
      return null;
    })();
    if (duplicateKind) {
      throw createCrudFormError(
        t("sales.channels.offers.errors.priceKindDuplicate", "Each price kind can only be overridden once."),
        {}
      );
    }
    const submittedPriceIds = collectPriceIds(overrides);
    const deletedIdSet = /* @__PURE__ */ new Set();
    initialPriceVersionsRef.current.forEach((_version, id) => {
      if (!submittedPriceIds.has(id)) deletedIdSet.add(id);
    });
    const deletedIds = Array.from(deletedIdSet);
    const deletedVersions = new Map(deletedIds.map((id) => [id, initialPriceVersionsRef.current.get(id) ?? null]));
    let savedId = offerId ?? null;
    try {
      if (mode === "create") {
        const res = await createCrud("catalog/offers", basePayload, {
          errorMessage: t("sales.channels.offers.errors.save", "Failed to save offer.")
        });
        savedId = res?.result?.offerId ?? res?.result?.id ?? null;
      } else if (offerId) {
        await updateCrud("catalog/offers", { id: offerId, ...basePayload }, {
          errorMessage: t("sales.channels.offers.errors.save", "Failed to save offer.")
        });
        savedId = offerId;
      }
    } catch (err) {
      if (extractOptimisticLockConflict(err)) {
        throw err;
      }
      const details = err?.details;
      const rawFieldErrors = err?.fieldErrors;
      const fieldErrors = rawFieldErrors && typeof rawFieldErrors === "object" ? rawFieldErrors : void 0;
      const status = err?.status;
      const message = typeof err.message === "string" && err.message.trim().length ? err.message : t(
        "sales.channels.offers.errors.duplicateProduct",
        "This product already has an offer in this channel."
      );
      throw createCrudFormError(
        message,
        fieldErrors,
        { status, details }
      );
    }
    if (savedId) {
      await syncPriceOverrides({
        overrides,
        deletedIds,
        deletedVersions,
        offerId: savedId,
        channelId,
        productId
      });
      initialPriceVersionsRef.current = collectPriceVersions(overrides);
    }
    flash(t("sales.channels.offers.messages.saved", "Offer saved."), "success");
    router.push(buildChannelOffersHref(channelId));
  }, [attachmentCache, lockedChannelId, mode, offerId, router, selectedChannelId, t]);
  const handleDelete = React.useCallback(async () => {
    if (!offerId) return;
    await deleteCrud("catalog/offers", offerId, {
      errorMessage: t("sales.channels.offers.errors.delete", "Failed to delete offer.")
    });
    flash(t("sales.channels.offers.messages.deleted", "Offer deleted."), "success");
    const targetChannel = initialValues?.channelId ?? lockedChannelId ?? "";
    router.push(buildChannelOffersHref(targetChannel));
  }, [initialValues?.channelId, lockedChannelId, offerId, router, t]);
  if (isNotFound) {
    return /* @__PURE__ */ jsx(
      RecordNotFoundState,
      {
        label: t("sales.channels.offers.errors.notFound", "Offer not found."),
        backHref: channelOffersHref,
        backLabel: t("sales.channels.offers.actions.backToList", "Back to offers")
      }
    );
  }
  return /* @__PURE__ */ jsxs("div", { children: [
    error ? /* @__PURE__ */ jsx(ErrorMessage, { label: error, className: "mb-4" }) : null,
    /* @__PURE__ */ jsx(
      CrudForm,
      {
        title: mode === "create" ? t("sales.channels.offers.form.createTitle", "Create offer") : t("sales.channels.offers.form.editTitle", "Edit offer"),
        entityId: E.catalog.catalog_offer,
        fields,
        groups,
        initialValues: initialValues ?? void 0,
        optimisticLockUpdatedAt: initialValues?.updatedAt,
        isLoading: loading,
        loadingMessage: t("sales.channels.offers.form.loading", "Loading offer\u2026"),
        submitLabel: mode === "create" ? t("sales.channels.offers.form.createSubmit", "Create offer") : t("sales.channels.offers.form.updateSubmit", "Save changes"),
        cancelHref: channelOffersHref,
        backHref: channelOffersHref,
        onSubmit: handleSubmit,
        onDelete: mode === "edit" ? handleDelete : void 0,
        deleteVisible: mode === "edit",
        deleteRedirect: channelOffersHref
      }
    )
  ] });
}
function mapOfferToFormValues(item, lockedChannelId) {
  const values = {
    channelId: typeof item.channelId === "string" ? item.channelId : typeof item.channel_id === "string" ? item.channel_id : lockedChannelId ?? null,
    productId: typeof item.productId === "string" ? item.productId : typeof item.product_id === "string" ? item.product_id : null,
    title: typeof item.title === "string" ? item.title : "",
    description: typeof item.description === "string" ? item.description : "",
    defaultMediaId: typeof item.defaultMediaId === "string" ? item.defaultMediaId : typeof item.default_media_id === "string" ? item.default_media_id : null,
    isActive: item.isActive === true || item.is_active === true,
    priceOverrides: [],
    updatedAt: typeof item.updatedAt === "string" ? item.updatedAt : typeof item.updated_at === "string" ? item.updated_at : null
  };
  mergeCustomFieldValues(values, item);
  return values;
}
function mapPriceRow(row) {
  return {
    tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),
    priceId: typeof row.id === "string" ? row.id : void 0,
    priceKindId: typeof row.priceKindId === "string" ? row.priceKindId : typeof row.price_kind_id === "string" ? row.price_kind_id : void 0,
    priceKindCode: typeof row.priceKindCode === "string" ? row.priceKindCode : typeof row.price_kind_code === "string" ? row.price_kind_code : null,
    currencyCode: typeof row.currencyCode === "string" ? row.currencyCode : typeof row.currency_code === "string" ? row.currency_code : null,
    displayMode: row.displayMode === "including-tax" || row.display_mode === "including-tax" ? "including-tax" : "excluding-tax",
    amount: typeof row.unitPriceNet === "string" ? row.unitPriceNet : typeof row.unit_price_net === "string" ? row.unit_price_net : typeof row.unitPriceGross === "string" ? row.unitPriceGross : typeof row.unit_price_gross === "string" ? row.unit_price_gross : "",
    updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : typeof row.updated_at === "string" ? row.updated_at : null
  };
}
function collectPriceIds(source) {
  if (!Array.isArray(source)) return /* @__PURE__ */ new Set();
  const ids = source.map((entry) => typeof entry?.priceId === "string" ? entry.priceId : null).filter((id) => Boolean(id));
  return new Set(ids);
}
function collectPriceVersions(source) {
  const versions = /* @__PURE__ */ new Map();
  if (!Array.isArray(source)) return versions;
  for (const entry of source) {
    if (typeof entry?.priceId === "string" && entry.priceId) {
      versions.set(entry.priceId, typeof entry.updatedAt === "string" ? entry.updatedAt : null);
    }
  }
  return versions;
}
function mergeCustomFieldValues(target, source) {
  Object.assign(target, extractCustomFieldEntries(source ?? {}));
}
function buildChannelOffersHref(channelId) {
  return channelId && channelId.length ? `/backend/sales/channels/${channelId}/edit?tab=offers` : "/backend/sales/channels/offers";
}
async function syncPriceOverrides(params) {
  const { overrides, deletedIds, deletedVersions, offerId, channelId, productId } = params;
  for (const draft of overrides) {
    if (!draft.priceKindId || !draft.amount) continue;
    const amount = Number(draft.amount);
    if (Number.isNaN(amount)) continue;
    const payload = {
      offerId,
      productId,
      channelId,
      priceKindId: draft.priceKindId,
      currencyCode: draft.currencyCode ?? void 0
    };
    if (draft.displayMode === "including-tax") {
      payload.unitPriceGross = amount;
    } else {
      payload.unitPriceNet = amount;
    }
    if (draft.priceId) {
      const priceId = draft.priceId;
      await withScopedApiRequestHeaders(
        buildOptimisticLockHeader(draft.updatedAt),
        () => updateCrud("catalog/prices", { id: priceId, ...payload })
      );
    } else {
      await createCrud("catalog/prices", payload);
    }
  }
  const uniqueDeletedIds = Array.from(new Set(
    deletedIds.filter((id) => typeof id === "string" && id.length > 0)
  ));
  for (const id of uniqueDeletedIds) {
    if (!id) continue;
    try {
      await withScopedApiRequestHeaders(
        buildOptimisticLockHeader(deletedVersions.get(id) ?? null),
        () => deleteCrud("catalog/prices", id)
      );
    } catch (err) {
      logger.error("catalog.prices.delete", { err });
    }
  }
}
function ChannelSelectInput({
  value,
  onChange,
  disabled,
  showDetailsLink
}) {
  const t = useT();
  const [options, setOptions] = React.useState([]);
  const selectedOption = React.useMemo(
    () => value ? options.find((opt) => opt.id === value) ?? null : null,
    [options, value]
  );
  React.useEffect(() => {
    async function load() {
      try {
        const payload = await readApiResultOrThrow(
          `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,
          void 0,
          { fallback: { items: [] } }
        );
        const items = Array.isArray(payload.items) ? payload.items : [];
        setOptions(items.map((item) => ({
          id: typeof item.id === "string" ? item.id : "",
          name: typeof item.name === "string" ? item.name : "",
          code: typeof item.code === "string" ? item.code : null
        })));
      } catch (err) {
        logger.error("sales.channels.options", { err });
      }
    }
    void load();
  }, []);
  React.useEffect(() => {
    const channelIdToLoad = typeof value === "string" ? value : null;
    if (!channelIdToLoad || selectedOption) return;
    const resolvedChannelId = channelIdToLoad;
    let cancelled = false;
    async function loadSingle() {
      try {
        const payload = await readApiResultOrThrow(
          `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,
          void 0,
          { fallback: { items: [] } }
        );
        const item = Array.isArray(payload.items) ? payload.items[0] : null;
        if (!item || cancelled) return;
        const entry = {
          id: typeof item.id === "string" ? item.id : resolvedChannelId,
          name: typeof item.name === "string" ? item.name : resolvedChannelId,
          code: typeof item.code === "string" ? item.code : null
        };
        setOptions((prev) => {
          if (prev.some((opt) => opt.id === entry.id)) return prev;
          return [...prev, entry];
        });
      } catch (err) {
        logger.error("sales.channels.lookup", { err });
      }
    }
    void loadSingle();
    return () => {
      cancelled = true;
    };
  }, [selectedOption, value]);
  if (disabled && value) {
    const label = selectedOption?.name ?? value;
    const detail = selectedOption?.code ?? null;
    return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm", children: [
      /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
        /* @__PURE__ */ jsx("div", { className: "font-medium truncate", children: label }),
        detail ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: detail }) : null
      ] }),
      showDetailsLink ? /* @__PURE__ */ jsx(Link, { href: `/backend/sales/channels/${value}/edit`, className: "text-xs font-medium text-primary hover:underline", children: t("sales.channels.offers.form.channelDetails", "Details") }) : null
    ] });
  }
  return /* @__PURE__ */ jsxs(Select, { value: value || void 0, onValueChange: (next) => onChange(next || null), children: [
    /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("sales.channels.offers.form.channelPlaceholder", "Select channel") }) }),
    /* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.id, children: opt.code ? `${opt.name} (${opt.code})` : opt.name }, opt.id)) })
  ] });
}
function ProductSelectInput({
  value,
  onChange,
  channelId,
  currentOfferId
}) {
  const t = useT();
  const [query, setQuery] = React.useState("");
  const [results, setResults] = React.useState([]);
  const [isLoading, setLoading] = React.useState(false);
  const [hasTyped, setHasTyped] = React.useState(false);
  const trimmed = query.trim();
  const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed);
  React.useEffect(() => {
    if (!shouldSearch) {
      setResults([]);
      return;
    }
    let cancelled = false;
    const controller = new AbortController();
    const timeout = setTimeout(async () => {
      setLoading(true);
      try {
        const params = new URLSearchParams({ pageSize: "10" });
        if (UUID_REGEX.test(trimmed)) {
          params.set("id", trimmed);
        } else if (trimmed.length) {
          params.set("search", trimmed);
        }
        if (channelId) params.set("channelId", channelId);
        const payload = await readApiResultOrThrow(
          `/api/catalog/products?${params.toString()}`,
          { signal: controller.signal },
          { fallback: { items: [] } }
        );
        const items = Array.isArray(payload.items) ? payload.items : [];
        if (!cancelled) {
          const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId));
          mapped.sort((a, b) => {
            const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct);
            const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct);
            return Number(aBlocked) - Number(bBlocked);
          });
          setResults(mapped);
        }
      } catch (err) {
        if (err.name === "AbortError") return;
        logger.error("catalog.products.lookup", { err });
      } finally {
        if (!cancelled) setLoading(false);
      }
    }, 250);
    return () => {
      cancelled = true;
      clearTimeout(timeout);
      controller.abort();
    };
  }, [channelId, currentOfferId, shouldSearch, trimmed]);
  const handleKeyDown = React.useCallback((event) => {
    if (event.key === "Enter" && UUID_REGEX.test(trimmed)) {
      event.preventDefault();
      onChange(trimmed);
    }
  }, [onChange, trimmed]);
  const selectedHint = value ? t("sales.channels.offers.form.productSelectedHint", "Selected product ID: {{id}}", { id: value }) : null;
  return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
    /* @__PURE__ */ jsx(
      Input,
      {
        leftIcon: /* @__PURE__ */ jsx(Search, {}),
        value: query,
        onChange: (event) => {
          setQuery(event.target.value);
          setHasTyped(true);
        },
        onKeyDown: handleKeyDown,
        placeholder: t("sales.channels.offers.form.productSearchPlaceholder", "Search by title, SKU, or ID\u2026")
      }
    ),
    selectedHint ? /* @__PURE__ */ jsx("div", { className: "rounded border bg-muted px-3 py-2 text-xs text-muted-foreground", children: selectedHint }) : null,
    value ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onChange(null), children: t("sales.channels.offers.form.productClear", "Clear selection") }) : null,
    shouldSearch ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
      isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
        /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
        t("sales.channels.offers.form.productSearchLoading", "Searching products\u2026")
      ] }) : null,
      !isLoading && !results.length ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.productSearchEmpty", "No products match your search.") }) : null,
      /* @__PURE__ */ jsx("div", { className: "space-y-2 max-h-80 overflow-y-auto", children: results.map((product) => {
        const isSelected = value === product.id;
        const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct);
        return /* @__PURE__ */ jsxs(
          "div",
          {
            className: cn(
              "flex gap-3 rounded border bg-card p-3 transition-colors",
              isSelected ? "border-primary/70 bg-primary/5" : "hover:border-primary/50"
            ),
            children: [
              /* @__PURE__ */ jsx("div", { className: "h-12 w-12 overflow-hidden rounded border bg-muted", children: product.defaultMediaUrl ? /* @__PURE__ */ jsx("img", { src: product.defaultMediaUrl, alt: product.title, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(ImageIcon, { className: "h-5 w-5" }) }) }),
              /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1", children: [
                /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
                  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
                    /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-medium", children: product.title || t("sales.channels.offers.form.productUntitled", "Untitled product") }),
                    product.sku ? /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
                      "SKU \xB7 ",
                      product.sku
                    ] }) : null
                  ] }),
                  /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground", children: product.pricing ? formatPriceDisplay(product.pricing) : t("sales.channels.offers.form.productPriceMissing", "No price") })
                ] }),
                hasConflict ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 text-xs text-status-warning-text", children: [
                  /* @__PURE__ */ jsx("span", { className: "truncate", children: t("sales.channels.offers.form.productHasOffer", "Already has an offer for this channel.") }),
                  channelId && product.existingOfferId ? /* @__PURE__ */ jsx(
                    Link,
                    {
                      href: `/backend/sales/channels/${encodeURIComponent(
                        String(channelId)
                      )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`,
                      className: "shrink-0 font-medium text-primary hover:underline",
                      children: t("sales.channels.offers.form.productHasOfferLink", "View offer")
                    }
                  ) : null
                ] }) : null,
                /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
                  Button,
                  {
                    type: "button",
                    variant: isSelected ? "secondary" : "outline",
                    size: "sm",
                    onClick: () => onChange(product.id),
                    disabled: hasConflict && !isSelected,
                    children: hasConflict && !isSelected ? t("sales.channels.offers.form.productUnavailable", "Unavailable") : isSelected ? t("sales.channels.offers.form.productSelected", "Selected") : t("sales.channels.offers.form.productSelect", "Select")
                  }
                ) })
              ] })
            ]
          },
          product.id
        );
      }) })
    ] }) : hasTyped ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.productSearchHint", "Type at least 2 characters or paste a product ID.") }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.productSearchIntro", "Search by name or paste the product id to find catalog items.") })
  ] });
}
function DefaultMediaSelect({
  value,
  options,
  onChange,
  productThumbnail,
  hasProduct,
  productDefaultMediaId
}) {
  const t = useT();
  const filteredOptions = React.useMemo(() => {
    if (!productDefaultMediaId) return options;
    return options.filter((opt) => opt.id !== productDefaultMediaId);
  }, [options, productDefaultMediaId]);
  const hasAttachmentOptions = filteredOptions.length > 0;
  const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct;
  if (showPlaceholder) {
    return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.mediaSelectProduct", "Select a product to load its media.") });
  }
  const tiles = [
    {
      id: "inherit",
      label: t("sales.channels.offers.form.mediaInherit", "Use product default"),
      thumbnail: productThumbnail,
      selected: value == null,
      onClick: () => onChange(null)
    },
    ...filteredOptions.map((opt) => ({
      id: opt.id,
      label: opt.label,
      thumbnail: opt.thumbnailUrl ?? null,
      selected: value === opt.id,
      onClick: () => onChange(opt.id)
    }))
  ];
  return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
    /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
      /* @__PURE__ */ jsx("p", { children: t("sales.channels.offers.form.mediaHelp", "Choose the thumbnail that should represent this offer in the channel.") }),
      !hasAttachmentOptions && hasProduct ? /* @__PURE__ */ jsx("p", { className: "mt-1", children: t("sales.channels.offers.form.mediaEmpty", "This product has no uploaded media yet; the product default will be used.") }) : null
    ] }),
    /* @__PURE__ */ jsx("div", { className: "grid gap-3 sm:grid-cols-3", children: tiles.map((tile) => /* @__PURE__ */ jsxs(
      "button",
      {
        type: "button",
        className: cn(
          "flex flex-col rounded border text-left transition-colors",
          tile.selected ? "border-primary shadow-sm" : "hover:border-primary/60"
        ),
        onClick: tile.onClick,
        children: [
          /* @__PURE__ */ jsxs("div", { className: "relative aspect-square overflow-hidden rounded-t bg-muted", children: [
            tile.thumbnail ? /* @__PURE__ */ jsx("img", { src: tile.thumbnail, alt: tile.label, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(ImageIcon, { className: "h-6 w-6" }) }),
            tile.selected ? /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground", children: t("sales.channels.offers.form.mediaSelected", "Active") }) : null
          ] }),
          /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx("div", { className: "line-clamp-2 text-xs font-medium", children: tile.label }) })
        ]
      },
      tile.id
    )) })
  ] });
}
function OfferFormWatchers({
  values,
  setValue,
  productCache,
  attachmentCache,
  setMediaOptions,
  setProductSummary,
  setVariantPreviews,
  variantCache,
  variantMediaCache,
  channelId,
  manualMediaSelections,
  setCurrentProductId,
  errors
}) {
  const previousProductIdRef = React.useRef(null);
  const initializedProductRef = React.useRef(false);
  React.useEffect(() => {
    const productId = typeof values.productId === "string" ? values.productId : null;
    setCurrentProductId(productId);
    if (!productId) {
      setMediaOptions([]);
      setProductSummary(null);
      setVariantPreviews([]);
      previousProductIdRef.current = null;
      return;
    }
    const resolvedProductId = productId;
    const resolvedChannelId = channelId ?? null;
    if (!initializedProductRef.current) {
      previousProductIdRef.current = resolvedProductId;
      initializedProductRef.current = true;
    } else if (previousProductIdRef.current !== resolvedProductId) {
      previousProductIdRef.current = resolvedProductId;
      setValue("defaultMediaId", void 0);
    }
    let cancelled = false;
    async function load() {
      try {
        const summary = await resolveProductSummaryWithCache({
          productId: resolvedProductId,
          channelId: resolvedChannelId,
          productCache
        });
        if (!cancelled) {
          setProductSummary(summary ?? null);
          if (summary) {
            const hasTitle = typeof values.title === "string" && values.title.trim().length > 0;
            if (!hasTitle && summary.title) {
              setValue("title", summary.title);
            }
            const hasDescription = typeof values.description === "string" && values.description.trim().length > 0;
            if (!hasDescription && summary.description) {
              setValue("description", summary.description);
            }
            if (!values.defaultMediaId && summary.defaultMediaId && !manualMediaSelections.current.has(resolvedProductId)) {
              setValue("defaultMediaId", summary.defaultMediaId);
            }
          }
        }
        const attachments = await resolveProductMediaOptionsWithCache({
          productId: resolvedProductId,
          attachmentCache
        });
        if (!cancelled) {
          const variants = await resolveVariantPreviewsWithCache({
            productId: resolvedProductId,
            variantCache,
            variantMediaCache
          });
          const mergedMedia = buildMediaOptionsFromSources({
            attachments,
            variants,
            summary
          });
          attachmentCache.current.set(resolvedProductId, mergedMedia);
          setMediaOptions(mergedMedia);
          setVariantPreviews(variants);
        }
      } catch (err) {
        logger.error("sales.channels.offer.watchers", { err });
      }
    }
    void load();
    return () => {
      cancelled = true;
    };
  }, [
    attachmentCache,
    channelId,
    manualMediaSelections,
    productCache,
    setMediaOptions,
    setProductSummary,
    setValue,
    setVariantPreviews,
    values.defaultMediaId,
    values.description,
    values.productId,
    values.title,
    variantCache,
    variantMediaCache,
    setCurrentProductId
  ]);
  return null;
}
async function resolveProductSummaryWithCache({
  productId,
  channelId,
  productCache
}) {
  if (!productId) return null;
  const cacheKey = channelId ? `${productId}:${channelId}` : productId;
  let summary = productCache.current.get(cacheKey);
  if (summary) return summary;
  const params = new URLSearchParams({ id: productId, pageSize: "1" });
  if (channelId) params.set("channelId", channelId);
  const payload = await readApiResultOrThrow(
    `/api/catalog/products?${params.toString()}`,
    void 0,
    { fallback: { items: [] } }
  );
  const product = Array.isArray(payload.items) ? payload.items[0] : null;
  summary = product ? mapProductSummary(product) : null;
  if (summary) {
    productCache.current.set(cacheKey, summary);
  }
  return summary ?? null;
}
async function resolveProductMediaOptionsWithCache({
  productId,
  attachmentCache
}) {
  if (!productId) return [];
  const cached = attachmentCache.current.get(productId) ?? [];
  if (cached.length) {
    const deduped = dedupeMediaOptions(cached);
    attachmentCache.current.set(productId, deduped);
    return deduped;
  }
  const attachments = dedupeMediaOptions(await loadProductMedia(productId));
  attachmentCache.current.set(productId, attachments);
  return attachments;
}
async function resolveVariantPreviewsWithCache({
  productId,
  variantCache,
  variantMediaCache
}) {
  if (!productId) return [];
  const cached = variantCache.current.get(productId);
  if (cached) return cached;
  const variantPayload = await readApiResultOrThrow(
    `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,
    void 0,
    { fallback: { items: [] } }
  );
  const items = Array.isArray(variantPayload.items) ? variantPayload.items : [];
  const variants = await Promise.all(
    items.map(async (item) => {
      const preview = mapVariantPreview(item);
      const media = await resolveVariantThumbnail(preview.id, variantMediaCache);
      return {
        ...preview,
        thumbnailId: media?.attachmentId ?? preview.thumbnailId,
        thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,
        thumbnailFileName: media?.fileName ?? preview.thumbnailFileName
      };
    })
  );
  variantCache.current.set(productId, variants);
  return variants;
}
function mapProductSummary(item) {
  const pricingSource = item.pricing && typeof item.pricing === "object" ? item.pricing : null;
  return {
    title: typeof item.title === "string" ? item.title : "",
    description: typeof item.description === "string" ? item.description : null,
    defaultMediaId: typeof item.defaultMediaId === "string" ? item.defaultMediaId : typeof item.default_media_id === "string" ? item.default_media_id : null,
    defaultMediaUrl: typeof item.defaultMediaUrl === "string" ? item.defaultMediaUrl : typeof item.default_media_url === "string" ? item.default_media_url : null,
    sku: typeof item.sku === "string" ? item.sku : null,
    pricing: normalizePricing(pricingSource)
  };
}
function normalizePricing(source) {
  if (!source) return null;
  const currencyCode = typeof source.currencyCode === "string" ? source.currencyCode : typeof source.currency_code === "string" ? source.currency_code : null;
  const unitPriceNet = typeof source.unitPriceNet === "string" ? source.unitPriceNet : typeof source.unit_price_net === "string" ? source.unit_price_net : null;
  const unitPriceGross = typeof source.unitPriceGross === "string" ? source.unitPriceGross : typeof source.unit_price_gross === "string" ? source.unit_price_gross : null;
  const displayMode = source.displayMode === "including-tax" || source.display_mode === "including-tax" ? "including-tax" : source.displayMode === "excluding-tax" || source.display_mode === "excluding-tax" ? "excluding-tax" : null;
  return { currencyCode, unitPriceNet, unitPriceGross, displayMode };
}
async function loadProductMedia(productId) {
  if (!productId) return [];
  const normalize = (items) => items.filter((item) => typeof item.id === "string" && typeof item.fileName === "string").map((item) => ({
    id: item.id,
    label: item.fileName,
    fileName: item.fileName,
    thumbnailUrl: typeof item.thumbnailUrl === "string" ? item.thumbnailUrl : buildAttachmentImageUrl(item.id, {
      width: 360,
      height: 360,
      slug: slugifyAttachmentFileName(item.fileName)
    })
  }));
  try {
    const primary = await apiCall(
      `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,
      void 0,
      { fallback: { items: [] } }
    );
    if (primary.ok && primary.result?.items) {
      return normalize(primary.result.items);
    }
  } catch (err) {
    logger.error("catalog.product-media.lookup", { err });
  }
  try {
    const fallback = await apiCall(
      `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,
      void 0,
      { fallback: { items: [] } }
    );
    if (fallback.ok && fallback.result?.items) {
      return normalize(fallback.result.items);
    }
  } catch (err) {
    logger.error("attachments.lookup", { err });
  }
  return [];
}
function buildVariantMediaOptions(variants) {
  return variants.map((variant) => {
    if (!variant.thumbnailId || !variant.thumbnailUrl) return null;
    const label = variant.name || variant.sku || "Variant";
    const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`;
    return {
      id: variant.thumbnailId,
      label,
      fileName,
      thumbnailUrl: variant.thumbnailUrl
    };
  }).filter((entry) => Boolean(entry));
}
function buildMediaOptionsFromSources({
  attachments,
  variants,
  summary
}) {
  const merged = dedupeMediaOptions([
    ...attachments ?? [],
    ...buildVariantMediaOptions(variants ?? [])
  ]);
  const defaultId = summary?.defaultMediaId ?? null;
  const defaultUrl = summary?.defaultMediaUrl ?? null;
  if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {
    const fileName = inferFileNameFromUrl(defaultUrl, defaultId);
    merged.unshift({
      id: defaultId,
      label: fileName,
      fileName,
      thumbnailUrl: defaultUrl
    });
  }
  return merged;
}
function dedupeMediaOptions(entries) {
  if (!Array.isArray(entries)) return [];
  const seen = /* @__PURE__ */ new Set();
  const result = [];
  for (const entry of entries) {
    if (!entry || typeof entry.id !== "string") continue;
    if (seen.has(entry.id)) continue;
    seen.add(entry.id);
    result.push(entry);
  }
  return result;
}
function inferFileNameFromUrl(url, fallbackId) {
  if (typeof url === "string" && url.length) {
    const cleaned = url.split(/[?#]/)[0];
    const last = cleaned.split("/").pop();
    if (last && last.trim().length) return last;
  }
  return `${fallbackId}.jpg`;
}
function mapVariantPreview(item) {
  return {
    id: typeof item.id === "string" ? item.id : "",
    name: typeof item.name === "string" ? item.name : typeof item.sku === "string" ? item.sku : "Variant",
    sku: typeof item.sku === "string" ? item.sku : null,
    thumbnailUrl: typeof item.defaultMediaUrl === "string" ? item.defaultMediaUrl : typeof item.default_media_url === "string" ? item.default_media_url : null,
    thumbnailId: null,
    thumbnailFileName: null
  };
}
async function resolveVariantThumbnail(variantId, cache) {
  if (!variantId) return null;
  if (cache.current.has(variantId)) {
    return cache.current.get(variantId) ?? null;
  }
  try {
    const payload = await apiCall(
      `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`
    );
    const items = payload.ok && payload.result?.items ? payload.result.items : [];
    const first = items.find((item) => typeof item.id === "string");
    if (first?.id) {
      const thumbnailUrl = typeof first.thumbnailUrl === "string" ? first.thumbnailUrl : buildAttachmentImageUrl(first.id, {
        width: 360,
        height: 360,
        slug: slugifyAttachmentFileName(first.fileName ?? first.id)
      });
      const info = {
        attachmentId: first.id,
        thumbnailUrl: thumbnailUrl ?? null,
        fileName: typeof first.fileName === "string" ? first.fileName : null
      };
      cache.current.set(variantId, info);
      return info;
    }
  } catch (err) {
    logger.error("sales.channels.offer.variantMedia", { err });
  }
  const empty = { attachmentId: null, thumbnailUrl: null, fileName: null };
  cache.current.set(variantId, empty);
  return empty;
}
function mapProductSearchResult(item, channelId, currentOfferId) {
  const offers = Array.isArray(item.offers) ? item.offers : [];
  const channelOffer = offers.find((entry) => {
    if (!entry || typeof entry !== "object") return false;
    const offerChannelId = typeof entry.channelId === "string" ? entry.channelId : typeof entry.channel_id === "string" ? entry.channel_id : null;
    return channelId ? offerChannelId === channelId : false;
  }) ?? null;
  const existingOfferId = channelOffer && typeof channelOffer.id === "string" ? channelOffer.id : null;
  return {
    id: typeof item.id === "string" ? item.id : "",
    title: typeof item.title === "string" ? item.title : "",
    sku: typeof item.sku === "string" ? item.sku : null,
    defaultMediaUrl: typeof item.defaultMediaUrl === "string" ? item.defaultMediaUrl : typeof item.default_media_url === "string" ? item.default_media_url : null,
    pricing: item.pricing && typeof item.pricing === "object" ? normalizePricing(item.pricing) : null,
    existingOfferId,
    existingOfferTitle: channelOffer && typeof channelOffer.title === "string" ? channelOffer.title : null,
    isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId)
  };
}
function formatPriceDisplay(pricing) {
  if (!pricing) return "\u2014";
  const amount = pricing.displayMode === "including-tax" ? pricing.unitPriceGross ?? pricing.unitPriceNet : pricing.unitPriceNet ?? pricing.unitPriceGross;
  if (!amount) return pricing.currencyCode ?? "\u2014";
  return `${pricing.currencyCode ?? ""} ${amount}`;
}
function PriceOverridesEditor({
  values,
  onChange,
  priceKinds,
  basePrice,
  onRemoveDraft
}) {
  const t = useT();
  const baseAmount = React.useMemo(() => {
    if (!basePrice) return "";
    const net = basePrice.unitPriceNet ?? null;
    const gross = basePrice.unitPriceGross ?? null;
    if (basePrice.displayMode === "including-tax") {
      return gross ?? net ?? "";
    }
    if (basePrice.displayMode === "excluding-tax") {
      return net ?? gross ?? "";
    }
    return net ?? gross ?? "";
  }, [basePrice]);
  const baseDefaults = React.useMemo(() => ({
    amount: baseAmount,
    currencyCode: basePrice?.currencyCode ?? null,
    displayMode: basePrice?.displayMode ?? null
  }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode]);
  const usedKindIdSet = React.useMemo(() => {
    const next = /* @__PURE__ */ new Set();
    values.forEach((row) => {
      if (typeof row.priceKindId === "string" && row.priceKindId.length) {
        next.add(row.priceKindId);
      }
    });
    return next;
  }, [values]);
  const availableKindCount = priceKinds.reduce(
    (count, kind) => usedKindIdSet.has(kind.id) ? count : count + 1,
    0
  );
  const canAddRow = availableKindCount > 0;
  const addRow = React.useCallback(() => {
    const usedIds = /* @__PURE__ */ new Set();
    values.forEach((row) => {
      if (typeof row.priceKindId === "string" && row.priceKindId.length) {
        usedIds.add(row.priceKindId);
      }
    });
    const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id));
    if (!nextKind && priceKinds.length) {
      return;
    }
    onChange([
      ...values,
      {
        tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),
        amount: baseDefaults.amount,
        currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,
        displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,
        priceKindId: nextKind?.id ?? null,
        priceKindCode: nextKind?.code ?? nextKind?.title ?? null
      }
    ]);
  }, [baseDefaults, onChange, priceKinds, values]);
  const updateRow = React.useCallback((tempId, patch) => {
    onChange(values.map((row) => row.tempId === tempId ? { ...row, ...patch } : row));
  }, [onChange, values]);
  const removeRow = React.useCallback(async (row) => {
    const allowRemoval = await onRemoveDraft?.(row);
    if (allowRemoval === false) return;
    onChange(values.filter((entry) => entry.tempId !== row.tempId));
  }, [onChange, onRemoveDraft, values]);
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    /* @__PURE__ */ jsxs("div", { className: "rounded border bg-muted/50 px-3 py-2", children: [
      /* @__PURE__ */ jsx("div", { className: "text-xs uppercase text-muted-foreground", children: t("sales.channels.offers.pricing.basePriceLabel", "Original product price") }),
      /* @__PURE__ */ jsx("div", { className: "text-base font-semibold", children: basePrice ? formatPriceDisplay(basePrice) : t("sales.channels.offers.pricing.basePriceMissing", "No price found") }),
      /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.pricing.basePriceHelp", "Shown to shoppers when no override is configured.") })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
      /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
        /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("sales.channels.offers.pricing.help", "Provide overrides for price kinds when this offer is active.") }),
        /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: addRow, disabled: !canAddRow, children: t("sales.channels.offers.pricing.add", "Add price") })
      ] }),
      !canAddRow ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: priceKinds.length ? t("sales.channels.offers.pricing.allKindsUsed", "Each price kind already has an override.") : t("sales.channels.offers.pricing.noKindsAvailable", "Define a price kind before adding overrides.") }) : null
    ] }),
    /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.pricing.overrideHint", "Overrides take precedence over the original product price.") }) }),
    values.length ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: values.map((row) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded border p-3 md:grid-cols-3", children: [
      /* @__PURE__ */ jsxs(
        Select,
        {
          value: row.priceKindId || void 0,
          onValueChange: (value) => {
            const next = priceKinds.find((kind) => kind.id === value);
            updateRow(row.tempId, {
              priceKindId: next?.id ?? null,
              priceKindCode: next?.code ?? next?.title ?? null,
              currencyCode: next?.currencyCode ?? null,
              displayMode: next?.displayMode ?? null
            });
          },
          children: [
            /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("sales.channels.offers.pricing.selectKind", "Select price kind") }) }),
            /* @__PURE__ */ jsx(SelectContent, { children: priceKinds.map((kind) => /* @__PURE__ */ jsx(
              SelectItem,
              {
                value: kind.id,
                disabled: usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id,
                children: kind.title ?? kind.code ?? kind.id
              },
              kind.id
            )) })
          ]
        }
      ),
      /* @__PURE__ */ jsxs("div", { className: "relative", children: [
        row.currencyCode ?? basePrice?.currencyCode ? /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground", children: row.currencyCode ?? basePrice?.currencyCode }) : null,
        /* @__PURE__ */ jsx(
          Input,
          {
            inputClassName: cn(row.currencyCode || basePrice?.currencyCode ? "pl-13" : ""),
            type: "number",
            placeholder: t("sales.channels.offers.pricing.amount", "Amount"),
            value: row.amount ?? "",
            onChange: (event) => updateRow(row.tempId, { amount: event.target.value })
          }
        )
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center", children: [
        /* @__PURE__ */ jsx("span", { children: row.displayMode === "including-tax" ? t("sales.channels.offers.pricing.includingTax", "Including tax") : t("sales.channels.offers.pricing.excludingTax", "Excluding tax") }),
        /* @__PURE__ */ jsxs(
          Button,
          {
            type: "button",
            variant: "ghost",
            size: "sm",
            className: "gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive",
            onClick: () => {
              void removeRow(row);
            },
            children: [
              /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" }),
              t("sales.channels.offers.pricing.remove", "Remove")
            ]
          }
        )
      ] })
    ] }, row.tempId)) }) : /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
      t("sales.channels.offers.pricing.empty", "No overrides yet."),
      basePrice ? /* @__PURE__ */ jsxs(Fragment, { children: [
        " ",
        t(
          "sales.channels.offers.pricing.emptyFallback",
          "Using {price} from the product until you add overrides.",
          { price: formatPriceDisplay(basePrice) }
        )
      ] }) : null
    ] })
  ] });
}
function ProductOverviewCard({ summary, variants }) {
  const t = useT();
  if (!summary) {
    return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.productSummaryPlaceholder", "Select a product to preview its media, price, and variants.") });
  }
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
      /* @__PURE__ */ jsx("div", { className: "h-16 w-16 overflow-hidden rounded border bg-muted", children: summary.defaultMediaUrl ? /* @__PURE__ */ jsx("img", { src: summary.defaultMediaUrl, alt: summary.title, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(ImageIcon, { className: "h-5 w-5" }) }) }),
      /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
        /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold", children: summary.title || t("sales.channels.offers.form.productUntitled", "Untitled product") }),
        summary.sku ? /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
          "SKU \xB7 ",
          summary.sku
        ] }) : null,
        /* @__PURE__ */ jsxs("div", { className: "text-sm", children: [
          /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
            t("sales.channels.offers.form.productPriceLabel", "Base price"),
            ":"
          ] }),
          " ",
          /* @__PURE__ */ jsx("span", { className: "font-semibold", children: formatPriceDisplay(summary.pricing) })
        ] })
      ] })
    ] }),
    summary.description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: summary.description }) : null,
    /* @__PURE__ */ jsx(ProductVariantsList, { variants })
  ] });
}
function ProductVariantsList({ variants }) {
  const t = useT();
  if (!variants.length) {
    return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.form.variantsEmpty", "No variants available for this product.") });
  }
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
    /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: t("sales.channels.offers.form.variantsTitle", "Variants") }),
    /* @__PURE__ */ jsx("div", { className: "space-y-2 max-h-64 overflow-y-auto pr-1", children: variants.map((variant) => /* @__PURE__ */ jsxs("div", { className: "flex gap-3 rounded border bg-card p-2", children: [
      /* @__PURE__ */ jsx("div", { className: "h-10 w-10 overflow-hidden rounded border bg-muted", children: variant.thumbnailUrl ? /* @__PURE__ */ jsx("img", { src: variant.thumbnailUrl, alt: variant.name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4" }) }) }),
      /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
        /* @__PURE__ */ jsx("div", { className: "text-xs font-medium", children: variant.name }),
        variant.sku ? /* @__PURE__ */ jsxs("div", { className: "text-overline text-muted-foreground", children: [
          "SKU \xB7 ",
          variant.sku
        ] }) : null
      ] })
    ] }, variant.id)) })
  ] });
}
export {
  ChannelOfferForm
};
//# sourceMappingURL=ChannelOfferForm.js.map
