import { useCallback, useEffect, useMemo } from 'react';
import type { ReactNode } from 'react';
import { SidebarExpandIcon } from '../ui/icons';
import { createDocumentsSurface } from '../documents/DocumentsPanel';
import { createDocumentViewerSurface } from '../preview/DocumentViewerPanel';
import createDesktopSurface from '../desktop/createDesktopSurface';
import { usePanelManager } from './PanelManagerContext';

type Identifier = string | number;

type EnsureAssetUrl = (docId: Identifier, asset: unknown, options?: Record<string, unknown>) => Promise<unknown> | void;
type EnsurePreviewData = (docId: Identifier, options?: Record<string, unknown>) => Promise<unknown>;
type GetDocumentAsset = (document: unknown, assetType: string) => unknown;
type ResolveApiPath = (path: string) => string;
type NotifyApiError = (error: unknown, fallbackMessage?: string) => void;

type DocumentsSurface = ReturnType<typeof createDocumentsSurface> | null;
type PreviewSurface = ReturnType<typeof createDocumentViewerSurface> | null;
type DesktopSurface = ReturnType<typeof createDesktopSurface> | null;
type WorkspaceSurface = DocumentsSurface | PreviewSurface | DesktopSurface | null;

interface UseWorkspaceSurfaceArgs {
  sidebarHidden?: boolean;
  onExpandSidebar?: () => void;
  documentsTableProps?: Record<string, any> | null;
  detailPanelProps?: (Record<string, any> & { onClose?: () => void }) | null;
  detailPanelOpen?: boolean;
  viewMode?: string;
  deskWorkspaceProps?: Record<string, any> | null;
  previewWorkspaceDocument?: unknown;
  previewWorkspaceEntry?: unknown;
  previewDocumentId?: Identifier | null;
  ensureAssetUrl?: EnsureAssetUrl;
  ensurePreviewData?: EnsurePreviewData;
  getDocumentAsset?: GetDocumentAsset;
  resolveApiPath?: ResolveApiPath;
  notifyApiError?: NotifyApiError;
  closeDocumentPreview?: () => void;
}

interface UseWorkspaceSurfaceResult {
  surface: WorkspaceSurface;
}

export const useWorkspaceSurface = ({
  sidebarHidden = false,
  onExpandSidebar,
  documentsTableProps,
  detailPanelProps,
  detailPanelOpen = false,
  viewMode = 'list',
  deskWorkspaceProps,
  previewWorkspaceDocument,
  previewWorkspaceEntry,
  previewDocumentId,
  ensureAssetUrl,
  ensurePreviewData,
  getDocumentAsset,
  resolveApiPath,
  notifyApiError,
  closeDocumentPreview,
}: UseWorkspaceSurfaceArgs): UseWorkspaceSurfaceResult => {
  const { registerDetailCloseHandler, setDetailActive } = usePanelManager();

  useEffect(() => {
    const handler = detailPanelProps?.onClose || null;
    registerDetailCloseHandler(handler);
    return () => registerDetailCloseHandler(null);
  }, [registerDetailCloseHandler, detailPanelProps?.onClose]);

  useEffect(() => {
    setDetailActive(Boolean(detailPanelOpen));
    return () => setDetailActive(false);
  }, [detailPanelOpen, setDetailActive]);

  const renderSidebarToggle = useCallback<() => ReactNode>(() => {
    if (!sidebarHidden) {
      return null;
    }
    return (
      <button
        type="button"
        className="icon-button"
        onClick={onExpandSidebar}
        aria-label="Expand sidebar"
        title="Expand sidebar"
      >
        <SidebarExpandIcon />
      </button>
    );
  }, [sidebarHidden, onExpandSidebar]);

  const documentsSurface = useMemo<DocumentsSurface>(() => {
    if (!documentsTableProps) {
      return null;
    }
    return createDocumentsSurface({
      tableProps: documentsTableProps,
      renderSidebarToggle,
      detailProps: detailPanelProps,
      detailOpen: detailPanelOpen,
    });
  }, [
    documentsTableProps,
    renderSidebarToggle,
    detailPanelProps,
    detailPanelOpen,
  ]);

  const showPreviewWorkspace = Boolean(previewDocumentId);

  const previewSurface = useMemo<PreviewSurface>(() => {
    if (!showPreviewWorkspace) {
      return null;
    }
    const detailExtras = detailPanelProps || {};
    const {
      tagLookupById,
      tags: tagOptions,
      onTagAdd,
      onTagRemove,
      correspondents,
      onCorrespondentAdd,
      onCorrespondentRemove,
      onUpdateTitle,
      onUpdateIssued,
      resolveFolderPath,
    } = detailExtras;
    return createDocumentViewerSurface({
      document: previewWorkspaceDocument,
      previewEntry: previewWorkspaceEntry,
      ensureAssetUrl,
      ensurePreviewData,
      getDocumentAsset,
      resolveApiPath,
      notifyApiError,
      onClose: closeDocumentPreview,
      renderSidebarToggle,
      tagLookupById,
      tagOptions,
      onTagAdd,
      onTagRemove,
      correspondents,
      onCorrespondentAdd,
      onCorrespondentRemove,
      onUpdateTitle,
      onUpdateIssued,
      resolveFolderPath,
    });
  }, [
    showPreviewWorkspace,
    previewWorkspaceDocument,
    previewWorkspaceEntry,
    ensureAssetUrl,
    ensurePreviewData,
    getDocumentAsset,
    resolveApiPath,
    notifyApiError,
    closeDocumentPreview,
    renderSidebarToggle,
    detailPanelProps,
  ]);

  const workspaceSurface = useMemo<DesktopSurface>(() => {
    if (viewMode !== 'desk') {
      return null;
    }
    return createDesktopSurface({
      workspaceProps: deskWorkspaceProps,
      renderSidebarToggle,
      detailProps: detailPanelProps,
      detailOpen: detailPanelOpen,
    });
  }, [
    viewMode,
    deskWorkspaceProps,
    renderSidebarToggle,
    detailPanelProps,
    detailPanelOpen,
  ]);

  const surface = useMemo<WorkspaceSurface>(() => {
    if (showPreviewWorkspace) {
      return previewSurface;
    }
    if (viewMode === 'desk') {
      return workspaceSurface;
    }
    return documentsSurface;
  }, [showPreviewWorkspace, viewMode, previewSurface, workspaceSurface, documentsSurface]);

  return { surface };
};
