import { useCallback, useEffect, useMemo } from 'react';
import type { MutableRefObject } from 'react';
import { resolveDocumentAssetUrl } from '../../lib/assets/AssetManager';
import { useDetailPanel } from '../../app/useDetailPanel';
import type { DocumentInfoPanelProps } from '../components/DocumentInfoPanel';
import type { EnsureAssetUrl, GetAsset } from '../../lib/assets/AssetManager';
import type { Identifier } from '../../types/identifiers';
import type { Document } from '../../types/documents';
import { resolveBreadcrumbs } from '../../documents/logic/breadcrumbs';

interface FolderNode {
  id: Identifier | 'root';
  name?: string;
  parentId?: Identifier | 'root';
}

interface UseDetailWorkspaceArgs {
  documents: Document[];
  documentLookup: Map<Identifier, Document>;
  folderNodes: Map<Identifier | 'root', FolderNode>;
  detailPanelControlRef: MutableRefObject<{ open?: (documentId: Identifier) => void; close?: () => void } | null>;
  detailFolderFetchRef: MutableRefObject<Set<Identifier | 'root'>>;
  previewDocumentId?: Identifier | null;
  activePreviewId?: Identifier | null;
  openDocumentPreview?: (args: { documentIds: Identifier[] }) => void;
  handleDocumentTitleUpdate?: (docId: Identifier, title: string) => Promise<boolean> | boolean;
  handleDocumentIssuedUpdate?: (docId: Identifier, issued: number | null) => Promise<boolean> | boolean;
  handleDocumentTagAdd?: (doc: Document, value: string, context?: { option?: unknown }) => void;
  handleDocumentTagDetach?: (...args: unknown[]) => void;
  ensureAssetUrl?: EnsureAssetUrl;
  getAsset?: GetAsset;
  correspondents?: unknown[];
  handleCorrespondentAdd?: (...args: unknown[]) => void;
  handleCorrespondentRemove?: (...args: unknown[]) => void;
  selectFolder?: (folderId?: Identifier | 'root') => void;
  tags?: unknown[];
  tagLookupById?: Map<Identifier, unknown> | null;
}

interface UseDetailWorkspaceResult {
  detailPanelProps: DocumentInfoPanelProps;
  detailPanelOpen: boolean;
  openDetailPanel: ReturnType<typeof useDetailPanel>['openDetailPanel'];
  closeDetailPanel: ReturnType<typeof useDetailPanel>['closeDetailPanel'];
  handleDetailPanelClose: () => void;
  inspectDocument: (docId: Identifier | null) => void;
  previewActive: boolean;
  previewWorkspaceDocument: Document | null;
  resolveThumbnailUrlForDoc: (doc: Document | null) => string | null;
  resolveFolderPath: (folderId?: Identifier | 'root') => Array<{ id: Identifier | 'root'; name: string }>;
}

import { listFolderContents } from '../../lib/api/apiClient';

const useDetailWorkspace = ({
  documents,
  documentLookup,
  folderNodes,
  detailPanelControlRef,
  detailFolderFetchRef,
  previewDocumentId,
  activePreviewId,
  openDocumentPreview,
  handleDocumentTitleUpdate,
  handleDocumentIssuedUpdate,
  handleDocumentTagAdd,
  handleDocumentTagDetach,
  ensureAssetUrl,
  getAsset,
  correspondents,
  handleCorrespondentAdd,
  handleCorrespondentRemove,
  selectFolder,
  tags,
  tagLookupById,
}: UseDetailWorkspaceArgs): UseDetailWorkspaceResult => {
  const {
    detailPanelOpen,
    detailPanelDocument,
    openDetailPanel,
    closeDetailPanel,
  } = useDetailPanel({
    documentLookup,
  });

  useEffect(() => {
    detailPanelControlRef.current = {
      open: openDetailPanel,
      close: closeDetailPanel,
    };
  }, [detailPanelControlRef, openDetailPanel, closeDetailPanel]);

  useEffect(() => {
    if (detailPanelOpen && activePreviewId) {
      openDetailPanel(activePreviewId);
    }
  }, [detailPanelOpen, activePreviewId, openDetailPanel]);

  // Prefetch folder ancestors for breadcrumb display
  useEffect(() => {
    const folderId = detailPanelDocument?.folder_id;
    if (!folderId) {
      return;
    }

    const visited = new Set();
    let currentId = folderId;
    let guard = 0;

    while (currentId && currentId !== 'root' && guard < 32) {
      guard += 1;
      if (visited.has(currentId)) {
        break;
      }
      visited.add(currentId);

      const node = folderNodes.get(currentId);
      if (!node) {
        if (!detailFolderFetchRef.current.has(currentId)) {
          detailFolderFetchRef.current.add(currentId);
          listFolderContents(currentId, { include_documents: false })
            .catch((error) => {
              console.warn('Failed to preload folder metadata for detail path', currentId, error);
            })
            .finally(() => {
              detailFolderFetchRef.current.delete(currentId);
            });
        }
        break;
      }

      const parentId = node.parentId ?? 'root';
      if (!parentId || parentId === 'root') {
        break;
      }
      currentId = parentId;
    }
  }, [detailPanelDocument, folderNodes, detailFolderFetchRef]);

  const resolveFolderPath = useCallback(
    (folderId) => {
      return resolveBreadcrumbs(folderId || 'root', folderNodes as any);
    },
    [folderNodes],
  );

  const previewWorkspaceDocument = useMemo(() => {
    if (!previewDocumentId) {
      return null;
    }
    return documentLookup.get(previewDocumentId)
      || documents.find((doc) => doc.id === previewDocumentId)
      || null;
  }, [previewDocumentId, documentLookup, documents]);

  const previewActive = Boolean(previewDocumentId && previewWorkspaceDocument);

  const resolveThumbnailUrlForDoc = useCallback(
    (doc) =>
      resolveDocumentAssetUrl(doc, 'thumbnail', {
        ensureAssetUrl,
        getAsset,
      }),
    [ensureAssetUrl, getAsset],
  );

  const inspectDocument = useCallback(
    (documentId: Identifier) => {
      if (!documentId) {
        return;
      }
      openDetailPanel(documentId);
    },
    [openDetailPanel],
  );

  const handleDetailPanelClose = useCallback(() => {
    closeDetailPanel();
  }, [closeDetailPanel]);

  const detailPanelProps = useMemo(
    () => ({
      document: detailPanelDocument,
      tags,
      tagLookupById,
      onTagAdd: handleDocumentTagAdd,
      onTagRemove: handleDocumentTagDetach,
      onOpenPreview: openDocumentPreview,
      activePreviewId,
      onUpdateTitle: handleDocumentTitleUpdate,
      onUpdateIssued: handleDocumentIssuedUpdate,
      ensureAssetUrl,
      getDocumentAsset: getAsset,
      correspondents,
      onCorrespondentAdd: handleCorrespondentAdd,
      onCorrespondentRemove: handleCorrespondentRemove,
      onFolderNavigate: selectFolder,
      onClose: handleDetailPanelClose,
      resolveFolderPath,
      folderNodes,
    }),
    [
      activePreviewId,
      correspondents,
      detailPanelDocument,
      ensureAssetUrl,
      getAsset,
      handleCorrespondentAdd,
      handleCorrespondentRemove,
      handleDetailPanelClose,
      handleDocumentTagAdd,
      handleDocumentIssuedUpdate,
      handleDocumentTitleUpdate,
      handleDocumentTagDetach,
      folderNodes,
      openDocumentPreview,
      resolveFolderPath,
      selectFolder,
      tags,
      tagLookupById,
    ],
  );

  return {
    detailPanelProps,
    detailPanelOpen,
    openDetailPanel,
    closeDetailPanel,
    handleDetailPanelClose,
    inspectDocument,
    previewActive,
    previewWorkspaceDocument,
    resolveThumbnailUrlForDoc,
    resolveFolderPath,
  };
};

export default useDetailWorkspace;
