import { useCallback, useMemo } from 'react';
import type { JSX } from 'react';
import DocumentInfoPanel from '../documents/DocumentInfoPanel';
import { DownloadIcon } from '../ui/icons';

interface DocumentLike {
  id?: string | number;
  title?: string;
  content_type?: string;
  filename?: string;
  original_name?: string;
  [key: string]: unknown;
}

interface PreviewEntry {
  url?: string;
  contentType?: string;
  filename?: string;
}

interface ContentTabConfig {
  id?: string;
  label?: string;
  enabled?: boolean;
  forceDisplay?: boolean;
  loadContent?: (options?: { signal?: AbortSignal }) => unknown | Promise<unknown>;
  loadingMessage?: string;
  emptyMessage?: string;
  unavailableMessage?: string;
  errorMessage?: string;
  [key: string]: unknown;
}

type LayoutMode = 'split' | 'stacked' | (string & {});

interface DocumentViewerLayoutProps {
  document?: DocumentLike | null;
  previewEntry?: PreviewEntry | null;
  summaryProps?: Record<string, unknown>;
  metadataPayload?: unknown;
  contentTabConfig?: ContentTabConfig | null;
  resetKey?: string | number | null;
  classNamePrefix?: string;
  defaultTabId?: string;
  infoPanelProps?: Record<string, unknown>;
  previewLoadingMessage?: string;
  layoutMode?: LayoutMode;
}

const DocumentViewerLayout = ({
  document,
  previewEntry,
  summaryProps = {},
  metadataPayload,
  contentTabConfig,
  resetKey,
  classNamePrefix = 'document-viewer',
  defaultTabId = 'details',
  infoPanelProps = {},
  previewLoadingMessage = 'Preparing preview…',
  layoutMode = 'split',
}: DocumentViewerLayoutProps): JSX.Element => {
  const isStacked = layoutMode === 'stacked';

  const previewContent = useMemo(() => {
    if (!document || !previewEntry?.url) {
      return null;
    }

    const normalizedContentType = (previewEntry.contentType
      || document.content_type
      || '')
      .toLowerCase();
    const isImage = normalizedContentType.startsWith('image/');
    const isPdf = normalizedContentType === 'application/pdf'
      || normalizedContentType === 'application/x-pdf';

    if (isImage) {
      return (
        <img
          src={previewEntry.url}
          alt={`Preview of ${document.title}`}
          className="document-viewer__object document-viewer__object--image"
          draggable={false}
        />
      );
    }

    if (isPdf) {
      return (
        <iframe
          src={previewEntry.url}
          title={`Preview of ${document.title}`}
          className="document-viewer__object"
        />
      );
    }

    const displayContentType = document.content_type || previewEntry.contentType || 'this file type';
    const displayFilename = previewEntry.filename
      || document.filename
      || document.original_name
      || 'download';

    return (
      <div className="document-viewer__unsupported">
        <div className="document-viewer__unsupported-message">
          Preview is not available for {displayContentType} files.
        </div>
        <div className="document-viewer__unsupported-filename">{displayFilename}</div>
        <a
          className="button-link document-viewer__unsupported-download"
          href={previewEntry.url}
          download={displayFilename}
          target="_blank"
          rel="noopener noreferrer"
        >
          <DownloadIcon />
          <span>Download</span>
        </a>
      </div>
    );
  }, [previewEntry, document]);

  const renderViewportPane = useCallback(() => (
    <div className="document-viewer__viewport">
      {!previewEntry?.url ? (
        <div className="document-viewer__message">{previewLoadingMessage}</div>
      ) : (
        previewContent
      )}
    </div>
  ), [previewEntry?.url, previewLoadingMessage, previewContent]);

  const viewportPane = renderViewportPane();

  const stackedLeadingTabs = useMemo(() => (
    isStacked
      ? [
          {
            id: 'preview',
            label: 'Preview',
            render: () => renderViewportPane(),
          },
        ]
      : []
  ), [isStacked, renderViewportPane]);

  const resolvedDefaultTabId = isStacked ? 'preview' : defaultTabId;
  const summaryPlacement = 'tabs';
  const tabsPlacement = 'bottom';
  const summaryLayout = 'compact';

  const detailsPane = (
    <div className="document-viewer__details-pane">
      <div className="document-viewer__details">
        <DocumentInfoPanel
          document={document}
          summaryProps={summaryProps}
          metadataPayload={metadataPayload}
          contentConfig={contentTabConfig}
          defaultTabId={resolvedDefaultTabId}
          classNamePrefix={classNamePrefix}
          hideTabNavWhenSingle={false}
          resetKey={resetKey || document?.id}
          summaryPlacement={summaryPlacement}
          summaryLayout={summaryLayout}
          leadingTabs={stackedLeadingTabs}
          tabsPlacement={tabsPlacement}
          {...infoPanelProps}
        />
      </div>
    </div>
  );

  if (isStacked) {
    return detailsPane;
  }

  return (
    <>
      {detailsPane}
      {viewportPane}
    </>
  );
};

export default DocumentViewerLayout;
