"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { DataTable } from "@open-mercato/ui/backend/DataTable";
import { RowActions } from "@open-mercato/ui/backend/RowActions";
import { Button } from "@open-mercato/ui/primitives/button";
import { Input } from "@open-mercato/ui/primitives/input";
import { Label } from "@open-mercato/ui/primitives/label";
import { RadioGroup, Radio } from "@open-mercato/ui/primitives/radio";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from "@open-mercato/ui/primitives/dialog";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
import { raiseCrudError } from "@open-mercato/ui/backend/utils/serverErrors";
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
import { DictionaryEntrySelect } from "@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect";
import { useCurrencyDictionary } from "@open-mercato/core/modules/customers/components/detail/hooks/useCurrencyDictionary";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("catalog");
const DISPLAY_MODES = [
  { value: "excluding-tax", label: "Excluding tax" },
  { value: "including-tax", label: "Including tax" }
];
const PAGE_SIZE = 100;
const DEFAULT_FORM = {
  code: "",
  title: "",
  displayMode: "excluding-tax",
  currencyCode: "",
  isPromotion: false,
  isActive: true
};
const normalizePriceKind = (input) => {
  const raw = input ?? {};
  const toStringValue = (value) => {
    if (typeof value === "string") return value;
    if (typeof value === "number" || typeof value === "bigint") return String(value);
    return null;
  };
  const toBooleanValue = (value) => typeof value === "boolean" ? value : null;
  const resolveDisplayMode = (value) => value === "including-tax" ? "including-tax" : "excluding-tax";
  const displayMode = resolveDisplayMode(
    toStringValue(raw.displayMode) ?? toStringValue(raw.display_mode)
  );
  const currencyCode = toStringValue(raw.currencyCode) ?? toStringValue(raw.currency_code);
  const isPromotion = toBooleanValue(raw.isPromotion) ?? toBooleanValue(raw.is_promotion);
  const isActive = toBooleanValue(raw.isActive) ?? toBooleanValue(raw.is_active);
  return {
    id: toStringValue(raw.id) ?? "",
    code: toStringValue(raw.code) ?? "",
    title: toStringValue(raw.title) ?? "",
    displayMode,
    currencyCode: currencyCode ?? null,
    isPromotion: isPromotion ?? false,
    isActive: isActive ?? true,
    createdAt: toStringValue(raw.createdAt) ?? toStringValue(raw.created_at) ?? "",
    updatedAt: toStringValue(raw.updatedAt) ?? toStringValue(raw.updated_at) ?? ""
  };
};
function PriceKindSettings() {
  const t = useT();
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const scopeVersion = useOrganizationScopeVersion();
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [search, setSearch] = React.useState("");
  const [dialog, setDialog] = React.useState(null);
  const [form, setForm] = React.useState(DEFAULT_FORM);
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState(null);
  const { data: currencyDictionary, refetch: refetchCurrencyDictionary } = useCurrencyDictionary();
  const currencyOptionsLoader = React.useCallback(async () => {
    if (currencyDictionary && Array.isArray(currencyDictionary.entries)) {
      return currencyDictionary.entries.map((entry) => ({
        value: entry.value,
        label: entry.label,
        color: entry.color ?? null,
        icon: entry.icon ?? null
      }));
    }
    const payload = await refetchCurrencyDictionary();
    return payload.entries.map((entry) => ({
      value: entry.value,
      label: entry.label,
      color: entry.color ?? null,
      icon: entry.icon ?? null
    }));
  }, [currencyDictionary, refetchCurrencyDictionary]);
  const loadItems = React.useCallback(async () => {
    setLoading(true);
    const loadErrorMessage = t("catalog.priceKinds.errors.load", "Failed to load price kinds.");
    try {
      const payload = await readApiResultOrThrow(
        `/api/catalog/price-kinds?pageSize=${PAGE_SIZE}`,
        void 0,
        { errorMessage: loadErrorMessage }
      );
      const normalized = Array.isArray(payload.items) ? payload.items.map((item) => normalizePriceKind(item)) : [];
      setItems(normalized);
    } catch (err) {
      logger.error("catalog.price-kinds.list failed", { err });
      flash(loadErrorMessage, "error");
    } finally {
      setLoading(false);
    }
  }, [t]);
  React.useEffect(() => {
    loadItems().catch(() => {
    });
  }, [loadItems, scopeVersion]);
  const openDialog = React.useCallback((state) => {
    if (state.mode === "edit") {
      setForm({
        code: state.entry.code,
        title: state.entry.title,
        displayMode: state.entry.displayMode,
        currencyCode: state.entry.currencyCode ?? "",
        isPromotion: state.entry.isPromotion,
        isActive: state.entry.isActive
      });
    } else {
      setForm(DEFAULT_FORM);
    }
    setError(null);
    setDialog(state);
  }, []);
  const closeDialog = React.useCallback(() => {
    setDialog(null);
    setError(null);
    setSubmitting(false);
    setForm(DEFAULT_FORM);
  }, []);
  const handleSubmit = React.useCallback(async () => {
    if (!dialog) return;
    const trimmedCode = form.code.trim().toLowerCase();
    const trimmedTitle = form.title.trim();
    if (!trimmedCode || !trimmedTitle) {
      setError(t("catalog.priceKinds.errors.required", "Code and title are required."));
      return;
    }
    setSubmitting(true);
    setError(null);
    try {
      const payload = {
        code: trimmedCode,
        title: trimmedTitle,
        displayMode: form.displayMode,
        currencyCode: form.currencyCode.trim() || void 0,
        isPromotion: form.isPromotion,
        isActive: form.isActive
      };
      const path = "/api/catalog/price-kinds";
      const method = dialog.mode === "create" ? "POST" : "PUT";
      const body = dialog.mode === "edit" ? JSON.stringify({ id: dialog.entry.id, ...payload }) : JSON.stringify(payload);
      const savePriceKind = () => apiCall(path, {
        method,
        headers: { "content-type": "application/json" },
        body
      });
      const optimisticLockHeader = buildOptimisticLockHeader(
        dialog.mode === "edit" ? dialog.entry.updatedAt : null
      );
      const call = Object.keys(optimisticLockHeader).length > 0 ? await withScopedApiRequestHeaders(optimisticLockHeader, savePriceKind) : await savePriceKind();
      if (!call.ok) {
        await raiseCrudError(call.response, t("catalog.priceKinds.errors.save", "Failed to save price kind."));
      }
      flash(
        dialog.mode === "create" ? t("catalog.priceKinds.messages.created", "Price kind created.") : t("catalog.priceKinds.messages.updated", "Price kind updated."),
        "success"
      );
      closeDialog();
      await loadItems();
    } catch (err) {
      logger.error("catalog.price-kinds.save failed", { err });
      if (surfaceRecordConflict(err, t, { onRefresh: () => {
        void loadItems();
      } })) {
        closeDialog();
        return;
      }
      const message = err instanceof Error ? err.message : t("catalog.priceKinds.errors.save", "Failed to save price kind.");
      setError(message);
    } finally {
      setSubmitting(false);
    }
  }, [dialog, form, t, closeDialog, loadItems]);
  const handleDelete = React.useCallback(
    async (entry) => {
      const confirmMessage = t("catalog.priceKinds.confirm.delete", 'Delete price kind "{{code}}"?').replace("{{code}}", entry.code);
      const confirmed = await confirm({
        title: confirmMessage,
        variant: "destructive"
      });
      if (!confirmed) return;
      try {
        const deletePriceKind = () => apiCall("/api/catalog/price-kinds", {
          method: "DELETE",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ id: entry.id })
        });
        const optimisticLockHeader = buildOptimisticLockHeader(entry.updatedAt);
        const call = Object.keys(optimisticLockHeader).length > 0 ? await withScopedApiRequestHeaders(optimisticLockHeader, deletePriceKind) : await deletePriceKind();
        if (!call.ok) {
          await raiseCrudError(call.response, t("catalog.priceKinds.errors.delete", "Failed to delete price kind."));
        }
        flash(t("catalog.priceKinds.messages.deleted", "Price kind deleted."), "success");
        await loadItems();
      } catch (err) {
        logger.error("catalog.price-kinds.delete failed", { err });
        if (surfaceRecordConflict(err, t, { onRefresh: () => {
          void loadItems();
        } })) return;
        const message = err instanceof Error ? err.message : t("catalog.priceKinds.errors.delete", "Failed to delete price kind.");
        flash(message, "error");
      }
    },
    [confirm, loadItems, t]
  );
  const formKeyHandler = React.useCallback(
    (event) => {
      if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
        event.preventDefault();
        void handleSubmit();
      }
    },
    [handleSubmit]
  );
  const displayModeLabels = React.useMemo(() => ({
    "including-tax": t("catalog.priceKinds.form.displayMode.include", "Including tax"),
    "excluding-tax": t("catalog.priceKinds.form.displayMode.exclude", "Excluding tax")
  }), [t]);
  const displayModeOptions = React.useMemo(
    () => DISPLAY_MODES.map((mode) => ({
      ...mode,
      label: displayModeLabels[mode.value]
    })),
    [displayModeLabels]
  );
  const currencyLabels = React.useMemo(() => ({
    placeholder: t("catalog.priceKinds.form.currency.placeholder", "Select currency\u2026"),
    addLabel: t("catalog.priceKinds.form.currency.add", "Add currency"),
    addPrompt: t("catalog.priceKinds.form.currency.addPrompt", "Provide a currency code."),
    dialogTitle: t("catalog.priceKinds.form.currency.dialogTitle", "Add currency"),
    valueLabel: t("catalog.priceKinds.form.currency.valueLabel", "Currency code"),
    valuePlaceholder: t("catalog.priceKinds.form.currency.valuePlaceholder", "e.g. USD"),
    labelLabel: t("catalog.priceKinds.form.currency.labelLabel", "Display label (optional)"),
    labelPlaceholder: t("catalog.priceKinds.form.currency.labelPlaceholder", "e.g. US Dollar"),
    emptyError: t("catalog.priceKinds.form.currency.required", "Currency code is required."),
    cancelLabel: t("catalog.priceKinds.form.currency.cancel", "Cancel"),
    saveLabel: t("catalog.priceKinds.form.currency.save", "Save"),
    saveShortcutHint: t("catalog.priceKinds.form.currency.saveShortcut", "Press Enter to save"),
    successCreateLabel: t("catalog.priceKinds.form.currency.success", "Currency added."),
    errorLoad: t("catalog.priceKinds.form.currency.loadError", "Unable to load currencies."),
    errorSave: t("catalog.priceKinds.form.currency.createError", "Unable to add currency."),
    loadingLabel: t("catalog.priceKinds.form.currency.loading", "Loading currencies\u2026"),
    manageTitle: t("catalog.priceKinds.form.currency.manage", "Manage currencies")
  }), [t]);
  const tableLabels = React.useMemo(() => ({
    code: t("catalog.priceKinds.table.code", "Code"),
    title: t("catalog.priceKinds.table.title", "Title"),
    displayMode: t("catalog.priceKinds.table.displayMode", "Display mode"),
    currency: t("catalog.priceKinds.table.currency", "Currency"),
    promotion: t("catalog.priceKinds.table.promotion", "Promotion"),
    promotionYes: t("catalog.priceKinds.table.promotionYes", "Yes"),
    promotionNo: t("catalog.priceKinds.table.promotionNo", "No"),
    active: t("catalog.priceKinds.table.active", "Active"),
    activeYes: t("catalog.priceKinds.table.activeYes", "Active"),
    activeNo: t("catalog.priceKinds.table.activeNo", "Inactive"),
    search: t("catalog.priceKinds.search.placeholder", "Search by code or title\u2026"),
    empty: t("catalog.priceKinds.table.empty", "No price kinds yet.")
  }), [t]);
  const columns = React.useMemo(() => [
    {
      accessorKey: "code",
      header: tableLabels.code,
      cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-mono uppercase", children: row.original.code })
    },
    {
      accessorKey: "title",
      header: tableLabels.title,
      cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-medium", children: row.original.title })
    },
    {
      accessorKey: "displayMode",
      header: tableLabels.displayMode,
      cell: ({ row }) => displayModeLabels[row.original.displayMode] ?? row.original.displayMode
    },
    {
      accessorKey: "currencyCode",
      header: tableLabels.currency,
      cell: ({ row }) => row.original.currencyCode ? row.original.currencyCode.toUpperCase() : "\u2014"
    },
    {
      id: "promotion",
      header: tableLabels.promotion,
      cell: ({ row }) => row.original.isPromotion ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border border-amber-200 bg-amber-50 px-2 py-0.5 text-xs font-medium text-amber-900 dark:border-amber-500/50 dark:bg-amber-500/10 dark:text-amber-100", children: tableLabels.promotionYes }) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium", children: tableLabels.promotionNo })
    },
    {
      id: "active",
      header: tableLabels.active,
      cell: ({ row }) => row.original.isActive ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border border-emerald-200 bg-emerald-50 px-2 py-0.5 text-xs font-medium text-emerald-900 dark:border-emerald-500/50 dark:bg-emerald-500/10 dark:text-emerald-100", children: tableLabels.activeYes }) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium", children: tableLabels.activeNo })
    }
  ], [displayModeLabels, tableLabels]);
  const filteredItems = React.useMemo(() => {
    const term = search.trim().toLowerCase();
    if (!term) return items;
    return items.filter((item) => {
      const currency = (item.currencyCode ?? "").toLowerCase();
      const modeLabel = (displayModeLabels[item.displayMode] ?? item.displayMode).toLowerCase();
      return item.code.toLowerCase().includes(term) || item.title.toLowerCase().includes(term) || currency.includes(term) || modeLabel.includes(term);
    });
  }, [displayModeLabels, items, search]);
  const handleRowClick = React.useCallback((entry) => {
    openDialog({ mode: "edit", entry });
  }, [openDialog]);
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsxs("section", { className: "border bg-card text-card-foreground shadow-sm", children: [
      /* @__PURE__ */ jsxs("div", { className: "border-b px-6 py-4 space-y-1", children: [
        /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("catalog.priceKinds.title", "Price kinds") }),
        /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("catalog.priceKinds.description", "Configure reusable price kinds that control pricing columns and tax display.") })
      ] }),
      /* @__PURE__ */ jsx("div", { className: "px-2 py-4 sm:px-4", children: /* @__PURE__ */ jsx(
        DataTable,
        {
          data: filteredItems,
          columns,
          embedded: true,
          isLoading: loading,
          searchValue: search,
          onSearchChange: setSearch,
          searchPlaceholder: tableLabels.search,
          emptyState: /* @__PURE__ */ jsx("p", { className: "py-8 text-center text-sm text-muted-foreground", children: tableLabels.empty }),
          actions: /* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => openDialog({ mode: "create" }), children: t("catalog.priceKinds.actions.add", "Add price kind") }),
          refreshButton: {
            label: t("catalog.priceKinds.actions.refresh", "Refresh"),
            onRefresh: () => {
              void loadItems();
            },
            isRefreshing: loading
          },
          rowActions: (entry) => /* @__PURE__ */ jsx(
            RowActions,
            {
              items: [
                {
                  id: "edit",
                  label: t("catalog.priceKinds.actions.edit", "Edit"),
                  onSelect: () => openDialog({ mode: "edit", entry })
                },
                {
                  id: "delete",
                  label: t("catalog.priceKinds.actions.delete", "Delete"),
                  destructive: true,
                  onSelect: () => {
                    void handleDelete(entry);
                  }
                }
              ]
            }
          ),
          onRowClick: handleRowClick
        }
      ) }),
      /* @__PURE__ */ jsx(Dialog, { open: dialog !== null, onOpenChange: (open) => {
        if (!open) closeDialog();
      }, children: /* @__PURE__ */ jsxs(DialogContent, { children: [
        /* @__PURE__ */ jsxs(DialogHeader, { children: [
          /* @__PURE__ */ jsx(DialogTitle, { children: dialog?.mode === "edit" ? t("catalog.priceKinds.dialog.editTitle", "Edit price kind") : t("catalog.priceKinds.dialog.createTitle", "Create price kind") }),
          /* @__PURE__ */ jsx(DialogDescription, { children: dialog?.mode === "edit" ? t("catalog.priceKinds.dialog.editDescription", "Update labels or tax behavior for this price kind.") : t("catalog.priceKinds.dialog.createDescription", "Define a reusable price kind for product pricing.") })
        ] }),
        /* @__PURE__ */ jsxs("form", { className: "space-y-4", onKeyDown: formKeyHandler, onSubmit: (event) => {
          event.preventDefault();
          void handleSubmit();
        }, children: [
          /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
            /* @__PURE__ */ jsx(Label, { htmlFor: "price-kind-code", children: t("catalog.priceKinds.form.codeLabel", "Code") }),
            /* @__PURE__ */ jsx(
              Input,
              {
                id: "price-kind-code",
                value: form.code,
                onChange: (event) => setForm((prev) => ({ ...prev, code: event.target.value })),
                placeholder: t("catalog.priceKinds.form.codePlaceholder", "e.g. regular"),
                className: "font-mono uppercase",
                disabled: dialog?.mode === "edit"
              }
            )
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
            /* @__PURE__ */ jsx(Label, { htmlFor: "price-kind-title", children: t("catalog.priceKinds.form.titleLabel", "Title") }),
            /* @__PURE__ */ jsx(
              Input,
              {
                id: "price-kind-title",
                value: form.title,
                onChange: (event) => setForm((prev) => ({ ...prev, title: event.target.value })),
                placeholder: t("catalog.priceKinds.form.titlePlaceholder", "e.g. Regular price")
              }
            )
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
            /* @__PURE__ */ jsx(Label, { children: t("catalog.priceKinds.form.displayModeLabel", "Display mode") }),
            /* @__PURE__ */ jsx(
              RadioGroup,
              {
                className: "grid gap-2 md:grid-cols-2",
                name: "displayMode",
                value: form.displayMode,
                onValueChange: (next) => setForm((prev) => ({ ...prev, displayMode: next })),
                children: displayModeOptions.map((mode) => /* @__PURE__ */ jsxs(
                  "label",
                  {
                    className: `flex cursor-pointer items-center gap-2 rounded-md border p-3 text-sm ${form.displayMode === mode.value ? "border-primary bg-primary/5" : "border-border"}`,
                    children: [
                      /* @__PURE__ */ jsx(Radio, { value: mode.value }),
                      /* @__PURE__ */ jsx("span", { children: mode.label })
                    ]
                  },
                  mode.value
                ))
              }
            )
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
            /* @__PURE__ */ jsx(Label, { children: t("catalog.priceKinds.form.currencyLabel", "Currency (optional)") }),
            /* @__PURE__ */ jsx(
              DictionaryEntrySelect,
              {
                value: form.currencyCode || void 0,
                onChange: (value) => setForm((prev) => ({ ...prev, currencyCode: value ?? "" })),
                fetchOptions: currencyOptionsLoader,
                labels: currencyLabels,
                allowInlineCreate: false,
                sortOptions: "none"
              }
            )
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
            /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "checkbox",
                  className: "h-4 w-4 rounded border",
                  checked: form.isPromotion,
                  onChange: (event) => setForm((prev) => ({ ...prev, isPromotion: event.target.checked }))
                }
              ),
              t("catalog.priceKinds.form.promotionLabel", "Mark as promotion")
            ] }),
            /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "checkbox",
                  className: "h-4 w-4 rounded border",
                  checked: form.isActive,
                  onChange: (event) => setForm((prev) => ({ ...prev, isActive: event.target.checked }))
                }
              ),
              t("catalog.priceKinds.form.activeLabel", "Active")
            ] })
          ] }),
          error ? /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: error }) : null
        ] }),
        /* @__PURE__ */ jsxs(DialogFooter, { children: [
          /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: closeDialog, children: t("catalog.priceKinds.actions.cancel", "Cancel") }),
          /* @__PURE__ */ jsx(Button, { onClick: () => void handleSubmit(), disabled: submitting, children: dialog?.mode === "edit" ? t("catalog.priceKinds.actions.saveChanges", "Save changes") : t("catalog.priceKinds.actions.create", "Create") })
        ] })
      ] }) })
    ] }),
    ConfirmDialogElement
  ] });
}
export {
  PriceKindSettings
};
//# sourceMappingURL=PriceKindSettings.js.map
