import React, { useCallback, useEffect, useMemo } from 'react';
import type { ReactNode } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAppShell } from '../appShellContext';
import DocumentsLayout from './DocumentsLayout';
import { useWorkspaceSurface } from './useWorkspaceSurface';
import PanelHeader from '../ui/PanelHeader';
import BreadcrumbTrail from '../ui/BreadcrumbTrail';
import { SidebarProvider, useSidebarContext } from '../sidebar/SidebarContext';
import { PanelManagerProvider, usePanelManager } from './PanelManagerContext';

type Identifier = string | number;

type Breadcrumb = { id?: Identifier; name?: string; label?: string; title?: string };

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;

interface DocumentsTableProps {
  breadcrumbs?: Breadcrumb[] | null;
  [key: string]: unknown;
}

interface DocumentsRouteAppShell {
  sidebarProps?: Record<string, unknown> | null;
  documentsTableProps?: DocumentsTableProps | null;
  detailPanelProps?: Record<string, unknown> | null;
  detailPanelOpen?: boolean;
  documentsViewMode?: string;
  deskWorkspaceProps?: Record<string, unknown> | null;
  openTagsModal?: () => void;
  openCorrespondentsModal?: () => void;
  previewWorkspaceDocument?: unknown;
  previewWorkspaceEntry?: unknown;
  previewDocumentId?: Identifier | null;
  closeDocumentPreview?: () => void;
  ensurePreviewData?: EnsurePreviewData;
  resolveApiPath?: ResolveApiPath;
  ensureAssetUrl?: EnsureAssetUrl;
  getDocumentAsset?: GetDocumentAsset;
  notifyApiError?: NotifyApiError;
}

const DocumentsRouteContent: React.FC = () => {
  const {
    sidebarProps,
    documentsTableProps,
    detailPanelProps,
    detailPanelOpen,
    documentsViewMode,
    deskWorkspaceProps,
    openTagsModal,
    openCorrespondentsModal,
    previewWorkspaceDocument,
    previewWorkspaceEntry,
    previewDocumentId,
    closeDocumentPreview,
    ensurePreviewData,
    resolveApiPath,
    ensureAssetUrl,
    getDocumentAsset,
    notifyApiError,
  } = useAppShell() as DocumentsRouteAppShell;
  const navigate = useNavigate();
  const { collapsed: sidebarCollapsed } = useSidebarContext();
  const {
    sidebarSuppressed,
    expandSidebar,
  } = usePanelManager();

  const safeSidebarProps = useMemo<Record<string, unknown>>(
    () => (sidebarProps && typeof sidebarProps === 'object' ? sidebarProps : {}),
    [sidebarProps],
  );

  const sidebarPropsWithActions = useMemo(
    () => ({
      ...safeSidebarProps,
      onManageTags: openTagsModal,
      onManageCorrespondents: openCorrespondentsModal,
    }),
    [safeSidebarProps, openTagsModal, openCorrespondentsModal],
  );

  const sidebarHidden = sidebarCollapsed || sidebarSuppressed;

  const handleHeaderBreadcrumbClick = useCallback((crumb: Breadcrumb) => {
    if (!crumb || !crumb.id) {
      return;
    }
    const target = crumb.id === 'root' ? '/documents' : `/documents/folder/${crumb.id}`;
    navigate(target);
  }, [navigate]);

  const { surface } = useWorkspaceSurface({
    sidebarHidden,
    onExpandSidebar: expandSidebar,
    documentsTableProps,
    detailPanelProps,
    detailPanelOpen,
    viewMode: documentsViewMode,
    deskWorkspaceProps,
    previewWorkspaceDocument,
    previewWorkspaceEntry,
    previewDocumentId,
    ensureAssetUrl,
    ensurePreviewData,
    getDocumentAsset,
    resolveApiPath,
    notifyApiError,
    closeDocumentPreview,
  });

  useEffect(() => {
    document.body.classList.add('has-main-content');
    return () => {
      document.body.classList.remove('has-main-content');
    };
  }, []);

  if (!surface) {
    return (
      <DocumentsLayout sidebarProps={sidebarPropsWithActions}>
        <div className="main-content main-content--documents">
          <div className="main-content__body main-content__body--documents" />
        </div>
      </DocumentsLayout>
    );
  }

  const variant = surface.variant || 'documents';

  const surfaceDetail = (surface as { detail?: ReactNode }).detail || null;
  const hasDetail = Boolean(surfaceDetail);

  const mainContentClass = `main-content main-content--${variant}${
    hasDetail ? ' main-content--has-detail' : ''
  }`;
  const bodyClass = `main-content__body main-content__body--${variant}${
    hasDetail ? ' main-content__body--has-detail' : ''
  }`;

  const header = surface.header || null;

  let headerTitle: React.ReactNode = null;
  if (header) {
    const breadcrumbEntries = Array.isArray(header.breadcrumbs) ? header.breadcrumbs.filter(Boolean) : [];
    const lastIndex = breadcrumbEntries.length - 1;
    const trailEntries = breadcrumbEntries.length
      ? breadcrumbEntries.map((crumb, index) => ({
          id: crumb.id ?? index,
          label: crumb.name ?? crumb.label ?? crumb.title ?? '',
          onClick: index < lastIndex ? () => handleHeaderBreadcrumbClick(crumb) : null,
        }))
      : [{ id: 'current-location', label: header.title }];

    headerTitle = (
      <h2 className="main-content__title">
        <BreadcrumbTrail
          entries={trailEntries}
          className="main-content__breadcrumbs"
          separator="/"
        />
        {header.subtitle ? (
          <span className="main-content__subtitle">{header.subtitle}</span>
        ) : null}
      </h2>
    );
  }

  return (
    <DocumentsLayout sidebarProps={sidebarPropsWithActions}>
      <div className={mainContentClass}>
        {header ? (
          <>
            <div className="main-content__header-wrapper">
              <PanelHeader
                className="main-content__header"
                leading={header.leading}
                title={headerTitle}
                titleTag="h2"
                actions={header.actions}
              />
            </div>
            {(header.selectionLabel || header.floatingActions) ? (
              <div className="panel-floating-region" aria-live="polite" aria-atomic="true">
                <div className="panel-floating">
                  {header.selectionLabel ? (
                    <span className="panel-floating__label">{header.selectionLabel}</span>
                  ) : null}
                  {header.floatingActions || null}
                </div>
              </div>
            ) : null}
          </>
        ) : null}
        <div className={bodyClass}>{surface.content}</div>
        {surfaceDetail}
      </div>
    </DocumentsLayout>
  );
};

const DocumentsRoute: React.FC = () => (
  <SidebarProvider>
    <PanelManagerProvider>
      <DocumentsRouteContent />
    </PanelManagerProvider>
  </SidebarProvider>
);

export default DocumentsRoute;
