import React, { useState, useEffect, useRef } from 'react';

interface PdfThumbnailProps {
  url: string;
  title: string;
  fallback: React.ReactNode;
}

// Simple in-memory cache for rendered thumbnails to avoid reprocessing the same PDFs during a session
const thumbnailCache: Record<string, string> = {};

export const PdfThumbnail: React.FC<PdfThumbnailProps> = ({ url, title, fallback }) => {
  const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(thumbnailCache[url] || null);
  const [error, setError] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(!thumbnailCache[url]);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);

  useEffect(() => {
    if (thumbnailUrl) {
      setLoading(false);
      return;
    }

    let isMounted = true;

    const loadPdfAndRender = async () => {
      try {
        // 1. Ensure PDF.js script is loaded dynamically
        if (!(window as any).pdfjsLib) {
          await new Promise<void>((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js';
            script.async = true;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error('Failed to load PDF.js library'));
            document.body.appendChild(script);
          });
        }

        const pdfjs = (window as any).pdfjsLib;
        if (!pdfjs) throw new Error('PDF.js lib not available');

        // Configure PDF.js Worker
        pdfjs.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';

        // 2. Fetch and load the PDF document
        const loadingTask = pdfjs.getDocument(url);
        const pdf = await loadingTask.promise;

        if (!isMounted) return;

        // 3. Load the first page of the PDF
        const page = await pdf.getPage(1);

        if (!isMounted) return;

        // Create a temporary canvas if not in DOM yet
        const canvas = canvasRef.current || document.createElement('canvas');
        const context = canvas.getContext('2d');
        if (!context) throw new Error('Could not get 2D context');

        // We want a thumbnail width of around 220px to fit the card well
        const originalViewport = page.getViewport({ scale: 1.0 });
        const scale = 220 / originalViewport.width;
        const viewport = page.getViewport({ scale });

        canvas.width = viewport.width;
        canvas.height = viewport.height;

        // Render PDF page to canvas
        const renderContext = {
          canvasContext: context,
          viewport: viewport,
        };

        await page.render(renderContext).promise;

        if (!isMounted) return;

        // Convert canvas rendering to a base64 image URL for high performance image display
        const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
        thumbnailCache[url] = dataUrl;
        
        if (isMounted) {
          setThumbnailUrl(dataUrl);
          setLoading(false);
        }
      } catch (err) {
        console.error('[PdfThumbnail] Failed to render first page preview:', err);
        if (isMounted) {
          setError(true);
          setLoading(false);
        }
      }
    };

    loadPdfAndRender();

    return () => {
      isMounted = false;
    };
  }, [url]);

  if (error) {
    return <>{fallback}</>;
  }

  return (
    <div className="w-full h-full flex items-center justify-center relative overflow-hidden bg-ink-50">
      {/* Hidden canvas for offscreen rendering */}
      <canvas ref={canvasRef} className="hidden" />

      {loading ? (
        <div className="flex flex-col items-center justify-center w-full h-full p-4 space-y-2">
          <div className="w-5 h-5 rounded-full border-2 border-ink-400 border-t-transparent animate-spin" />
          <span className="text-[10px] text-ink-400 font-medium">Generating preview...</span>
        </div>
      ) : thumbnailUrl ? (
        <img
          src={thumbnailUrl}
          alt={title}
          className="w-full h-full object-cover object-top transition-transform duration-500 group-hover:scale-105"
        />
      ) : (
        fallback
      )}
    </div>
  );
};
