"use client";
import * as React from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
import { toErrorMessage } from "./message-detail/utils.js";
const MESSAGE_BULK_REQUESTS = {
  markRead: {
    method: "PUT",
    buildUrl: (messageId) => `/api/messages/${encodeURIComponent(messageId)}/read`,
    successKey: "messages.bulk.flash.markReadSuccess",
    successFallback: "{count} messages marked as read.",
    errorKey: "messages.errors.stateChangeFailed",
    errorFallback: "Failed to update message state."
  },
  markUnread: {
    method: "DELETE",
    buildUrl: (messageId) => `/api/messages/${encodeURIComponent(messageId)}/read`,
    successKey: "messages.bulk.flash.markUnreadSuccess",
    successFallback: "{count} messages marked as unread.",
    errorKey: "messages.errors.stateChangeFailed",
    errorFallback: "Failed to update message state."
  },
  archive: {
    method: "PUT",
    buildUrl: (messageId) => `/api/messages/${encodeURIComponent(messageId)}/archive`,
    successKey: "messages.bulk.flash.archiveSuccess",
    successFallback: "{count} messages archived.",
    errorKey: "messages.errors.stateChangeFailed",
    errorFallback: "Failed to update message state."
  },
  unarchive: {
    method: "DELETE",
    buildUrl: (messageId) => `/api/messages/${encodeURIComponent(messageId)}/archive`,
    successKey: "messages.bulk.flash.unarchiveSuccess",
    successFallback: "{count} messages moved to inbox.",
    errorKey: "messages.errors.stateChangeFailed",
    errorFallback: "Failed to update message state."
  },
  delete: {
    method: "DELETE",
    buildUrl: (messageId) => `/api/messages/${encodeURIComponent(messageId)}`,
    successKey: "messages.bulk.flash.deleteSuccess",
    successFallback: "{count} messages deleted.",
    errorKey: "messages.errors.deleteFailed",
    errorFallback: "Failed to delete message."
  }
};
const MESSAGE_BULK_ACTIONS = {
  markRead: {
    id: "messages-mark-read",
    labelKey: "messages.actions.markRead",
    labelFallback: "Mark read"
  },
  markUnread: {
    id: "messages-mark-unread",
    labelKey: "messages.actions.markUnread",
    labelFallback: "Mark unread"
  },
  archive: {
    id: "messages-archive",
    labelKey: "messages.actions.archive",
    labelFallback: "Archive"
  },
  unarchive: {
    id: "messages-unarchive",
    labelKey: "messages.actions.unarchive",
    labelFallback: "Unarchive"
  },
  delete: {
    id: "messages-delete",
    labelKey: "messages.actions.delete",
    labelFallback: "Delete",
    destructive: true
  }
};
const MESSAGE_BULK_ACTION_IDS_BY_FOLDER = {
  inbox: ["markRead", "markUnread", "archive", "delete"],
  archived: ["markRead", "markUnread", "unarchive", "delete"],
  sent: ["delete"],
  drafts: ["delete"],
  all: []
};
function getMessageBulkActionIdsForFolder(folder) {
  return [...MESSAGE_BULK_ACTION_IDS_BY_FOLDER[folder]];
}
function normalizeSelectionScopeValue(value) {
  if (value == null) return void 0;
  if (typeof value === "string") {
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed : void 0;
  }
  if (Array.isArray(value)) {
    const normalized = value.map((item) => normalizeSelectionScopeValue(item)).filter((item) => item !== void 0);
    return normalized.length > 0 ? normalized : void 0;
  }
  if (typeof value === "object") {
    const normalizedEntries = Object.entries(value).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key, nestedValue]) => [key, normalizeSelectionScopeValue(nestedValue)]).filter(([, nestedValue]) => nestedValue !== void 0);
    if (normalizedEntries.length === 0) return void 0;
    return Object.fromEntries(normalizedEntries);
  }
  return value;
}
function buildMessageSelectionScopeKey(folder, page, search, filterValues) {
  return JSON.stringify({
    folder,
    page,
    search: search.trim(),
    filters: normalizeSelectionScopeValue(filterValues) ?? {}
  });
}
async function runWithConcurrency(items, limit, worker) {
  if (items.length === 0) return [];
  const results = new Array(items.length);
  let nextIndex = 0;
  const runWorker = async () => {
    while (nextIndex < items.length) {
      const currentIndex = nextIndex;
      nextIndex += 1;
      try {
        await worker(items[currentIndex]);
        results[currentIndex] = { status: "fulfilled", value: void 0 };
      } catch (error) {
        results[currentIndex] = { status: "rejected", reason: error };
      }
    }
  };
  await Promise.all(
    Array.from({ length: Math.min(limit, items.length) }, () => runWorker())
  );
  return results;
}
function useMessagesInboxBulkActions({
  folder,
  page,
  search,
  filterValues
}) {
  const t = useT();
  const queryClient = useQueryClient();
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: "messages-inbox-bulk-actions"
  });
  const selectionScopeKey = React.useMemo(
    () => buildMessageSelectionScopeKey(folder, page, search, filterValues),
    [filterValues, folder, page, search]
  );
  const injectionContext = React.useMemo(
    () => ({
      folder,
      page,
      search: search.trim(),
      filters: filterValues,
      retryLastMutation
    }),
    [filterValues, folder, page, retryLastMutation, search]
  );
  const executeBulkAction = React.useCallback(async (actionId, selectedRows) => {
    const messageIds = selectedRows.map((row) => row.id).filter((id) => id.trim().length > 0);
    if (messageIds.length === 0) return false;
    if (actionId === "delete") {
      const confirmed = await confirm({
        title: t("messages.bulk.delete.title", "Delete {count} messages?", { count: messageIds.length }),
        description: t("messages.bulk.delete.description", "This removes the selected messages from your view."),
        confirmText: t("messages.actions.delete", "Delete"),
        variant: "destructive"
      });
      if (!confirmed) return false;
    }
    const requestConfig = MESSAGE_BULK_REQUESTS[actionId];
    try {
      const summary = await runMutation({
        operation: async () => {
          const results = await runWithConcurrency(messageIds, 5, async (messageId) => {
            const call = await apiCall(requestConfig.buildUrl(messageId), {
              method: requestConfig.method
            });
            if (!call.ok) {
              throw new Error(
                toErrorMessage(call.result) ?? t(requestConfig.errorKey, requestConfig.errorFallback)
              );
            }
          });
          const failed = results.filter((result) => result.status === "rejected").length;
          const succeeded = results.length - failed;
          if (succeeded > 0) {
            await queryClient.invalidateQueries({ queryKey: ["messages", "list"] });
          }
          return {
            action: actionId,
            total: messageIds.length,
            succeeded,
            failed
          };
        },
        context: {
          actionId,
          messageIds,
          folder,
          page,
          search: search.trim(),
          filters: filterValues,
          retryLastMutation
        },
        mutationPayload: {
          actionId,
          messageIds
        }
      });
      if (summary.succeeded === 0) {
        flash(
          t("messages.bulk.flash.failed", "Failed to process {count} messages.", { count: summary.failed }),
          "error"
        );
        return false;
      }
      if (summary.failed > 0) {
        flash(
          t("messages.bulk.flash.partial", "{succeeded} of {total} messages processed; {failed} failed.", {
            succeeded: summary.succeeded,
            total: summary.total,
            failed: summary.failed
          }),
          "warning"
        );
        return true;
      }
      flash(
        t(requestConfig.successKey, requestConfig.successFallback, { count: summary.succeeded }),
        "success"
      );
      return true;
    } catch (error) {
      flash(
        error instanceof Error ? error.message : t(requestConfig.errorKey, requestConfig.errorFallback),
        "error"
      );
      return false;
    }
  }, [confirm, filterValues, folder, page, queryClient, retryLastMutation, runMutation, search, t]);
  const bulkActions = React.useMemo(
    () => {
      const actionIds = getMessageBulkActionIdsForFolder(folder);
      if (actionIds.length === 0) return void 0;
      return actionIds.map((actionId) => {
        const action = MESSAGE_BULK_ACTIONS[actionId];
        return {
          id: action.id,
          label: t(action.labelKey, action.labelFallback),
          destructive: action.destructive,
          onExecute: (selectedRows) => executeBulkAction(actionId, selectedRows)
        };
      });
    },
    [executeBulkAction, folder, t]
  );
  return {
    bulkActions,
    selectionScopeKey,
    injectionContext,
    ConfirmDialogElement
  };
}
export {
  getMessageBulkActionIdsForFolder,
  useMessagesInboxBulkActions
};
//# sourceMappingURL=useMessagesInboxBulkActions.js.map
