"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { filterCustomFieldDefs, useCustomFieldDefs } from "@open-mercato/ui/backend/utils/customFieldDefs";
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
import { DataTable } from "@open-mercato/ui/backend/DataTable";
import { ContextHelp } from "@open-mercato/ui/backend/ContextHelp";
import { Button } from "@open-mercato/ui/primitives/button";
import { RowActions } from "@open-mercato/ui/backend/RowActions";
import Link from "next/link";
import { apiCall, readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { raiseCrudError } from "@open-mercato/ui/backend/utils/serverErrors";
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { ErrorMessage, LoadingMessage } from "@open-mercato/ui/backend/detail";
import { useRecordsEntityGuard } from "@open-mercato/core/modules/entities/components/useRecordsEntityGuard";
function toCsvUrl(base, params) {
  const p = new URLSearchParams(params);
  p.set("format", "csv");
  const qs = p.toString();
  return qs ? `${base}?${qs}` : base;
}
function normalizeCell(v) {
  if (Array.isArray(v)) return v.filter((x) => x != null && x !== "").join(", ");
  if (v === true) return "Yes";
  if (v === false) return "No";
  if (v == null) return "";
  if (v instanceof Date) return v.toISOString();
  return String(v);
}
function RecordsPage({ params }) {
  const t = useT();
  const entityId = decodeURIComponent(params?.entityId || "");
  const guard = useRecordsEntityGuard(entityId);
  if (guard !== "allowed") {
    return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: guard === "blocked" ? /* @__PURE__ */ jsx(ErrorMessage, { label: t("entities.userEntities.records.errors.systemEntity", "This entity is system-managed. Records are available for custom entities only.") }) : /* @__PURE__ */ jsx(LoadingMessage, { label: t("entities.userEntities.records.loading", "Loading records...") }) }) });
  }
  return /* @__PURE__ */ jsx(RecordsPageInner, { params });
}
function RecordsPageInner({ params }) {
  const t = useT();
  const entityId = decodeURIComponent(params?.entityId || "");
  const [sorting, setSorting] = React.useState([{ id: "id", desc: false }]);
  const [page, setPage] = React.useState(1);
  const [pageSize, setPageSize] = React.useState(50);
  const [search, setSearch] = React.useState("");
  const [filterValues, setFilterValues] = React.useState({});
  const [columns, setColumns] = React.useState([]);
  const [rawData, setRawData] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [totalPages, setTotalPages] = React.useState(1);
  const [loading, setLoading] = React.useState(false);
  const scopeVersion = useOrganizationScopeVersion();
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const deleteMutationContextId = `entities.user.records.${entityId}:single-delete`;
  const { runMutation: runDeleteMutation, retryLastMutation: retryDeleteMutation } = useGuardedMutation({
    contextId: deleteMutationContextId,
    blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const { data: cfDefs = [] } = useCustomFieldDefs(entityId, {
    enabled: Boolean(entityId),
    keyExtras: [scopeVersion]
  });
  const searchableFields = React.useMemo(() => {
    const fields = (columns || []).map((col) => col.accessorKey).filter((key) => typeof key === "string" && key.length > 0);
    return Array.from(/* @__PURE__ */ new Set(["id", ...fields]));
  }, [columns]);
  React.useEffect(() => {
    let cancelled = false;
    const run = async () => {
      setLoading(true);
      try {
        const params2 = new URLSearchParams();
        params2.set("entityId", entityId);
        params2.set("page", String(page));
        params2.set("pageSize", String(pageSize));
        const trimmedSearch = search.trim();
        if (trimmedSearch) {
          params2.set("search", trimmedSearch);
          if (searchableFields.length) params2.set("searchFields", searchableFields.join(","));
        }
        const s = sorting?.[0];
        if (s?.id) {
          params2.set("sortField", String(s.id));
          params2.set("sortDir", s.desc ? "desc" : "asc");
        }
        for (const [k, v] of Object.entries(filterValues)) {
          if (v == null) continue;
          if (Array.isArray(v)) {
            if (v.length) params2.set(k, v.join(","));
          } else if (typeof v === "object") {
          } else {
            params2.set(k, String(v));
          }
        }
        const j = await readApiResultOrThrow(
          `/api/entities/records?${params2.toString()}`,
          void 0,
          {
            errorMessage: "Failed to load records",
            fallback: {
              items: [],
              total: 0,
              page,
              pageSize,
              totalPages: 1
            }
          }
        );
        if (!cancelled) {
          setRawData(j.items || []);
          setTotal(j.total);
          setTotalPages(j.totalPages);
        }
      } catch (e) {
        if (!cancelled) {
          setRawData([]);
          setTotal(0);
          setTotalPages(1);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    };
    if (entityId) run();
    return () => {
      cancelled = true;
    };
  }, [entityId, page, pageSize, sorting, filterValues, scopeVersion, search, searchableFields]);
  React.useEffect(() => {
    const visibleDefs = filterCustomFieldDefs(cfDefs, "list");
    const maxVisible = 10;
    const cols = visibleDefs.map((d, idx) => ({
      accessorKey: d.key,
      header: d.label || d.key,
      meta: { priority: idx < 4 ? 1 : idx < 6 ? 2 : idx < 8 ? 3 : idx < maxVisible ? 4 : 5 },
      cell: ({ getValue }) => {
        const v = getValue();
        return /* @__PURE__ */ jsx("span", { className: "truncate max-w-[24ch] inline-block align-top", title: normalizeCell(v), children: normalizeCell(v) });
      }
    }));
    const hasIdCol = cols.some((c) => c.accessorKey === "id" || c.id === "id");
    if (!hasIdCol) cols.unshift({ accessorKey: "id", header: "ID", meta: { hidden: true, priority: 6 } });
    setColumns(cols);
  }, [cfDefs]);
  const data = rawData;
  const viewExportColumns = React.useMemo(() => {
    return (columns || []).map((col) => {
      const accessorKey = col.accessorKey;
      if (!accessorKey || typeof accessorKey !== "string") return null;
      if (col.meta?.hidden) return null;
      const header = typeof col.header === "string" ? col.header : accessorKey.startsWith("cf_") ? accessorKey.slice(3) : accessorKey;
      return { field: accessorKey, header };
    }).filter((col) => !!col);
  }, [columns]);
  const buildFullExportUrl = React.useCallback((format) => {
    const qp = new URLSearchParams({
      entityId,
      format,
      exportScope: "full",
      all: "true"
    });
    const sort = sorting?.[0];
    if (sort?.id) {
      qp.set("sortField", String(sort.id));
      qp.set("sortDir", sort.desc ? "desc" : "asc");
    }
    const trimmedSearch = search.trim();
    if (trimmedSearch) {
      qp.set("search", trimmedSearch);
      if (searchableFields.length) qp.set("searchFields", searchableFields.join(","));
    }
    return `/api/entities/records?${qp.toString()}`;
  }, [entityId, sorting, search, searchableFields]);
  const exportConfig = React.useMemo(() => {
    const safeEntityId = entityId.replace(/[^a-z0-9_-]/gi, "_") || "records";
    return {
      view: {
        description: "Exports the current list respecting filters and column visibility.",
        prepare: async () => {
          const rowsForExport = data.map((row) => {
            const out = {};
            for (const col of viewExportColumns) {
              out[col.field] = row[col.field];
            }
            return out;
          });
          const prepared = {
            columns: viewExportColumns.map((col) => ({ field: col.field, header: col.header })),
            rows: rowsForExport
          };
          return { prepared, filename: `${safeEntityId}_view` };
        }
      },
      full: {
        description: "Exports raw records with every field and custom field included.",
        getUrl: (format) => buildFullExportUrl(format),
        filename: () => `${safeEntityId}_full`
      }
    };
  }, [buildFullExportUrl, data, entityId, viewExportColumns]);
  const hasAnyFormFields = React.useMemo(() => filterCustomFieldDefs(cfDefs, "form").length > 0, [cfDefs]);
  const actions = /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsx(Link, { href: `/backend/entities/user/${encodeURIComponent(entityId)}`, children: "Edit Entity Definition" }) }),
    hasAnyFormFields && /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: `/backend/entities/user/${encodeURIComponent(entityId)}/records/create`, children: "Create" }) })
  ] });
  const baseFilters = React.useMemo(() => [
    { id: "id", label: "ID", type: "text" }
  ], []);
  return /* @__PURE__ */ jsxs(Page, { children: [
    /* @__PURE__ */ jsxs(PageBody, { children: [
      /* @__PURE__ */ jsxs(ContextHelp, { bulb: true, title: "API: Manage Records via cURL", className: "mb-4", children: [
        /* @__PURE__ */ jsxs("p", { className: "mb-2", children: [
          "Interact with this custom entity via the backend API using cURL. Use API keys for machine-to-machine access\u2014mint one from the",
          " ",
          /* @__PURE__ */ jsx("a", { className: "underline", target: "_blank", rel: "noreferrer", href: "https://docs.openmercato.com/user-guide/api-keys", children: "Managing API keys guide" }),
          " ",
          "or the",
          " ",
          /* @__PURE__ */ jsx("a", { className: "underline", target: "_blank", rel: "noreferrer", href: "https://docs.openmercato.com/cli/api-keys", children: "API keys CLI documentation" }),
          " ",
          "before running these calls."
        ] }),
        /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "1) Configure environment variables" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `export BASE_URL="http://localhost:3000/api"
export API_KEY="<paste API key secret here>"           # scoped with entities.features
export ENTITY_ID="${entityId}"
export RECORD_ID="<record uuid>"` }) }),
            /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground mt-1", children: [
              "Need a new key? Follow the",
              " ",
              /* @__PURE__ */ jsx("a", { className: "underline", target: "_blank", rel: "noreferrer", href: "https://docs.openmercato.com/user-guide/api-keys", children: "Managing API keys" }),
              " ",
              "walkthrough or mint one via",
              " ",
              /* @__PURE__ */ jsx("a", { className: "underline", target: "_blank", rel: "noreferrer", href: "https://docs.openmercato.com/cli/api-keys", children: "mercato api_keys add" }),
              "."
            ] })
          ] }),
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "2) List records" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `curl -s -H "X-Api-Key: $API_KEY"   "$BASE_URL/entities/records?entityId=$ENTITY_ID" | jq` }) })
          ] }),
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "3) Read a single record (by id)" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `curl -s -H "X-Api-Key: $API_KEY"   "$BASE_URL/entities/records?entityId=$ENTITY_ID&id=$RECORD_ID" | jq` }) }),
            /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground mt-1", children: [
              "Note: Response is a list; filter by ",
              /* @__PURE__ */ jsx("code", { children: "id" }),
              " to get a single item."
            ] })
          ] }),
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "4) Create a record" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `curl -s -X POST   -H "X-Api-Key: $API_KEY"   -H "Content-Type: application/json"   -d "{
    \\"entityId\\": \\"$ENTITY_ID\\",
    \\"values\\": {
      \\"field_one\\": \\"Example\\",
      \\"field_two\\": 123
    }
  }"   "$BASE_URL/entities/records" | jq` }) }),
            /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground mt-1", children: [
              "For custom entities, send field keys without the ",
              /* @__PURE__ */ jsx("code", { children: "cf_" }),
              " prefix. The API normalizes this server-side."
            ] })
          ] }),
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "5) Update a record" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `curl -s -X PUT   -H "X-Api-Key: $API_KEY"   -H "Content-Type: application/json"   -d "{
    \\"entityId\\": \\"$ENTITY_ID\\",
    \\"recordId\\": \\"$RECORD_ID\\",
    \\"values\\": {
      \\"field_one\\": \\"Updated\\"
    }
  }"   "$BASE_URL/entities/records" | jq` }) })
          ] }),
          /* @__PURE__ */ jsxs("div", { children: [
            /* @__PURE__ */ jsx("div", { className: "font-medium mb-1", children: "6) Delete a record" }),
            /* @__PURE__ */ jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-auto", children: /* @__PURE__ */ jsx("code", { children: `curl -s -X DELETE   -H "X-Api-Key: $API_KEY"   "$BASE_URL/entities/records?entityId=$ENTITY_ID&recordId=$RECORD_ID" | jq` }) })
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "text-muted-foreground", children: [
            "Security notes:",
            /* @__PURE__ */ jsxs("ul", { className: "list-disc pl-5 mt-1 space-y-1", children: [
              /* @__PURE__ */ jsx("li", { children: "All endpoints require a valid API key. Keys inherit tenant, organization, and feature scope." }),
              /* @__PURE__ */ jsx("li", { children: "Rotate keys regularly and delete unused ones in the admin UI." }),
              /* @__PURE__ */ jsx("li", { children: "Store the secret in a secure vault; anyone with the header can act within the key's permissions." })
            ] })
          ] })
        ] })
      ] }),
      /* @__PURE__ */ jsx(
        DataTable,
        {
          stickyActionsColumn: true,
          title: `Records: ${entityId}`,
          entityId,
          actions,
          columns,
          data,
          perspective: { tableId: `entities.user.records.${entityId}` },
          exporter: exportConfig,
          filters: baseFilters,
          filterValues,
          rowActions: (row) => /* @__PURE__ */ jsx(
            RowActions,
            {
              items: [
                { id: "edit", label: "Edit", href: `/backend/entities/user/${encodeURIComponent(entityId)}/records/${encodeURIComponent(String(row.id))}` },
                { id: "delete", label: "Delete", destructive: true, onSelect: async () => {
                  const recordId = String(row.id);
                  try {
                    const confirmed = await confirm({
                      title: "Delete this record?",
                      variant: "destructive"
                    });
                    if (!confirmed) return;
                    await runDeleteMutation({
                      operation: async () => {
                        const deleteCall = await withScopedApiRequestHeaders(
                          buildOptimisticLockHeader(row.updatedAt),
                          () => apiCall(
                            `/api/entities/records?entityId=${encodeURIComponent(entityId)}&recordId=${encodeURIComponent(recordId)}`,
                            { method: "DELETE" }
                          )
                        );
                        if (!deleteCall.ok) {
                          await raiseCrudError(deleteCall.response, "Failed to delete record");
                        }
                      },
                      context: {
                        formId: deleteMutationContextId,
                        resourceKind: "entities.record",
                        resourceId: recordId,
                        retryLastMutation: retryDeleteMutation
                      }
                    });
                    const j = await readApiResultOrThrow(
                      `/api/entities/records?entityId=${encodeURIComponent(entityId)}&page=${page}&pageSize=${pageSize}`,
                      void 0,
                      {
                        errorMessage: "Failed to reload records",
                        fallback: { items: [], total: 0, page, pageSize, totalPages: 1 }
                      }
                    );
                    setRawData(j.items || []);
                    setTotal(j.total || 0);
                    setTotalPages(j.totalPages || 1);
                    flash("Record has been removed", "success");
                  } catch (error) {
                    const message = error instanceof Error ? error.message : "Failed to delete record";
                    flash(message, "error");
                  }
                } }
              ]
            }
          ),
          sortable: true,
          sorting,
          onSortingChange: setSorting,
          searchValue: search,
          onSearchChange: (v) => {
            setSearch(v);
            setPage(1);
          },
          onFiltersApply: (vals) => {
            setFilterValues(vals);
            setPage(1);
          },
          onFiltersClear: () => {
            setFilterValues({});
            setPage(1);
          },
          pagination: { page, pageSize, total, totalPages, onPageChange: setPage },
          isLoading: loading
        }
      )
    ] }),
    ConfirmDialogElement
  ] });
}
export {
  RecordsPage as default
};
//# sourceMappingURL=page.js.map
