import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import DocumentsGrid from '../DocumentsGrid';
import DocumentsList from '../DocumentsList';
import type { DragEvent, ReactNode, RefObject } from 'react';
import type {
  DocumentsListEntry,
  FolderEventHandler,
  DocumentEventHandler,
  DocumentLike,
  DocumentTag,
} from '../DocumentsList';
import DesktopWorkspace from '../../desktop/DesktopWorkspace';
import { isTagTransferEvent } from '../tagTransfer';
import PreviewZoomOverlay from '../../detail/PreviewZoomOverlay';
import { isPointerModifierEvent, isPrimaryPointerEvent } from '../useEntryPointer';
import {
  WorkspaceSelectionProvider,
  useWorkspaceSelectionContext,
} from '../../app/WorkspaceSelectionContext';
import type { WorkspaceSelectionValue } from '../../app/WorkspaceSelectionContext';
import DocumentsPanelHeader, {
  DocumentsPanelHeaderConfig,
  DocumentsHeaderBreadcrumb,
} from './DocumentsPanelHeader';
import { SelectionFloatingPanel } from '../SelectionFloatingActions';
import { createDocumentEntryKey } from '../../app/entryKey';
import { createDocumentsTableHeaderActions } from './DocumentsToolbar';
import { useDocumentsFilter } from '../context/DocumentsFilterContext';
import { DEFAULT_GRID_ICON_SIZE } from '../../constants/documents';
import type { Identifier } from '../../types/identifiers';

const EntryType = {
  folder: 'folder',
  document: 'document',
};

interface DocumentsPanelInnerProps {
  headerLeading?: ReactNode;
  onBreadcrumbNavigate?: (crumb: DocumentsHeaderBreadcrumb) => void;
  [key: string]: any;
}

interface DocumentsPanelProps extends DocumentsPanelInnerProps {
  selectionValue: WorkspaceSelectionValue;
}

const defaultGetDocumentAsset = (_doc?: unknown, _type?: string) => null;

export type DocumentLinkLike = { url?: string | null; mimeType?: string | null };

export interface DocumentsViewProps {
  entries: DocumentsListEntry[];
  draggingDocumentIdsSet?: Set<Identifier> | null;
  draggedFolderId?: Identifier | 'root' | null;
  ensureAssetUrl?: (...args: any[]) => unknown;
  getDocumentAsset?: (...args: any[]) => unknown;
  onFolderClick?: FolderEventHandler;
  onFolderSelect?: (folderId: Identifier | 'root') => void;
  onFolderDragOver?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
  onFolderDragLeave?: (event: DragEvent<HTMLElement>) => void;
  onFolderDrop?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
  onFolderDragStart?: (event: DragEvent<HTMLElement>, folderId: Identifier | 'root') => void;
  onFolderDragEnd?: (event: DragEvent<HTMLElement>) => void;
  onFolderRename?: (folderId: Identifier | 'root', nextName: string) => Promise<boolean> | boolean;
  onDocumentClick?: DocumentEventHandler;
  onDocumentActivate?: DocumentEventHandler;
  onDocumentDragStart?: (event: DragEvent<HTMLElement>, document: DocumentLike) => void;
  onDocumentDragEnd?: (event: DragEvent<HTMLElement>) => void;
  onDocumentTagDragOver?: (event: DragEvent<HTMLElement>) => void;
  onDocumentTagDragLeave?: (event: DragEvent<HTMLElement>) => void;
  onDocumentTagDrop?: (documentId: Identifier, tag: any) => void;
  onDocumentRename?: (documentId: Identifier, nextTitle: string) => Promise<boolean> | boolean;
  tagLookupById?: Map<Identifier, DocumentTag> | null;
  onTagClick?: (tagId: Identifier) => void;
  onCorrespondentClick?: (correspondentId: Identifier) => void;
  activeCorrespondentIdSet?: Set<Identifier> | null;
  scrollRef?: RefObject<HTMLElement | null>;
  // Desk specific (optional for now or handled via intersection)
  tenantId?: Identifier | null;
  viewId?: string | null;
  documentLinks?: Map<Identifier, any> | null;
  ensureDownloadUrl?: (docId: Identifier, options?: { force?: boolean }) => Promise<any>;
  onDocumentStackSelect?: (docIds: Identifier[], event?: any) => void;
  onPromoteSelection?: (docId: Identifier | null) => void;
  activeTagFilters?: Array<Identifier | null>;
}

const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
  headerLeading = null,
  onBreadcrumbNavigate,
  currentFolderName,
  breadcrumbs,
  subfolders,
  documents,
  searchResultIds,
  onFolderSelect,
  onFolderDrop,
  onFolderDragOver,
  onFolderDragLeave,
  onFolderDragStart,
  onFolderDragEnd,
  draggedFolderId,
  onFolderRename,
  draggingDocumentIds = [],
  onDocumentDragStart,
  onDocumentDragEnd,
  onDocumentRename,
  onEntryPointer = null,
  onDocumentActivate = null,
  tagLookupById,
  activeCorrespondentIds = [],
  ensureAssetUrl = null,
  getDocumentAsset = defaultGetDocumentAsset,
  isSearchLoading = false,
  viewMode = 'list',
  onViewModeChange,
  documentLinks,
  ensureDownloadUrl,
  onRefresh = () => { },
  sortField,
  sortDirection,
  onSortFieldChange,
  onSortDirectionToggle,
  onDeleteSelection,
  documentLookup,
  tags,
  correspondents,
  onBulkTagAdd,
  onBulkTagRemove,
  onBulkCorrespondentAdd,
  onBulkCorrespondentRemove,
  onBulkReanalyze,
  folderOptions,
  onMoveDocumentsToFolder,
  searchQuery = '',
  activeTagFilters = [],
  activeCorrespondentFilters = [],
  selectedFolder = null,
  promoteSelectionOrder,
  onDocumentTagDrop,
  currentTenantId,
}): ReactNode => {
  const {
    selectedEntries,
    focusedEntryKey,
    setFocusedEntryKey,
    handleEntrySelection,
    clearSelection,
    selectionAnchorRef,
    applySelection,
  } = useWorkspaceSelectionContext();
  const {
    isActive: isFilterActive,
    includeDescendants,
    toggleIncludeDescendants,
    toggleTag: toggleTagFilter,
    toggleCorrespondent: toggleCorrespondentFilter,
  } = useDocumentsFilter();
  const searchDocuments = useMemo(
    () =>
      Array.isArray(searchResultIds)
        ? searchResultIds
          .map((id) => documentLookup?.get?.(id) || null)
          .filter((doc): doc is Record<string, unknown> => Boolean(doc))
        : null,
    [searchResultIds, documentLookup],
  );

  const showingSearchResults = Array.isArray(searchResultIds);
  const rows = showingSearchResults && searchDocuments ? searchDocuments : documents;
  const documentLinkMap = documentLinks instanceof Map ? documentLinks : null;
  const searchResultCount = Array.isArray(searchResultIds) ? searchResultIds.length : 0;

  const handleDeskDocumentStackSelect = useCallback(
    (docIds: Array<Identifier | string>) => {
      if (!Array.isArray(docIds) || docIds.length === 0) {
        return;
      }

      const entryKeys = docIds
        .map((id) => createDocumentEntryKey(id as Identifier))
        .filter((value): value is string => typeof value === 'string');

      if (!entryKeys.length) {
        return;
      }

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

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

      applySelection(nextKeys, {
        anchor,
        interactedKeys: entryKeys,
      });
    },
    [applySelection, 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,
  ]);

  const headerTitle = showingSearchResults
    ? 'Search results'
    : currentFolderName || 'Documents';
  const headerSubtitle = showingSearchResults
    ? `${searchResultCount} matching document${searchResultCount === 1 ? '' : 's'}`
    : null;
  const headerActions = useMemo(
    () => createDocumentsTableHeaderActions({
      viewMode,
      onViewModeChange,
      onRefresh,
      sortField,
      onSortFieldChange,
      sortDirection,
      onSortDirectionToggle,
      isFilterActive,
      includeDescendants,
      onToggleIncludeDescendants: toggleIncludeDescendants,
    }),
    [
      viewMode,
      onViewModeChange,
      onRefresh,
      sortField,
      onSortFieldChange,
      sortDirection,
      onSortDirectionToggle,
      isFilterActive,
      includeDescendants,
      toggleIncludeDescendants,
    ],
  );
  const floatingActions = useMemo(() => (
    <SelectionFloatingPanel
      documentLookup={documentLookup}
      tags={tags}
      tagLookupById={tagLookupById}
      correspondents={correspondents}
      onBulkTagAdd={onBulkTagAdd}
      onBulkTagRemove={onBulkTagRemove}
      onBulkCorrespondentAdd={onBulkCorrespondentAdd}
      onBulkCorrespondentRemove={onBulkCorrespondentRemove}
      onBulkReanalyze={onBulkReanalyze}
      onDeleteSelection={onDeleteSelection}
      folderOptions={folderOptions}
      onMoveDocumentsToFolder={onMoveDocumentsToFolder}
      onClearSelection={clearSelection}
    />
  ), [
    documentLookup,
    tags,
    tagLookupById,
    correspondents,
    onBulkTagAdd,
    onBulkTagRemove,
    onBulkCorrespondentAdd,
    onBulkCorrespondentRemove,
    onBulkReanalyze,
    onDeleteSelection,
    folderOptions,
    onMoveDocumentsToFolder,
    clearSelection,
  ]);
  const headerConfig: DocumentsPanelHeaderConfig = useMemo(() => ({
    title: headerTitle,
    subtitle: headerSubtitle,
    leading: headerLeading,
    actions: headerActions,
    breadcrumbs,
    floatingActions,
  }), [
    headerTitle,
    headerSubtitle,
    headerLeading,
    headerActions,
    breadcrumbs,
    floatingActions,
  ]);

  const currentFolderId = useMemo(() => {
    if (showingSearchResults) {
      return null;
    }
    const trail = Array.isArray(breadcrumbs) ? breadcrumbs : [];
    if (trail.length === 0) {
      return 'root';
    }
    return trail[trail.length - 1]?.id || 'root';
  }, [breadcrumbs, showingSearchResults]);

  const selectionContextRef = useRef(null);
  useEffect(() => {
    const nextContext = showingSearchResults
      ? { type: 'search', marker: searchResultIds }
      : { type: 'folder', marker: currentFolderId || 'root' };
    const previous = selectionContextRef.current;
    selectionContextRef.current = nextContext;
    if (!previous) {
      return;
    }
    const changed = previous.type !== nextContext.type
      || previous.marker !== nextContext.marker;
    if (changed) {
      clearSelection();
    }
  }, [showingSearchResults, currentFolderId, searchResultIds, clearSelection]);

  const entries = useMemo(() => {
    const list = [];
    if (!showingSearchResults) {
      subfolders.forEach((folder) => {
        if (!folder || !folder.id) {
          return;
        }
        list.push({ type: EntryType.folder, id: folder.id, key: `folder:${folder.id}`, folder });
      });
    }
    rows.forEach((doc) => {
      if (!doc || !doc.id) {
        return;
      }
      list.push({ type: EntryType.document, id: doc.id, key: `document:${doc.id}`, document: doc });
    });
    return list;
  }, [showingSearchResults, subfolders, rows]);

  const draggingSet = useMemo(
    () => new Set(draggingDocumentIds || []),
    [draggingDocumentIds],
  );
  const activeCorrespondentIdSet = useMemo(
    () => new Set(activeCorrespondentIds || []),
    [activeCorrespondentIds],
  );
  const scrollRef = useRef<HTMLElement | null>(null);
  const suppressDocumentClickRef = useRef(false);
  const isGridView = viewMode === 'grid';
  const isDeskView = viewMode === 'desk';
  const gridIconSize = DEFAULT_GRID_ICON_SIZE;

  type ZoomSource = { url: string; alt?: string | null; mimeType?: string | null };

  const [previewDocId, setPreviewDocId] = useState<Identifier | null>(null);

  const previewDoc = useMemo(() => {
    if (!previewDocId) {
      return null;
    }
    return rows.find((doc) => doc?.id === previewDocId) || null;
  }, [previewDocId, rows]);

  useEffect(() => {
    if (previewDocId && !previewDoc) {
      setPreviewDocId(null);
    }
  }, [previewDocId, previewDoc]);

  const [previewZoomSource, setPreviewZoomSource] = useState<ZoomSource | null>(null);
  const zoomDisplay = previewZoomSource;
  const overlayDocument = useMemo(() => (
    previewDoc && zoomDisplay?.url
      ? { ...previewDoc, documentLink: zoomDisplay }
      : previewDoc
  ), [previewDoc, zoomDisplay]);

  useEffect(() => {
    let cancelled = false;
    if (!previewDocId || !previewDoc) {
      setPreviewZoomSource(null);
      return () => {
        cancelled = true;
      };
    }
    const documentMimeType = previewDoc.mime_type;

    const applyEntry = (entry?: DocumentLinkLike | null) => {
      if (!entry?.url) {
        setPreviewZoomSource(null);
        return;
      }
      setPreviewZoomSource({
        url: entry.url,
        alt: previewDoc.title,
        mimeType: documentMimeType,
      });
    };

    const cachedEntry = documentLinkMap?.get(previewDocId) || null;
    if (cachedEntry?.url) {
      applyEntry(cachedEntry);
      return () => {
        cancelled = true;
      };
    }

    if (!ensureDownloadUrl) {
      setPreviewZoomSource(null);
      return () => {
        cancelled = true;
      };
    }

    ensureDownloadUrl(previewDocId)
      .then((entry) => {
        if (cancelled) {
          return;
        }
        applyEntry(entry);
      })
      .catch(() => {
        if (!cancelled) {
          setPreviewZoomSource(null);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [previewDocId, previewDoc, documentLinkMap, ensureDownloadUrl]);

  const closePreviewOverlay = useCallback(() => {
    setPreviewDocId(null);
    setPreviewZoomSource(null);
  }, []);

  const handleDocumentPreviewZoom = useCallback(
    (doc) => {
      if (!doc || !doc.id) {
        return;
      }
      if (!ensureDownloadUrl && !(documentLinkMap?.get(doc.id)?.url)) {
        return;
      }
      setPreviewDocId(doc.id);
    },
    [ensureDownloadUrl, documentLinkMap],
  );

  const handleDocumentActivate = useCallback(
    (doc, event?: React.MouseEvent | KeyboardEvent | null) => {
      if (!doc) {
        return;
      }
      if (event) {
        event.preventDefault();
        event.stopPropagation();
      }
      if (event?.altKey) {
        handleDocumentPreviewZoom(doc);
        return;
      }
      onDocumentActivate?.(doc.id);
    },
    [handleDocumentPreviewZoom, onDocumentActivate],
  );

  const navigableRows = useMemo(
    () => entries.map((entry) => ({ key: entry.key, type: entry.type, id: entry.id })),
    [entries],
  );
  const navigableEntryKeys = useMemo(() => navigableRows.map((row) => row.key), [navigableRows]);

  const getEntryByKey = useCallback(
    (entryKey) => entries.find((entry) => entry.key === entryKey) || null,
    [entries],
  );

  const handlePanelFocus = useCallback(() => {
    let resolvedKey = null;

    if (focusedEntryKey && navigableEntryKeys.includes(focusedEntryKey)) {
      resolvedKey = focusedEntryKey;
    }

    if (!resolvedKey) {
      for (let index = selectedEntries.length - 1; index >= 0; index -= 1) {
        const candidate = selectedEntries[index];
        if (navigableEntryKeys.includes(candidate)) {
          resolvedKey = candidate;
          break;
        }
      }
    }

    if (!resolvedKey) {
      if (!selectedEntries.length) {
        return;
      }
      if (navigableRows.length) {
        resolvedKey = navigableRows[0].key;
      }
    }

    if (!resolvedKey) {
      return;
    }

    setFocusedEntryKey(resolvedKey);
  }, [
    focusedEntryKey,
    navigableEntryKeys,
    navigableRows,
    setFocusedEntryKey,
    selectedEntries,
  ]);

  const handlePanelKeyDown = useCallback(
    (event) => {
      const { key, shiftKey } = event;
      const triggers = ['ArrowUp', 'ArrowDown', 'Home', 'End', 'Enter', ' ', 'Space', 'Spacebar'];
      if (!triggers.includes(key)) {
        return;
      }

      if (!navigableRows.length) {
        return;
      }

      event.preventDefault();

      let activeKey =
        focusedEntryKey && navigableEntryKeys.includes(focusedEntryKey)
          ? focusedEntryKey
          : null;

      if (!activeKey) {
        if (selectedEntries.length) {
          for (let index = selectedEntries.length - 1; index >= 0; index -= 1) {
            const candidate = selectedEntries[index];
            if (navigableEntryKeys.includes(candidate)) {
              activeKey = candidate;
              break;
            }
          }
        }

        if (!activeKey) {
          activeKey = key === 'ArrowUp' ? navigableEntryKeys[navigableEntryKeys.length - 1] : navigableEntryKeys[0];
        }
      }

      const currentIndex = navigableEntryKeys.indexOf(activeKey);
      const activeRow = currentIndex === -1 ? null : navigableRows[currentIndex];

      if (key === 'Enter' || key === ' ' || key === 'Space' || key === 'Spacebar') {
        if (activeRow) {
          handleEntrySelection(activeRow.key, event);
          if (activeRow.type === EntryType.folder) {
            onFolderSelect?.(activeRow.id);
          } else {
            const entry = getEntryByKey(activeRow.key);
            if (entry?.document) {
              handleDocumentPreviewZoom(entry.document);
            }
          }
        }
        return;
      }

      let nextIndex = currentIndex;
      if (key === 'ArrowDown') {
        nextIndex = currentIndex === -1 ? 0 : Math.min(currentIndex + 1, navigableRows.length - 1);
      } else if (key === 'ArrowUp') {
        nextIndex = currentIndex === -1 ? navigableRows.length - 1 : Math.max(currentIndex - 1, 0);
      } else if (key === 'Home') {
        nextIndex = 0;
      } else if (key === 'End') {
        nextIndex = navigableRows.length - 1;
      }

      if (nextIndex === -1 || nextIndex >= navigableRows.length) {
        return;
      }

      const targetRow = navigableRows[nextIndex];
      if (!targetRow) {
        return;
      }

      setFocusedEntryKey(targetRow.key);
      handleEntrySelection(targetRow.key, {
        shiftKey,
        preventDefault: () => { },
      });
    },
    [
      focusedEntryKey,
      getEntryByKey,
      navigableEntryKeys,
      navigableRows,
      onFolderSelect,
      selectedEntries,
      handleDocumentPreviewZoom,
      handleEntrySelection,
      setFocusedEntryKey,
    ],
  );

  const scrollToTop = useCallback(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = 0;
    }
  }, []);

  const searchKey = useMemo(
    () => (Array.isArray(searchResultIds) ? searchResultIds.join(':') : 'none'),
    [searchResultIds],
  );

  const breadcrumbKey = useMemo(
    () => (Array.isArray(breadcrumbs) ? breadcrumbs.map((crumb) => crumb?.id ?? '').join(':') : 'none'),
    [breadcrumbs],
  );

  useEffect(() => {
    scrollToTop();
  }, [
    scrollToTop,
    viewMode,
    showingSearchResults,
    searchKey,
    breadcrumbKey,
  ]);

  const isTagDragEvent = useCallback((event) => isTagTransferEvent(event), []);
  const ensureFocusedRowVisible = useCallback(() => {
    if (!focusedEntryKey) return;
    const container = scrollRef.current;
    if (!container) return;
    let selector = null;
    if (focusedEntryKey.startsWith('document:')) {
      selector = `#document-row-${focusedEntryKey.slice('document:'.length)}`;
    } else if (focusedEntryKey.startsWith('folder:')) {
      selector = `#folder-row-${focusedEntryKey.slice('folder:'.length)}`;
    }
    if (!selector) {
      return;
    }
    const row = container.querySelector(selector);
    if (!row || !container.contains(row)) {
      return;
    }

    const header = container.querySelector('thead');
    const headerHeight = header ? header.getBoundingClientRect().height : 0;
    const rowTop = row.offsetTop;
    const rowBottom = rowTop + row.offsetHeight;
    const visibleTop = container.scrollTop + headerHeight;
    const visibleBottom = container.scrollTop + container.clientHeight;

    if (rowTop < visibleTop) {
      container.scrollTop = Math.max(rowTop - headerHeight, 0);
      return;
    }

    if (rowBottom > visibleBottom) {
      const nextScrollTop = rowBottom - container.clientHeight;
      container.scrollTop = Math.max(nextScrollTop, 0);
    }
  }, [focusedEntryKey]);

  useEffect(() => {
    ensureFocusedRowVisible();
  }, [ensureFocusedRowVisible]);

  const activeDescendantId = useMemo(() => {
    if (!focusedEntryKey) return undefined;
    if (focusedEntryKey.startsWith('document:')) {
      return `document-row-${focusedEntryKey.slice('document:'.length)}`;
    }
    if (focusedEntryKey.startsWith('folder:')) {
      return `folder-row-${focusedEntryKey.slice('folder:'.length)}`;
    }
    return undefined;
  }, [focusedEntryKey]);

  const handleDocumentTagDragOver = useCallback(
    (event) => {
      if (!isTagDragEvent(event)) {
        return;
      }
      event.preventDefault();
      event.dataTransfer.dropEffect = 'copy';
      event.currentTarget.classList.add('tag-drop-target');
    },
    [isTagDragEvent],
  );

  const handleDocumentTagDragLeave = useCallback(
    (event) => {
      if (!isTagDragEvent(event)) {
        return;
      }
      if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) {
        return;
      }
      event.currentTarget.classList.remove('tag-drop-target');
    },
    [isTagDragEvent],
  );

  const handleDocumentClick = useCallback(
    (doc, event) => {
      if (!doc || suppressDocumentClickRef.current || !onEntryPointer) {
        return;
      }

      onEntryPointer(
        { type: EntryType.document, id: doc.id, key: `document:${doc.id}`, document: doc },
        event,
      );
    },
    [onEntryPointer],
  );

  const handleFolderClick = useCallback(
    (folder, event) => {
      if (!folder) {
        return;
      }

      if (onEntryPointer) {
        onEntryPointer(
          { type: EntryType.folder, id: folder.id, key: `folder:${folder.id}`, folder },
          event,
        );
      }

      if (
        !isPointerModifierEvent(event)
        && isPrimaryPointerEvent(event)
        && scrollRef.current
      ) {
        scrollRef.current.focus({ preventScroll: true });
        setFocusedEntryKey(`folder:${folder.id}`);
      }
    },
    [onEntryPointer, setFocusedEntryKey],
  );

  const handleDocumentDragStartLocal = useCallback(
    (event, doc) => {
      suppressDocumentClickRef.current = true;
      onDocumentDragStart?.(event, doc);
    },
    [onDocumentDragStart],
  );

  const handleDocumentDragEndLocal = useCallback(
    (event) => {
      onDocumentDragEnd?.(event);
      requestAnimationFrame(() => {
        suppressDocumentClickRef.current = false;
      });
    },
    [onDocumentDragEnd],
  );

  const hasDocumentEntries = useMemo(
    () => entries.some((entry) => entry.type === EntryType.document),
    [entries],
  );

  const viewProps: DocumentsViewProps = {
    entries,
    draggingDocumentIdsSet: draggingSet,
    draggedFolderId,
    onFolderClick: handleFolderClick,
    onFolderSelect,
    onFolderDragOver,
    onFolderDragLeave,
    onFolderDrop,
    onFolderDragStart,
    onFolderDragEnd,
    onDocumentClick: handleDocumentClick,
    onDocumentActivate: handleDocumentActivate,
    onDocumentDragStart: handleDocumentDragStartLocal,
    onDocumentDragEnd: handleDocumentDragEndLocal,
    onDocumentTagDragOver: handleDocumentTagDragOver,
    onDocumentTagDragLeave: handleDocumentTagDragLeave,
    onDocumentTagDrop,
    onDocumentRename,
    onFolderRename,
    ensureAssetUrl,
    getDocumentAsset,
    tagLookupById,
    onTagClick: toggleTagFilter,
    onCorrespondentClick: toggleCorrespondentFilter,
    activeCorrespondentIdSet: activeCorrespondentIdSet,
    activeTagFilters,
    scrollRef,
    // Desk specific
    onDocumentStackSelect: handleDeskDocumentStackSelect,
    onPromoteSelection: promoteSelectionOrder,
    tenantId: currentTenantId,
    viewId: deskViewId,
    documentLinks: documentLinkMap,
    ensureDownloadUrl,
  };

  const renderBody = () => {
    const hasEntries = entries.length > 0;
    const isSearchEmpty = (showingSearchResults || isFilterActive) && !hasDocumentEntries && !isSearchLoading;

    if (isSearchEmpty) {
      return (
        <div className="empty-state">
          No documents match the current filters.
        </div>
      );
    }

    if (!hasEntries) {
      return (
        <div className="empty-state">
          No documents to show here yet. Drop files to make this space come alive.
        </div>
      );
    }

    switch (viewMode) {
      case 'desk':
        return <DesktopWorkspace {...viewProps} />;
      case 'grid':
        return <DocumentsGrid {...viewProps} gridIconSize={gridIconSize} />;
      case 'list':
      default:
        return <DocumentsList {...viewProps} />;
    }
  };

  const panelVariant = isDeskView ? 'desk' : isGridView ? 'grid' : 'list';
  const shouldHandlePanelInteractions = !isDeskView && entries.length > 0;

  const handleSectionFocus = useCallback((event: React.FocusEvent<HTMLElement>) => {
    if (!shouldHandlePanelInteractions || event.target !== event.currentTarget) {
      return;
    }
    handlePanelFocus();
  }, [shouldHandlePanelInteractions, handlePanelFocus]);

  const handleSectionKeyDown = useCallback((event: React.KeyboardEvent<HTMLElement>) => {
    if (!shouldHandlePanelInteractions || event.target !== event.currentTarget) {
      return;
    }
    handlePanelKeyDown(event);
  }, [shouldHandlePanelInteractions, handlePanelKeyDown]);

  const handleSectionClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
    if (!shouldHandlePanelInteractions || event.target !== event.currentTarget) {
      return;
    }
    clearSelection();
  }, [shouldHandlePanelInteractions, clearSelection]);

  return (
    <>
      <DocumentsPanelHeader
        header={headerConfig}
        onBreadcrumbClick={onBreadcrumbNavigate}
      />
      <section
        ref={scrollRef}
        className={`documents-panel documents-panel--view-${panelVariant}`}
        tabIndex={shouldHandlePanelInteractions ? 0 : undefined}
        onFocus={handleSectionFocus}
        onKeyDown={handleSectionKeyDown}
        onClick={handleSectionClick}
        aria-activedescendant={shouldHandlePanelInteractions && !isGridView ? activeDescendantId : undefined}
      >
        {renderBody()}
      </section>
      <PreviewZoomOverlay
        open={Boolean(zoomDisplay?.url)}
        onClose={closePreviewOverlay}
        document={overlayDocument}
      />
    </>
  );
};

const DocumentsPanel: React.FC<DocumentsPanelProps> = ({ selectionValue, ...rest }) => (
  <WorkspaceSelectionProvider value={selectionValue}>
    <DocumentsPanelInner {...rest} />
  </WorkspaceSelectionProvider>
);

export default DocumentsPanel;
