"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
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 { apiCallOrThrow, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
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 { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("query_index").child({ component: "indexes-table" });
const MUTATION_CONTEXT_ID = "query_index.status.list:actions";
function formatCount(value) {
  if (value == null) return "\u2014";
  return value.toLocaleString();
}
function formatNumeric(value) {
  if (value == null) return null;
  return Number(value).toLocaleString();
}
function formatProgressLabel(processed, total, t) {
  const processedText = formatNumeric(processed);
  if (!processedText) return null;
  const totalText = formatNumeric(total);
  if (totalText) return t("query_index.table.status.progress", { processed: processedText, total: totalText });
  return t("query_index.table.status.progressSingle", { processed: processedText });
}
function translateJobStatus(t, status, ok) {
  if (!status || status === "idle") {
    return ok ? t("query_index.table.status.in_sync") : t("query_index.table.status.out_of_sync");
  }
  if (status === "reindexing") return t("query_index.table.status.reindexing");
  if (status === "purging") return t("query_index.table.status.purging");
  if (status === "stalled") return t("query_index.table.status.stalled");
  return ok ? t("query_index.table.status.in_sync") : t("query_index.table.status.out_of_sync");
}
function translateScopeStatus(t, status) {
  if (status === "reindexing") return t("query_index.table.status.scope.reindexing");
  if (status === "purging") return t("query_index.table.status.scope.purging");
  if (status === "stalled") return t("query_index.table.status.scope.stalled");
  return t("query_index.table.status.scope.completed");
}
function createColumns(t) {
  return [
    { id: "entityId", header: () => t("query_index.table.columns.entity"), accessorKey: "entityId", meta: { priority: 1 } },
    { id: "label", header: () => t("query_index.table.columns.label"), accessorKey: "label", meta: { priority: 2 } },
    {
      id: "baseCount",
      header: () => t("query_index.table.columns.records"),
      accessorFn: (row) => row.baseCount ?? 0,
      cell: ({ row }) => /* @__PURE__ */ jsx("span", { children: formatCount(row.original.baseCount) }),
      meta: { priority: 2 }
    },
    {
      id: "indexCount",
      header: () => t("query_index.table.columns.indexed"),
      accessorFn: (row) => row.indexCount ?? 0,
      cell: ({ row }) => /* @__PURE__ */ jsx("span", { children: formatCount(row.original.indexCount) }),
      meta: { priority: 2 }
    },
    {
      id: "vectorCount",
      header: () => t("query_index.table.columns.vector"),
      accessorFn: (row) => row.vectorEnabled ? row.vectorCount ?? 0 : -1,
      cell: ({ row }) => {
        const record = row.original;
        if (!record.vectorEnabled) return /* @__PURE__ */ jsx("span", { children: "\u2014" });
        const ok = record.vectorCount != null && record.baseCount != null && record.vectorCount === record.baseCount;
        const display = formatCount(record.vectorCount);
        const className = ok ? "text-status-success-text" : "text-status-warning-text";
        return /* @__PURE__ */ jsx("span", { className, children: display });
      },
      meta: { priority: 2 }
    },
    {
      id: "fulltextCount",
      header: () => t("query_index.table.columns.fulltext"),
      accessorFn: (row) => row.fulltextEnabled ? row.fulltextCount ?? 0 : -1,
      cell: ({ row }) => {
        const record = row.original;
        if (!record.fulltextEnabled) return /* @__PURE__ */ jsx("span", { children: "\u2014" });
        const ok = record.fulltextCount != null && record.baseCount != null && record.fulltextCount === record.baseCount;
        const display = formatCount(record.fulltextCount);
        const className = ok ? "text-status-success-text" : "text-status-warning-text";
        return /* @__PURE__ */ jsx("span", { className, children: display });
      },
      meta: { priority: 2 }
    },
    {
      id: "status",
      header: () => t("query_index.table.columns.status"),
      cell: ({ row }) => {
        const record = row.original;
        const job = record.job;
        const partitions = job?.partitions ?? [];
        const ok = record.ok && (!job || job.status === "idle");
        const statusText = translateJobStatus(t, job?.status, ok);
        const jobProgress = job ? formatProgressLabel(job.processedCount ?? null, job.totalCount ?? null, t) : null;
        const label = jobProgress ? t("query_index.table.status.withProgress", { status: statusText, progress: jobProgress }) : statusText;
        let variant = "neutral";
        if (job) {
          if (job.status === "stalled") variant = "error";
          else if (job.status === "reindexing" || job.status === "purging") variant = "warning";
          else variant = ok ? "success" : "neutral";
        } else {
          variant = ok ? "success" : "neutral";
        }
        const lines = [];
        if (job?.scope && partitions.length <= 1) {
          const scopeStatus = translateScopeStatus(t, job.scope.status ?? null);
          const scopeProgress = formatProgressLabel(job.scope.processedCount ?? null, job.scope.totalCount ?? null, t);
          const scopeLabel = t("query_index.table.status.scopeLabel");
          lines.push(`${scopeLabel}: ${scopeStatus}${scopeProgress ? ` (${scopeProgress})` : ""}`);
        }
        if (partitions.length > 1) {
          for (const part of partitions) {
            const partitionLabel = part.partitionIndex != null ? t("query_index.table.status.partitionLabel", { index: Number(part.partitionIndex) + 1 }) : t("query_index.table.status.scopeLabel");
            const partitionStatus = translateScopeStatus(t, part.status);
            const partitionProgress = formatProgressLabel(part.processedCount ?? null, part.totalCount ?? null, t);
            lines.push(`${partitionLabel}: ${partitionStatus}${partitionProgress ? ` (${partitionProgress})` : ""}`);
          }
        }
        if (record.vectorEnabled) {
          const vectorLabel = t("query_index.table.status.vectorLabel");
          const vectorCount = formatCount(record.vectorCount);
          const vectorTotal = record.baseCount != null ? formatCount(record.baseCount) : null;
          const vectorValue = vectorTotal ? t("query_index.table.status.vectorValue", { count: vectorCount, total: vectorTotal }) : vectorCount;
          lines.push(`${vectorLabel}: ${vectorValue}`);
        }
        return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
          /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(StatusBadge, { variant, dot: true, children: label }) }),
          lines.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: lines.map((line, idx) => /* @__PURE__ */ jsx("div", { children: line }, idx)) })
        ] });
      },
      meta: { priority: 1 }
    }
  ];
}
function QueryIndexesTable() {
  const [sorting, setSorting] = React.useState([{ id: "entityId", desc: false }]);
  const [page, setPage] = React.useState(1);
  const [search, setSearch] = React.useState("");
  const qc = useQueryClient();
  const scopeVersion = useOrganizationScopeVersion();
  const [refreshSeq, setRefreshSeq] = React.useState(0);
  const t = useT();
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const columns = React.useMemo(() => createColumns(t), [t]);
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: MUTATION_CONTEXT_ID,
    blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const { data, isLoading } = useQuery({
    queryKey: ["query-index-status", scopeVersion, refreshSeq],
    queryFn: async () => {
      const baseUrl = "/api/query_index/status";
      const url = refreshSeq > 0 ? `${baseUrl}?refresh=${refreshSeq}` : baseUrl;
      return readApiResultOrThrow(
        url,
        void 0,
        { errorMessage: t("query_index.table.errors.loadFailed") }
      );
    },
    refetchInterval: 4e3
  });
  const rowsAll = data?.items || [];
  const rows = React.useMemo(() => {
    if (!search) return rowsAll;
    const q = search.toLowerCase();
    return rowsAll.filter((r) => r.entityId.toLowerCase().includes(q) || r.label.toLowerCase().includes(q));
  }, [rowsAll, search]);
  const trigger = React.useCallback(
    async (action, entityId, opts) => {
      const body = { entityType: entityId };
      if (opts?.force) body.force = true;
      const actionLabel = action === "purge" ? t("query_index.table.actions.purge") : t("query_index.table.actions.reindex");
      const errorMessage = t("query_index.table.errors.actionFailed", { action: actionLabel });
      try {
        await runMutation({
          operation: () => apiCallOrThrow(`/api/query_index/${action}`, {
            method: "POST",
            headers: { "content-type": "application/json" },
            body: JSON.stringify(body)
          }, { errorMessage }),
          context: {
            formId: MUTATION_CONTEXT_ID,
            resourceKind: "query_index",
            resourceId: entityId,
            retryLastMutation
          },
          mutationPayload: { action, entityType: entityId, force: Boolean(opts?.force) }
        });
      } catch (err) {
        const message = err instanceof Error && err.message ? err.message : errorMessage;
        logger.warn("Index action failed", { message });
        flash(message, "error");
      }
      qc.invalidateQueries({ queryKey: ["query-index-status"] });
    },
    [qc, t, runMutation, retryLastMutation]
  );
  const triggerVector = React.useCallback(
    async (action, entityId) => {
      if (action === "purge") {
        const confirmed = await confirm({
          title: t("query_index.table.confirm.vectorPurge"),
          variant: "destructive"
        });
        if (!confirmed) return;
      }
      const actionLabel = action === "purge" ? t("query_index.table.actions.vectorPurge") : t("query_index.table.actions.vectorReindex");
      const errorMessage = t("query_index.table.errors.actionFailed", { action: actionLabel });
      try {
        await runMutation({
          operation: () => apiCallOrThrow("/api/search/embeddings/reindex", {
            method: "POST",
            headers: { "content-type": "application/json" },
            body: JSON.stringify({
              entityId,
              purgeFirst: action === "purge"
            })
          }, { errorMessage }),
          context: {
            formId: MUTATION_CONTEXT_ID,
            resourceKind: "query_index.vector",
            resourceId: entityId,
            retryLastMutation
          },
          mutationPayload: { action, entityId, purgeFirst: action === "purge" }
        });
      } catch (err) {
        const message = err instanceof Error && err.message ? err.message : errorMessage;
        logger.warn("Vector action failed", { message });
        flash(message, "error");
      }
      qc.invalidateQueries({ queryKey: ["query-index-status"] });
    },
    [confirm, qc, t, runMutation, retryLastMutation]
  );
  const triggerFulltext = React.useCallback(
    async (action, entityId) => {
      if (action === "purge") {
        const confirmed = await confirm({
          title: t("query_index.table.confirm.fulltextPurge"),
          variant: "destructive"
        });
        if (!confirmed) return;
      }
      const actionLabel = action === "purge" ? t("query_index.table.actions.fulltextPurge") : t("query_index.table.actions.fulltextReindex");
      const errorMessage = t("query_index.table.errors.actionFailed", { action: actionLabel });
      try {
        await runMutation({
          operation: () => apiCallOrThrow("/api/search/reindex", {
            method: "POST",
            headers: { "content-type": "application/json" },
            body: JSON.stringify({
              action: action === "purge" ? "clear" : "reindex",
              entityId
            })
          }, { errorMessage }),
          context: {
            formId: MUTATION_CONTEXT_ID,
            resourceKind: "query_index.fulltext",
            resourceId: entityId,
            retryLastMutation
          },
          mutationPayload: { action, entityId }
        });
      } catch (err) {
        const message = err instanceof Error && err.message ? err.message : errorMessage;
        logger.warn("Fulltext action failed", { message });
        flash(message, "error");
      }
      qc.invalidateQueries({ queryKey: ["query-index-status"] });
    },
    [confirm, qc, t, runMutation, retryLastMutation]
  );
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx(
      DataTable,
      {
        title: t("query_index.nav.queryIndexes"),
        actions: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
          Button,
          {
            variant: "outline",
            onClick: () => {
              setRefreshSeq((v) => v + 1);
              qc.invalidateQueries({ queryKey: ["query-index-status"] });
            },
            children: t("query_index.table.refresh")
          }
        ) }),
        columns,
        data: rows,
        searchValue: search,
        searchPlaceholder: t("query_index.table.searchPlaceholder"),
        onSearchChange: (value) => {
          setSearch(value);
          setPage(1);
        },
        sortable: true,
        sorting,
        onSortingChange: setSorting,
        perspective: { tableId: "query_index.status.list" },
        rowActions: (row) => {
          const items = [
            { id: "reindex", label: t("query_index.table.actions.reindex"), onSelect: () => void trigger("reindex", row.entityId) },
            {
              id: "reindex-force",
              label: t("query_index.table.actions.reindexForce"),
              onSelect: () => void trigger("reindex", row.entityId, { force: true })
            },
            {
              id: "purge",
              label: t("query_index.table.actions.purge"),
              destructive: true,
              onSelect: () => void trigger("purge", row.entityId)
            }
          ];
          if (row.vectorEnabled) {
            items.push(
              {
                id: "vector-reindex",
                label: t("query_index.table.actions.vectorReindex"),
                onSelect: () => void triggerVector("reindex", row.entityId)
              },
              {
                id: "vector-purge",
                label: t("query_index.table.actions.vectorPurge"),
                destructive: true,
                onSelect: () => void triggerVector("purge", row.entityId)
              }
            );
          }
          if (row.fulltextEnabled) {
            items.push(
              {
                id: "fulltext-reindex",
                label: t("query_index.table.actions.fulltextReindex"),
                onSelect: () => void triggerFulltext("reindex", row.entityId)
              },
              {
                id: "fulltext-purge",
                label: t("query_index.table.actions.fulltextPurge"),
                destructive: true,
                onSelect: () => void triggerFulltext("purge", row.entityId)
              }
            );
          }
          return /* @__PURE__ */ jsx(RowActions, { items });
        },
        pagination: { page, pageSize: 50, total: rows.length, totalPages: 1, onPageChange: setPage },
        isLoading
      }
    ),
    ConfirmDialogElement
  ] });
}
export {
  QueryIndexesTable as default
};
//# sourceMappingURL=QueryIndexesTable.js.map
