import { useCallback, useMemo } from 'react';

type Identifier = string | number;

type DocumentEntry = { id?: Identifier } & Record<string, unknown>;
type InspectTarget = DocumentEntry | Identifier | null | undefined;

type WorkspaceViewMode = 'desk' | 'grid' | 'list' | string;

type DeskDocumentStackSelectHandler = (docIds: Identifier[]) => void;

type ResolveRowKey = (id: Identifier) => Identifier | string | null;

type ApplySelection = (
  keys: Array<Identifier | string>,
  options: { anchor?: Identifier | string | null; interactedKeys?: Array<Identifier | string> },
) => void;

interface UseDeskWorkspacePropsArgs {
  documents?: DocumentEntry[];
  searchResults?: DocumentEntry[];
  breadcrumbs?: unknown[];
  currentFolderName?: string | null;
  documentsViewMode?: WorkspaceViewMode;
  handleDocumentsViewModeChange?: (mode: WorkspaceViewMode) => void;
  handleDeskExit?: () => void;
  refreshCurrentFolder?: () => Promise<void> | void;
  inspectDocument?: (doc: InspectTarget) => void;
  handleEntryPointerCore?: (...args: unknown[]) => void;
  promoteSelectionOrder?: (...args: unknown[]) => void;
  currentTenantId?: Identifier | null;
  selectedDocumentIds?: Identifier[];
  selectedFolderIds?: Identifier[];
  clearDocumentSelection?: () => void;
  detailPanelOpen?: boolean;
  handleDetailPanelClose?: () => void;
  resolveThumbnailUrlForDoc?: (doc: DocumentEntry) => string | null;
  handleDocumentTagDrop?: (...args: unknown[]) => void;
  handleTagRemove?: (...args: unknown[]) => void;
  ensureAssetUrl?: (...args: unknown[]) => void;
  getDocumentAsset?: (...args: unknown[]) => unknown;
  activeTagFilters?: Identifier[];
  handleDeleteSelection?: () => void;
  tags?: unknown[];
  correspondents?: unknown[];
  documentLookup?: unknown;
  tagLookupById?: unknown;
  handleBulkTagAddFromDetail?: (...args: unknown[]) => void;
  handleBulkTagRemoveFromDetail?: (...args: unknown[]) => void;
  handleBulkCorrespondentAdd?: (...args: unknown[]) => void;
  handleBulkCorrespondentRemove?: (...args: unknown[]) => void;
  handleBulkSelectionReanalyze?: (...args: unknown[]) => void;
  folderOptions?: unknown[];
  moveDocumentsToFolder?: (...args: unknown[]) => void;
  searchIncludeDescendants?: boolean;
  toggleSearchIncludeDescendants?: () => void;
  selectedEntries?: Array<Identifier | string>;
  selectionAnchorRef: { current: Identifier | string | null };
  applySelection: ApplySelection;
  resolveDocumentRowKey: ResolveRowKey;
  showingSearchResults?: boolean;
  searchQuery?: string;
  activeCorrespondentFilters?: Identifier[];
  selectedFolder?: Identifier | string | null;
}

const useDeskWorkspaceProps = ({
  documents,
  searchResults,
  breadcrumbs,
  currentFolderName,
  documentsViewMode = 'desk',
  handleDocumentsViewModeChange,
  handleDeskExit,
  refreshCurrentFolder,
  inspectDocument,
  handleEntryPointerCore,
  promoteSelectionOrder,
  currentTenantId,
  selectedDocumentIds,
  selectedFolderIds,
  clearDocumentSelection,
  detailPanelOpen,
  handleDetailPanelClose,
  resolveThumbnailUrlForDoc,
  handleDocumentTagDrop,
  handleTagRemove,
  ensureAssetUrl,
  getDocumentAsset,
  activeTagFilters = [],
  handleDeleteSelection,
  tags,
  correspondents,
  documentLookup,
  tagLookupById,
  handleBulkTagAddFromDetail,
  handleBulkTagRemoveFromDetail,
  handleBulkCorrespondentAdd,
  handleBulkCorrespondentRemove,
  handleBulkSelectionReanalyze,
  folderOptions,
  moveDocumentsToFolder,
  searchIncludeDescendants,
  toggleSearchIncludeDescendants,
  selectedEntries = [],
  selectionAnchorRef,
  applySelection,
  resolveDocumentRowKey,
  showingSearchResults = false,
  searchQuery = '',
  activeCorrespondentFilters = [],
  selectedFolder,
}: UseDeskWorkspacePropsArgs) => {
  const handleDeskDocumentStackSelect: DeskDocumentStackSelectHandler = useCallback(
    (docIds) => {
      if (!Array.isArray(docIds) || docIds.length === 0) {
        return;
      }

      const rowKeys = docIds
        .map((id) => resolveDocumentRowKey(id))
        .filter((value): value is Identifier | string => Boolean(value));

      if (!rowKeys.length) {
        return;
      }

      const nextKeys = [...selectedEntries];
      rowKeys.forEach((key) => {
        if (!nextKeys.includes(key)) {
          nextKeys.push(key);
        }
      });

      const anchor = (rowKeys[0]
        || selectionAnchorRef.current
        || nextKeys[nextKeys.length - 1]) as Identifier | string | null;

      applySelection(nextKeys, {
        anchor,
        interactedKeys: rowKeys,
      });
    },
    [applySelection, resolveDocumentRowKey, selectedEntries, selectionAnchorRef],
  );

  const deskViewId = useMemo(() => {
    if (showingSearchResults) {
      const trimmedQuery = searchQuery.trim();
      const tagsKey = [...activeTagFilters].sort().join(',');
      const correspondentsKey = [...activeCorrespondentFilters].sort().join(',');
      return `search:${trimmedQuery}|tags:${tagsKey}|corr:${correspondentsKey}`;
    }

    const folderKey = selectedFolder && selectedFolder !== '' ? selectedFolder : 'root';
    return `folder:${folderKey}`;
  }, [
    showingSearchResults,
    searchQuery,
    activeTagFilters,
    activeCorrespondentFilters,
    selectedFolder,
  ]);

  return useMemo(
    () => ({
      documents,
      searchResults,
      breadcrumbs,
      currentFolderName,
      viewMode: documentsViewMode,
      onViewModeChange: handleDocumentsViewModeChange,
      onExit: handleDeskExit,
      onRefresh: refreshCurrentFolder,
      onInspectDocument: inspectDocument,
      onEntryPointer: handleEntryPointerCore,
      onDocumentStackSelect: handleDeskDocumentStackSelect,
      onPromoteSelection: promoteSelectionOrder,
      tenantId: currentTenantId,
      viewId: deskViewId,
      selectedDocumentIds,
      selectedFolderIds,
      onClearSelection: clearDocumentSelection,
      detailPanelOpen,
      onCloseDetailPanel: handleDetailPanelClose,
      resolveThumbnailUrl: resolveThumbnailUrlForDoc,
      onAssignTagToDocument: handleDocumentTagDrop,
      onRemoveTagFromDocument: handleTagRemove,
      ensureAssetUrl,
      getDocumentAsset,
      activeTagIds: activeTagFilters,
      onDeleteSelection: handleDeleteSelection,
      tags,
      correspondents,
      documentLookup,
      tagLookupById,
      onBulkTagAdd: handleBulkTagAddFromDetail,
      onBulkTagRemove: handleBulkTagRemoveFromDetail,
      onBulkCorrespondentAdd: handleBulkCorrespondentAdd,
      onBulkCorrespondentRemove: handleBulkCorrespondentRemove,
      onBulkReanalyze: handleBulkSelectionReanalyze,
      folderOptions,
      onMoveDocumentsToFolder: moveDocumentsToFolder,
      searchIncludeDescendants,
      onToggleSearchIncludeDescendants: toggleSearchIncludeDescendants,
    }),
    [
      documents,
      searchResults,
      breadcrumbs,
      currentFolderName,
      documentsViewMode,
      handleDocumentsViewModeChange,
      handleDeskExit,
      refreshCurrentFolder,
      inspectDocument,
      handleEntryPointerCore,
      handleDeskDocumentStackSelect,
      promoteSelectionOrder,
      currentTenantId,
      deskViewId,
      selectedDocumentIds,
      selectedFolderIds,
      clearDocumentSelection,
      detailPanelOpen,
      handleDetailPanelClose,
      resolveThumbnailUrlForDoc,
      handleDocumentTagDrop,
      handleTagRemove,
      ensureAssetUrl,
      getDocumentAsset,
      activeTagFilters,
      handleDeleteSelection,
      tags,
      correspondents,
      documentLookup,
      tagLookupById,
      handleBulkTagAddFromDetail,
      handleBulkTagRemoveFromDetail,
      handleBulkCorrespondentAdd,
      handleBulkCorrespondentRemove,
      handleBulkSelectionReanalyze,
      folderOptions,
      moveDocumentsToFolder,
      searchIncludeDescendants,
      toggleSearchIncludeDescendants,
    ],
  );
};

export default useDeskWorkspaceProps;
