import { useEffect, useState } from 'react';
import { createAssetView } from '../../asset_manager';

interface DocumentLike {
  id?: string | number;
  current_version?: unknown;
  tags?: unknown;
}

interface AssetLike {
  id?: string | number;
  [key: string]: unknown;
}

interface PreviewMetadataEntry {
  docId: string;
  width: number;
  height: number;
}

type GetDocumentAsset = (doc: DocumentLike, type: string) => AssetLike | null | undefined;
type EnsureAssetUrl = (docId: string | number, asset: AssetLike, options?: { start?: number; limit?: number }) => Promise<AssetLike | null | undefined>;

const usePreviewMetadata = (
  documents: DocumentLike[] | null | undefined,
  getDocumentAsset?: GetDocumentAsset,
  ensureAssetUrl?: EnsureAssetUrl,
) => {
  const [metadataMap, setMetadataMap] = useState<Map<string, PreviewMetadataEntry>>(() => new Map());

  useEffect(() => {
    let cancelled = false;
    const docs = Array.isArray(documents) ? documents : [];
    if (!docs.length) {
      setMetadataMap(new Map());
      return () => {
        cancelled = true;
      };
    }

    const fetchMetadataForDoc = async (doc: DocumentLike) => {
      if (!doc?.id) {
        return null;
      }

      const docId = String(doc.id);
      const resolveAsset = (type: string) => getDocumentAsset?.(doc, type) ?? null;

      let asset = resolveAsset('preview') || resolveAsset('thumbnail');
      let view = createAssetView(asset);
      let metadata = view.getPrimaryMetadata();

      const hasDimensions = (meta: { width?: number | string; height?: number | string } | null | undefined) =>
        Number.isFinite(Number(meta?.width)) &&
        Number.isFinite(Number(meta?.height)) &&
        Number(meta.width) > 0 &&
        Number(meta.height) > 0;

      if (!hasDimensions(metadata) && ensureAssetUrl && docId && asset?.id) {
        try {
          const ensured = await ensureAssetUrl(doc.id, asset, { start: 1, limit: 1 });
          if (ensured) {
            asset = ensured;
            view = createAssetView(asset);
            metadata = view.getPrimaryMetadata();
          }
        } catch (error) {
          console.warn('[desk] ensureDocumentSize metadata fetch failed', error);
        }
      }

      if (!hasDimensions(metadata)) {
        return null;
      }

      return {
        docId,
        width: Number(metadata.width),
        height: Number(metadata.height),
      };
    };

    let mounted = true;
    (async () => {
      const entries = await Promise.all(docs.map(fetchMetadataForDoc));
      if (!mounted || cancelled) {
        return;
      }
      const next = new Map();
      entries.forEach((entry) => {
        if (entry && entry.docId) {
          next.set(entry.docId, entry);
        }
      });
      if (!cancelled) {
        setMetadataMap(next);
      }
    })();

    return () => {
      cancelled = true;
      mounted = false;
    };
  }, [documents, getDocumentAsset, ensureAssetUrl]);

  return metadataMap;
};

export default usePreviewMetadata;
