"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { DataTable } from "@open-mercato/ui/backend/DataTable";
import { Button } from "@open-mercato/ui/primitives/button";
import { apiCallOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { ActionLogDetailsDialog } from "./ActionLogDetailsDialog.js";
import { Undo2, RotateCcw } from "lucide-react";
import { markRedoConsumed, markUndoSuccess } from "@open-mercato/ui/backend/operations/store";
import { useAuditPermissions, canUndoEntry, canRedoEntry } from "@open-mercato/ui/backend/version-history";
import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("audit_logs").child({ component: "AuditLogsActions" });
function AuditLogsActions({
  items,
  onRefresh,
  isLoading,
  headerExtras,
  onUndoError,
  onRedoError,
  pagination
}) {
  const t = useT();
  const permissions = useAuditPermissions(true);
  const [undoingToken, setUndoingToken] = React.useState(null);
  const [redoingId, setRedoingId] = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const actionItems = Array.isArray(items) ? items : [];
  const latestUndoable = React.useMemo(() => actionItems.find((item) => !!item.undoToken && item.executionState === "done"), [actionItems]);
  const noneLabel = t("audit_logs.common.none");
  const latestPerResource = React.useMemo(() => {
    const map = /* @__PURE__ */ new Map();
    let fallback = null;
    for (const item of actionItems) {
      if (!item.undoToken || item.executionState !== "done") continue;
      const key = buildResourceKey(item);
      if (key) {
        if (!map.has(key)) map.set(key, item.id);
      } else if (!fallback) {
        fallback = item.id;
      }
    }
    return { map, fallback };
  }, [actionItems]);
  const latestUndoneId = React.useMemo(() => {
    const undone = actionItems.filter((item) => item.executionState === "undone");
    if (!undone.length) return null;
    const sorted = [...undone].sort((a, b) => {
      const aTs = Date.parse(a.updatedAt);
      const bTs = Date.parse(b.updatedAt);
      return (Number.isFinite(bTs) ? bTs : 0) - (Number.isFinite(aTs) ? aTs : 0);
    });
    return sorted[0]?.id ?? null;
  }, [actionItems]);
  const isLatestUndoableForItem = React.useCallback((item) => {
    const key = buildResourceKey(item);
    if (key) return latestPerResource.map.get(key) === item.id;
    return latestPerResource.fallback === item.id;
  }, [latestPerResource]);
  const isRedoCandidate = React.useCallback((item) => item.executionState === "undone" && latestUndoneId === item.id, [latestUndoneId]);
  const handleUndo = React.useCallback(async (token) => {
    if (!token) return;
    setUndoingToken(token);
    try {
      await apiCallOrThrow("/api/audit_logs/audit-logs/actions/undo", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ undoToken: token })
      }, { errorMessage: t("audit_logs.error.undo") });
      markUndoSuccess(token);
      await onRefresh();
    } catch (err) {
      logger.error("Undo action failed", { err });
      onUndoError?.();
    } finally {
      setUndoingToken(null);
    }
  }, [onRefresh, onUndoError, t]);
  const handleRedo = React.useCallback(async (logId) => {
    if (!logId) return;
    setRedoingId(logId);
    try {
      await apiCallOrThrow("/api/audit_logs/audit-logs/actions/redo", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ logId })
      }, { errorMessage: t("audit_logs.error.redo") });
      markRedoConsumed(logId);
      await onRefresh();
    } catch (err) {
      logger.error("Redo action failed", { err });
      onRedoError?.();
    } finally {
      setRedoingId(null);
    }
  }, [onRefresh, onRedoError, t]);
  const columns = React.useMemo(() => [
    {
      accessorKey: "actionLabel",
      header: t("audit_logs.actions.columns.action"),
      cell: (info) => info.row.original.actionLabel || info.row.original.commandId
    },
    {
      accessorKey: "resourceKind",
      header: t("audit_logs.actions.columns.resource"),
      cell: (info) => formatResource(info.row.original, noneLabel)
    },
    {
      accessorKey: "actorUserId",
      header: t("audit_logs.actions.columns.user"),
      cell: (info) => info.row.original.actorUserName || info.getValue() || noneLabel,
      meta: { priority: 3 }
    },
    {
      accessorKey: "tenantId",
      header: t("audit_logs.actions.columns.tenant"),
      cell: (info) => info.row.original.tenantName || info.getValue() || noneLabel,
      meta: { priority: 4 }
    },
    {
      accessorKey: "organizationId",
      header: t("audit_logs.actions.columns.organization"),
      cell: (info) => info.row.original.organizationName || info.getValue() || noneLabel,
      meta: { priority: 4 }
    },
    {
      accessorKey: "createdAt",
      header: t("audit_logs.actions.columns.when"),
      cell: (info) => formatDate(info.getValue())
    },
    {
      accessorKey: "executionState",
      header: t("audit_logs.actions.columns.status")
    },
    {
      id: "controls",
      header: t("audit_logs.actions.columns.controls"),
      enableSorting: false,
      cell: (info) => {
        const item = info.row.original;
        const itemCanUndo = canUndoEntry(permissions, item.actorUserId);
        const itemCanRedo = canRedoEntry(permissions, item.actorUserId);
        const canUndo = itemCanUndo && Boolean(item.undoToken) && item.executionState === "done" && isLatestUndoableForItem(item);
        const showRedo = itemCanRedo && item.executionState === "undone";
        const canRedo = showRedo && isRedoCandidate(item);
        if (!canUndo && !showRedo) return null;
        return /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-1", children: [
          canUndo ? /* @__PURE__ */ jsx(
            Button,
            {
              variant: "ghost",
              size: "icon",
              "aria-label": t("audit_logs.actions.undo"),
              onClick: () => {
                void handleUndo(item.undoToken);
              },
              disabled: undoingToken === item.undoToken || Boolean(redoingId),
              children: /* @__PURE__ */ jsx(Undo2, { className: "size-4", "aria-hidden": "true" })
            }
          ) : null,
          showRedo ? /* @__PURE__ */ jsx(
            Button,
            {
              variant: "ghost",
              size: "icon",
              "aria-label": t("audit_logs.actions.redo"),
              onClick: () => {
                void handleRedo(item.id);
              },
              disabled: !canRedo || redoingId === item.id || Boolean(undoingToken),
              children: /* @__PURE__ */ jsx(RotateCcw, { className: "size-4", "aria-hidden": "true" })
            }
          ) : null
        ] });
      },
      meta: { align: "right" }
    }
  ], [t, noneLabel, handleUndo, handleRedo, isLatestUndoableForItem, isRedoCandidate, undoingToken, redoingId, permissions]);
  const undoButton = latestUndoable?.undoToken && canUndoEntry(permissions, latestUndoable.actorUserId) ? /* @__PURE__ */ jsx(
    Button,
    {
      variant: "secondary",
      size: "sm",
      onClick: () => {
        void handleUndo(latestUndoable.undoToken);
      },
      disabled: Boolean(undoingToken) || Boolean(redoingId),
      children: undoingToken ? t("audit_logs.actions.undoing") : t("audit_logs.actions.undo")
    }
  ) : null;
  const combinedActions = undoButton || headerExtras ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
    headerExtras,
    undoButton
  ] }) : void 0;
  const showSelfOnlyHint = !permissions.isLoading && !permissions.canViewTenant && !!permissions.currentUserId;
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    showSelfOnlyHint ? /* @__PURE__ */ jsx(Alert, { variant: "info", className: "mb-4", children: /* @__PURE__ */ jsx(AlertDescription, { children: t("audit_logs.hint.view_self_only", "Showing only your own changes. Contact an administrator for broader access.") }) }) : null,
    /* @__PURE__ */ jsx(
      DataTable,
      {
        title: t("audit_logs.actions.title"),
        data: actionItems,
        columns,
        actions: combinedActions,
        perspective: { tableId: "audit_logs.actions.list" },
        isLoading: Boolean(isLoading) || Boolean(undoingToken) || Boolean(redoingId),
        onRowClick: (item) => setSelected(item),
        pagination
      }
    ),
    selected ? /* @__PURE__ */ jsx(
      ActionLogDetailsDialog,
      {
        item: selected,
        onClose: () => setSelected(null)
      }
    ) : null
  ] });
}
function formatResource(item, fallback) {
  if (!item.resourceKind && !item.resourceId) return fallback;
  return [item.resourceKind, item.resourceId].filter(Boolean).join(" \xB7 ");
}
function buildResourceKey(item) {
  const kind = typeof item.resourceKind === "string" ? item.resourceKind.trim() : "";
  const id = typeof item.resourceId === "string" ? item.resourceId.trim() : "";
  if (!kind && !id) return null;
  return `${kind}::${id}`;
}
function formatDate(value) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return new Intl.DateTimeFormat(void 0, {
    dateStyle: "medium",
    timeStyle: "short"
  }).format(date);
}
export {
  AuditLogsActions
};
//# sourceMappingURL=AuditLogsActions.js.map
