import { useEffect } from 'react';
import type { JSX } from 'react';
import { useAssetNavigator } from '../hooks/useAssetNavigator';
import type { Identifier } from '../types/identifiers';
import type { Document } from '../types/documents';

interface AssetLike {
  id?: Identifier;
  url?: string | null;
  expires_at?: number | null;
  metadata?: Record<string, unknown> | null;
  [key: string]: unknown;
}

type EnsureAssetUrl = (
  documentId: Identifier,
  asset: AssetLike,
  options?: { force?: boolean;[key: string]: unknown },
) => Promise<unknown>;

type GetDocumentAsset = (document: Document | null, assetType: string) => AssetLike | null;

interface NavigatorSnapshot {
  url: string | null;
  alt?: string;
  width: number | null;
  height: number | null;
}

interface DesktopPreviewCardProps {
  doc: Document | null;
  title?: string;
  ensureAssetUrl?: EnsureAssetUrl | null;
  getDocumentAsset?: GetDocumentAsset;
  onNavigatorSnapshot?: (docId: Identifier, snapshot: NavigatorSnapshot | null) => void;
  shouldLoad?: boolean;
}

const DesktopPreviewCard = ({
  doc,
  title,
  ensureAssetUrl,
  getDocumentAsset,
  onNavigatorSnapshot,
  shouldLoad = true,
}: DesktopPreviewCardProps): JSX.Element => {
  const navigator = useAssetNavigator({
    document: doc,
    assetType: 'thumbnail',
    ensureAssetUrl: shouldLoad ? ensureAssetUrl : null,
    getAsset: getDocumentAsset,
  });

  const { currentUrl, currentMetadata } = navigator;
  const docId = doc?.id ?? null;

  const metadataWidth = Number((currentMetadata as { width?: number } | null)?.width);
  const metadataHeight = Number((currentMetadata as { height?: number } | null)?.height);

  useEffect(() => {
    if (!onNavigatorSnapshot || !docId) {
      return undefined;
    }
    if (!currentUrl) {
      onNavigatorSnapshot(docId, null);
      return undefined;
    }
    const snapshot = {
      url: currentUrl,
      alt: title,
      width: Number.isFinite(metadataWidth) && metadataWidth > 0 ? metadataWidth : null,
      height: Number.isFinite(metadataHeight) && metadataHeight > 0 ? metadataHeight : null,
    };
    onNavigatorSnapshot(docId, snapshot);
    return () => onNavigatorSnapshot(docId, null);
  }, [
    docId,
    currentUrl,
    title,
    metadataWidth,
    metadataHeight,
    onNavigatorSnapshot,
  ]);

  const hasPreview = Boolean(currentUrl);
  const cardClasses = ['desk-item__card'];
  if (!hasPreview) cardClasses.push('desk-item__card--empty');
  return (
    <div
      className={cardClasses.join(' ')}
      onDragStart={(event) => {
        if (event instanceof DragEvent) {
          event.preventDefault();
        }
      }}
    >
      {hasPreview ? (
        <img
          src={currentUrl}
          alt={title}
          draggable={false}
          onDragStart={(event) => event.preventDefault()}
        />
      ) : (
        <div className="desk-item__empty">
          <div className="desk-item__placeholder">DOC</div>
          <div className="desk-item__title" title={title}>
            {title}
          </div>
        </div>
      )}
    </div>
  );
};

export default DesktopPreviewCard;
