import React, { useEffect, useMemo } from 'react';
import { DEFAULT_FOLDER_NAME } from '../../app/workspaceUtils';
import type { FolderId as FolderIdentifier } from '../../types/identifiers';

type FolderId = FolderIdentifier | 'root';

interface UseWorkspaceBreadcrumbsArgs {
  selectedFolder: FolderId | null;
  folderNodes: Map<FolderId, { id?: FolderId; name?: string | null; parentId?: FolderId | null; parent_id?: FolderId | null }>;
  currentFolder: { id?: FolderId; name?: string | null; parentId?: FolderId | null; parent_id?: FolderId | null } | null;
  breadcrumbFetchRef: React.MutableRefObject<Set<FolderId>>;
  ensureFolderData: (folderId: FolderId, options?: Record<string, unknown>) => Promise<unknown>;
}

const useWorkspaceBreadcrumbs = ({
  selectedFolder,
  folderNodes,
  currentFolder,
  breadcrumbFetchRef,
  ensureFolderData,
}: UseWorkspaceBreadcrumbsArgs) => {
  const { breadcrumbs, missingBreadcrumbAncestors } = useMemo(() => {
    const chain: Array<{ id: FolderId; name?: string | null }> = [];
    const seen = new Set<FolderId>();
    const pending = new Set<FolderId>();
    let currentId: FolderId | null = (selectedFolder || 'root') as FolderId;
    let guard = 0;

    while (currentId && !seen.has(currentId) && guard < 32) {
      guard += 1;
      seen.add(currentId);

      if (currentId === 'root') {
        chain.push({ id: 'root', name: DEFAULT_FOLDER_NAME });
        currentId = null;
        break;
      }

      const node = folderNodes.get(currentId as FolderId);
      if (node) {
        chain.push({ id: currentId, name: node.name || 'Folder' });
        currentId = (node.parentId ?? node.parent_id ?? 'root') as FolderId;
        continue;
      }

      let fallbackName: string | null = '…';
      let parentId: FolderId | null = null;

      if (currentFolder && currentFolder.id === currentId) {
        fallbackName = currentFolder.name;
        parentId = (currentFolder.parent_id ?? currentFolder.parentId ?? 'root') as FolderId;
      }

      chain.push({ id: currentId, name: fallbackName });
      pending.add(currentId);
      currentId = parentId as FolderId | null;
    }

    if (!chain.some((crumb) => crumb.id === 'root')) {
      chain.push({ id: 'root', name: DEFAULT_FOLDER_NAME });
    }

    const ordered: Array<{ id: FolderId; name?: string | null }> = [];
    const seenOrdered = new Set<FolderId>();
    chain
      .slice()
      .reverse()
      .forEach((crumb) => {
        if (!seenOrdered.has(crumb.id)) {
          seenOrdered.add(crumb.id);
          ordered.push(crumb);
        }
      });

    return { breadcrumbs: ordered, missingBreadcrumbAncestors: Array.from(pending) };
  }, [selectedFolder, folderNodes, currentFolder]);

  useEffect(() => {
    if (!missingBreadcrumbAncestors.length) {
      return;
    }

    missingBreadcrumbAncestors.forEach((folderId) => {
      if (!folderId || folderId === 'root') {
        return;
      }
      if (breadcrumbFetchRef.current.has(folderId)) {
        return;
      }

      breadcrumbFetchRef.current.add(folderId);
      ensureFolderData(folderId, { force: false })
        .catch((error) => {
          console.warn('Failed to preload breadcrumb ancestor', folderId, error);
        })
        .finally(() => {
          breadcrumbFetchRef.current.delete(folderId);
        });
    });
  }, [missingBreadcrumbAncestors, ensureFolderData, breadcrumbFetchRef]);

  return breadcrumbs;
};

export default useWorkspaceBreadcrumbs;
