"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { useSearchParams, usePathname } from "next/navigation";
import { Book, Plus, Pencil, Trash2 } from "lucide-react";
import { EmptyState } from "@open-mercato/ui/primitives/empty-state";
import { Button } from "@open-mercato/ui/primitives/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from "@open-mercato/ui/primitives/select";
import { Spinner } from "@open-mercato/ui/primitives/spinner";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { apiCall, 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 { buildRecordInjectionContext, useSetCurrentRecordInjectionContext } from "@open-mercato/ui/backend/injection/recordContext";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
import { DictionaryEntriesEditor } from "./DictionaryEntriesEditor.js";
import {
  DEFAULT_DICTIONARY_ENTRY_SORT_MODE,
  dictionaryEntrySortModes
} from "../lib/entrySort.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("dictionaries").child({ component: "DictionariesManager" });
function DictionariesManager() {
  const t = useT();
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const [items, setItems] = React.useState([]);
  const [selectedId, setSelectedId] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [dialog, setDialog] = React.useState(null);
  const [form, setForm] = React.useState({
    key: "",
    name: "",
    description: "",
    entrySortMode: DEFAULT_DICTIONARY_ENTRY_SORT_MODE
  });
  const [errors, setErrors] = React.useState({});
  const [submitting, setSubmitting] = React.useState(false);
  const [deleting, setDeleting] = React.useState(null);
  const selectionFromQueryApplied = React.useRef(false);
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: "dictionaries:dictionary",
    blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const inheritedManageMessage = t("dictionaries.config.error.inheritedManage", "Inherited dictionaries must be managed at the parent organization.");
  const requestedDictionaryId = searchParams?.get("dictionaryId") ?? null;
  const requestedDictionaryKey = searchParams?.get("key")?.trim().toLowerCase() ?? null;
  const entrySortOptions = React.useMemo(
    () => dictionaryEntrySortModes.map((mode) => ({
      value: mode,
      label: mode === "label_asc" ? t("dictionaries.config.sortModes.labelAsc", "A to Z") : mode === "label_desc" ? t("dictionaries.config.sortModes.labelDesc", "Z to A") : mode === "value_asc" ? t("dictionaries.config.sortModes.valueAsc", "Value A to Z") : mode === "value_desc" ? t("dictionaries.config.sortModes.valueDesc", "Value Z to A") : mode === "created_at_asc" ? t("dictionaries.config.sortModes.createdAtAsc", "Oldest first") : t("dictionaries.config.sortModes.createdAtDesc", "Newest first")
    })),
    [t]
  );
  const loadDictionaries = React.useCallback(async () => {
    setLoading(true);
    try {
      const call = await apiCall("/api/dictionaries");
      if (!call.ok) {
        throw new Error(typeof call.result?.error === "string" ? call.result.error : "Failed to load dictionaries");
      }
      const resultItems = Array.isArray(call.result?.items) ? call.result.items : [];
      const list = Array.isArray(resultItems) ? resultItems.map((item) => ({
        id: String(item.id),
        key: String(item.key),
        name: String(item.name ?? item.key),
        description: typeof item.description === "string" ? item.description : null,
        isSystem: Boolean(item.isSystem),
        isActive: item.isActive !== false,
        entrySortMode: dictionaryEntrySortModes.includes(item.entrySortMode) ? item.entrySortMode : DEFAULT_DICTIONARY_ENTRY_SORT_MODE,
        organizationId: typeof item.organizationId === "string" ? item.organizationId : "",
        isInherited: item.isInherited === true,
        managerVisibility: item.managerVisibility === "hidden" ? "hidden" : "default",
        updatedAt: typeof item.updatedAt === "string" ? item.updatedAt : null
      })) : [];
      const filtered = list.filter((dictionary) => dictionary.managerVisibility !== "hidden");
      setItems(filtered);
      setSelectedId((current) => {
        if (current && filtered.some((dict) => dict.id === current)) {
          return current;
        }
        return filtered.length ? filtered[0].id : null;
      });
    } catch (err) {
      logger.error("Failed to load dictionaries", { err });
      flash(t("dictionaries.config.error.load", "Failed to load dictionaries."), "error");
    } finally {
      setLoading(false);
    }
  }, [t]);
  React.useEffect(() => {
    loadDictionaries().catch(() => {
    });
  }, [loadDictionaries]);
  React.useEffect(() => {
    if (selectionFromQueryApplied.current) return;
    if (!items.length) return;
    if (!requestedDictionaryId && !requestedDictionaryKey) return;
    if (requestedDictionaryId) {
      const match = items.find((dictionary) => dictionary.id === requestedDictionaryId);
      if (match && selectedId !== match.id) {
        setSelectedId(match.id);
      }
      selectionFromQueryApplied.current = true;
      return;
    }
    if (requestedDictionaryKey) {
      const match = items.find((dictionary) => dictionary.key.toLowerCase() === requestedDictionaryKey);
      if (match && selectedId !== match.id) {
        setSelectedId(match.id);
      }
      selectionFromQueryApplied.current = true;
    }
  }, [items, requestedDictionaryId, requestedDictionaryKey, selectedId]);
  const openCreateDialog = React.useCallback(() => {
    setForm({
      key: "",
      name: "",
      description: "",
      entrySortMode: DEFAULT_DICTIONARY_ENTRY_SORT_MODE
    });
    setDialog({ mode: "create" });
    setErrors({});
  }, []);
  const openEditDialog = React.useCallback((dictionary) => {
    if (dictionary.isInherited) {
      flash(inheritedManageMessage, "info");
      return;
    }
    setForm({
      key: dictionary.key,
      name: dictionary.name,
      description: dictionary.description ?? "",
      entrySortMode: dictionary.entrySortMode
    });
    setDialog({ mode: "edit", dictionary });
    setErrors({});
  }, [inheritedManageMessage]);
  const closeDialog = React.useCallback(() => {
    setDialog(null);
    setForm({
      key: "",
      name: "",
      description: "",
      entrySortMode: DEFAULT_DICTIONARY_ENTRY_SORT_MODE
    });
    setErrors({});
  }, []);
  const handleSubmit = React.useCallback(async () => {
    if (!dialog) return;
    if (dialog.mode === "edit" && dialog.dictionary?.isInherited) {
      flash(inheritedManageMessage, "info");
      return;
    }
    const trimmedKey = form.key.trim();
    const trimmedName = form.name.trim();
    const nextErrors = {};
    if (!trimmedKey) {
      nextErrors.key = t("dictionaries.config.dialog.keyErrorRequired", "Key is required.");
    } else if (trimmedKey.length > 100) {
      nextErrors.key = t("dictionaries.config.dialog.keyErrorLength", "Key must be at most 100 characters long.");
    } else if (!/^[a-z0-9][a-z0-9_-]*$/.test(trimmedKey)) {
      nextErrors.key = t("dictionaries.config.dialog.keyErrorPattern", "Use lowercase letters, numbers, hyphen, or underscore.");
    }
    if (!trimmedName) {
      nextErrors.name = t("dictionaries.config.dialog.nameErrorRequired", "Name is required.");
    }
    if (nextErrors.key || nextErrors.name) {
      setErrors(nextErrors);
      return;
    }
    setSubmitting(true);
    try {
      const payload = {
        key: trimmedKey,
        name: trimmedName,
        description: form.description.trim() || void 0,
        entrySortMode: form.entrySortMode
      };
      if (dialog.mode === "create") {
        await runMutation({
          operation: async () => {
            const call = await apiCall("/api/dictionaries", {
              method: "POST",
              headers: { "content-type": "application/json" },
              body: JSON.stringify(payload)
            });
            if (!call.ok) {
              throw new Error(typeof call.result?.error === "string" ? call.result.error : "Failed to create dictionary");
            }
            return call;
          },
          context: {
            formId: "dictionaries:dictionary",
            resourceKind: "dictionaries.dictionary",
            retryLastMutation
          },
          mutationPayload: payload
        });
        flash(t("dictionaries.config.success.create", "Dictionary created."), "success");
      } else if (dialog.dictionary) {
        const dictionaryId = dialog.dictionary.id;
        const expectedUpdatedAt = dialog.dictionary.updatedAt;
        await runMutation({
          operation: () => withScopedApiRequestHeaders(
            buildOptimisticLockHeader(expectedUpdatedAt),
            async () => {
              const call = await apiCall(`/api/dictionaries/${dictionaryId}`, {
                method: "PATCH",
                headers: { "content-type": "application/json" },
                body: JSON.stringify(payload)
              });
              if (!call.ok) {
                throw Object.assign(
                  new Error(typeof call.result?.error === "string" ? call.result.error : "Failed to update dictionary"),
                  { status: call.status, ...call.result && typeof call.result === "object" ? call.result : {} }
                );
              }
              return call;
            }
          ),
          context: {
            formId: "dictionaries:dictionary",
            resourceKind: "dictionaries.dictionary",
            resourceId: dictionaryId,
            retryLastMutation
          },
          mutationPayload: payload
        });
        flash(t("dictionaries.config.success.update", "Dictionary updated."), "success");
      }
      closeDialog();
      await loadDictionaries();
      setErrors({});
    } catch (err) {
      if (surfaceRecordConflict(err, t)) {
        return;
      }
      logger.error("Failed to save dictionary", { err });
      flash(t("dictionaries.config.error.save", "Failed to save dictionary."), "error");
    } finally {
      setSubmitting(false);
    }
  }, [closeDialog, dialog, form.description, form.entrySortMode, form.key, form.name, inheritedManageMessage, loadDictionaries, runMutation, retryLastMutation, t]);
  const handleDelete = React.useCallback(
    async (dictionary) => {
      if (dictionary.isInherited) {
        flash(inheritedManageMessage, "info");
        return;
      }
      if (dictionary.isSystem) {
        flash(t("dictionaries.config.error.system", "System dictionaries cannot be deleted."), "error");
        return;
      }
      const rawConfirm = t("dictionaries.config.delete.confirm", { name: dictionary.name });
      const confirmMessage = rawConfirm && rawConfirm !== "dictionaries.config.delete.confirm" ? rawConfirm : `Delete dictionary "${dictionary.name}"?`;
      const confirmed = await confirm({
        title: confirmMessage,
        variant: "destructive"
      });
      if (!confirmed) return;
      setDeleting(dictionary.id);
      try {
        await runMutation({
          operation: () => withScopedApiRequestHeaders(
            buildOptimisticLockHeader(dictionary.updatedAt),
            async () => {
              const call = await apiCall(`/api/dictionaries/${dictionary.id}`, { method: "DELETE" });
              if (!call.ok) {
                throw Object.assign(
                  new Error(typeof call.result?.error === "string" ? call.result.error : "Failed to delete dictionary"),
                  { status: call.status, ...call.result && typeof call.result === "object" ? call.result : {} }
                );
              }
              return call;
            }
          ),
          context: {
            formId: "dictionaries:dictionary",
            resourceKind: "dictionaries.dictionary",
            resourceId: dictionary.id,
            retryLastMutation
          },
          mutationPayload: { id: dictionary.id }
        });
        flash(t("dictionaries.config.success.delete", "Dictionary deleted."), "success");
        await loadDictionaries();
      } catch (err) {
        if (surfaceRecordConflict(err, t)) {
          return;
        }
        logger.error("Failed to delete dictionary", { err });
        flash(t("dictionaries.config.error.delete", "Failed to delete dictionary."), "error");
      } finally {
        setDeleting(null);
      }
    },
    [confirm, inheritedManageMessage, loadDictionaries, runMutation, retryLastMutation, t]
  );
  const selectedDictionary = items.find((item) => item.id === selectedId) ?? null;
  useSetCurrentRecordInjectionContext(
    buildRecordInjectionContext({
      resourceKind: "dictionaries.dictionary",
      resourceId: selectedDictionary?.id ?? null,
      updatedAt: selectedDictionary?.updatedAt ?? null,
      data: selectedDictionary ?? null,
      path: pathname
    })
  );
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[320px_1fr]", children: [
    /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4 shadow-sm", children: [
      /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
        /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold", children: t("dictionaries.config.list.title", "Dictionaries") }),
        /* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: openCreateDialog, children: [
          /* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4" }),
          t("dictionaries.config.list.add", "New dictionary")
        ] })
      ] }),
      /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-2", children: loading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
        /* @__PURE__ */ jsx(Spinner, { className: "h-4 w-4" }),
        t("dictionaries.config.list.loading", "Loading dictionaries\u2026")
      ] }) : items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("dictionaries.config.list.empty", "No dictionaries yet. Create one to get started.") }) : /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: items.map((dictionary) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
        "div",
        {
          role: "button",
          tabIndex: 0,
          "aria-pressed": dictionary.id === selectedId,
          className: `flex w-full cursor-pointer select-none items-center justify-between rounded border px-3 py-2 text-left text-sm transition ${dictionary.id === selectedId ? "border-primary bg-primary/5 text-primary" : "border-border hover:bg-muted"}`,
          onClick: () => setSelectedId(dictionary.id),
          onKeyDown: (event) => {
            if (event.key === "Enter" || event.key === " ") {
              event.preventDefault();
              setSelectedId(dictionary.id);
            }
          },
          children: [
            /* @__PURE__ */ jsxs("div", { children: [
              /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 font-medium", children: [
                /* @__PURE__ */ jsx("span", { children: dictionary.name }),
                dictionary.isInherited ? /* @__PURE__ */ jsx("span", { className: "rounded-full border border-border px-2 py-0.5 text-overline font-normal uppercase tracking-wide text-muted-foreground", children: t("dictionaries.config.list.inherited", "Inherited") }) : null
              ] }),
              /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: dictionary.key })
            ] }),
            /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
              /* @__PURE__ */ jsx(
                Button,
                {
                  type: "button",
                  size: "icon",
                  variant: "ghost",
                  disabled: dictionary.isInherited,
                  title: dictionary.isInherited ? inheritedManageMessage : void 0,
                  onClick: (event) => {
                    event.stopPropagation();
                    openEditDialog(dictionary);
                  },
                  children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
                }
              ),
              /* @__PURE__ */ jsx(
                Button,
                {
                  type: "button",
                  size: "icon",
                  variant: "ghost",
                  disabled: dictionary.isInherited || deleting === dictionary.id,
                  title: dictionary.isInherited ? inheritedManageMessage : void 0,
                  onClick: (event) => {
                    event.stopPropagation();
                    handleDelete(dictionary);
                  },
                  children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
                }
              )
            ] })
          ]
        }
      ) }, dictionary.id)) }) })
    ] }),
    /* @__PURE__ */ jsx("div", { children: selectedDictionary ? /* @__PURE__ */ jsx(
      DictionaryEntriesEditor,
      {
        dictionaryId: selectedDictionary.id,
        dictionaryName: selectedDictionary.name,
        readOnly: selectedDictionary.isInherited
      }
    ) : /* @__PURE__ */ jsx(
      EmptyState,
      {
        icon: /* @__PURE__ */ jsx(Book, { className: "h-8 w-8", "aria-hidden": "true" }),
        title: t("dictionaries.config.entries.placeholder", "Select a dictionary to manage its entries."),
        className: "h-full"
      }
    ) }),
    /* @__PURE__ */ jsx(Dialog, { open: dialog != null, onOpenChange: (open) => open ? void 0 : closeDialog(), children: /* @__PURE__ */ jsxs(DialogContent, { children: [
      /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: dialog?.mode === "create" ? t("dictionaries.config.dialog.createTitle", "Create dictionary") : t("dictionaries.config.dialog.editTitle", "Edit dictionary") }) }),
      /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
        /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("dictionaries.config.dialog.keyLabel", "Key") }),
          /* @__PURE__ */ jsx(
            "input",
            {
              value: form.key,
              onChange: (event) => {
                const next = event.target.value;
                setForm((prev) => ({ ...prev, key: next }));
                if (errors.key) setErrors((prev) => ({ ...prev, key: void 0 }));
              },
              placeholder: t("dictionaries.config.dialog.keyPlaceholder", "slug_name"),
              disabled: dialog?.mode === "edit",
              className: `w-full rounded border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:bg-muted ${errors.key ? "border-destructive focus-visible:ring-destructive" : ""}`,
              "aria-invalid": errors.key ? "true" : "false",
              "aria-describedby": "dictionary-key-hint"
            }
          ),
          /* @__PURE__ */ jsx(
            "p",
            {
              id: "dictionary-key-hint",
              className: `text-xs ${errors.key ? "text-destructive" : "text-muted-foreground"}`,
              children: errors.key ?? t("dictionaries.config.dialog.keyHint", "Use lowercase letters, numbers, hyphen, or underscore.")
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("dictionaries.config.dialog.nameLabel", "Name") }),
          /* @__PURE__ */ jsx(
            "input",
            {
              value: form.name,
              onChange: (event) => {
                const next = event.target.value;
                setForm((prev) => ({ ...prev, name: next }));
                if (errors.name) setErrors((prev) => ({ ...prev, name: void 0 }));
              },
              placeholder: t("dictionaries.config.dialog.namePlaceholder", "Display name"),
              className: `w-full rounded border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${errors.name ? "border-destructive focus-visible:ring-destructive" : ""}`,
              "aria-invalid": errors.name ? "true" : "false"
            }
          ),
          errors.name ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: errors.name }) : null
        ] }),
        /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("dictionaries.config.dialog.descriptionLabel", "Description") }),
          /* @__PURE__ */ jsx(
            "textarea",
            {
              value: form.description,
              onChange: (event) => setForm((prev) => ({ ...prev, description: event.target.value })),
              className: "min-h-[120px] w-full rounded border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
              placeholder: t("dictionaries.config.dialog.descriptionPlaceholder", "Explain how this dictionary is used (optional).")
            }
          )
        ] }),
        /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("dictionaries.config.dialog.entrySortModeLabel", "Entry sort order") }),
          /* @__PURE__ */ jsxs(
            Select,
            {
              value: form.entrySortMode,
              onValueChange: (next) => setForm((prev) => ({
                ...prev,
                entrySortMode: dictionaryEntrySortModes.includes(next) ? next : DEFAULT_DICTIONARY_ENTRY_SORT_MODE
              })),
              children: [
                /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
                /* @__PURE__ */ jsx(SelectContent, { children: entrySortOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
              ]
            }
          ),
          /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("dictionaries.config.dialog.entrySortModeHelp", "Controls the order returned by dictionary entry APIs and dropdowns.") })
        ] })
      ] }),
      /* @__PURE__ */ jsxs(DialogFooter, { children: [
        /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", onClick: closeDialog, disabled: submitting, children: t("dictionaries.config.dialog.cancel", "Cancel") }),
        /* @__PURE__ */ jsxs(Button, { type: "button", onClick: handleSubmit, disabled: submitting, children: [
          submitting ? /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }) : null,
          t("dictionaries.config.dialog.save", "Save")
        ] })
      ] })
    ] }) }),
    ConfirmDialogElement
  ] });
}
export {
  DictionariesManager
};
//# sourceMappingURL=DictionariesManager.js.map
