'use client';

import { useEffect, useMemo, useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import { ChevronLeft, ChevronRight, Loader2, Minus, Plus } from 'lucide-react';

import { Button } from '@/components/ui/button';
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';

/**
 * In-app PDF viewer.
 *
 * Replaces the `<iframe>` preview which delegated rendering to the
 * browser's built-in PDF viewer. The iframe path works on desktop
 * Chrome/Firefox/Safari but is unreliable on mobile (older Android
 * Chrome refuses to render PDFs inline; iOS Safari opens a new tab).
 * react-pdf renders via pdfjs-dist which works identically everywhere.
 *
 * The pdfjs worker is loaded from a CDN matched to the installed
 * pdfjs-dist version. Bundling the worker locally would inflate the
 * main-route bundle by ~150kb; the CDN avoids that cost on every page
 * that uses pdfjs at the cost of a single first-load fetch per user.
 */

// Match the pdfjs.version that react-pdf has bundled at runtime. If
// pdfjs-dist is bumped, the URL auto-tracks. .mjs (module worker) is
// the current pdfjs distribution; .js fallback handled by pdf.js
// internally for older browsers.
pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;

interface PdfViewerProps {
  url: string;
  /** Optional aria-friendly filename for the document. */
  fileName?: string;
}

export function PdfViewer({ url, fileName }: PdfViewerProps) {
  const [numPages, setNumPages] = useState<number | null>(null);
  const [pageNumber, setPageNumber] = useState(1);
  const [scale, setScale] = useState(1);
  const [error, setError] = useState<string | null>(null);

  // Keep options stable across renders so react-pdf doesn't refetch
  // every render — useMemo wins because react-pdf compares by identity.
  const options = useMemo(
    () => ({
      // Inline the worker fetch URL above; CMap/StandardFontDataUrl
      // pull from the same CDN for unicode + non-system fonts.
      cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,
      standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts/`,
    }),
    [],
  );

  useEffect(() => {
    // Reset on url change so navigation between documents lands on
    // page 1 at default zoom.
    setPageNumber(1);
    setScale(1);
    setError(null);
  }, [url]);

  return (
    <div className="flex h-full flex-col">
      <div className="flex items-center justify-between gap-2 border-b bg-muted/40 px-3 py-2 text-sm">
        <div className="flex items-center gap-1">
          <Button
            type="button"
            variant="ghost"
            size="icon"
            disabled={pageNumber <= 1}
            onClick={() => setPageNumber((p) => Math.max(1, p - 1))}
            aria-label="Previous page"
          >
            <ChevronLeft className="h-4 w-4" />
          </Button>
          <span className="min-w-[80px] text-center tabular-nums">
            {numPages ? `${pageNumber} / ${numPages}` : '—'}
          </span>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            disabled={numPages === null || pageNumber >= numPages}
            onClick={() => setPageNumber((p) => (numPages ? Math.min(numPages, p + 1) : p))}
            aria-label="Next page"
          >
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>

        <div className="flex items-center gap-1">
          <Button
            type="button"
            variant="ghost"
            size="icon"
            onClick={() => setScale((s) => Math.max(0.5, s - 0.25))}
            aria-label="Zoom out"
          >
            <Minus className="h-4 w-4" />
          </Button>
          <span className="min-w-[48px] text-center tabular-nums">{Math.round(scale * 100)}%</span>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            onClick={() => setScale((s) => Math.min(3, s + 0.25))}
            aria-label="Zoom in"
          >
            <Plus className="h-4 w-4" />
          </Button>
        </div>
      </div>

      <div className="flex-1 overflow-auto bg-muted/30 p-4">
        {error ? (
          <div className="flex h-full items-center justify-center text-sm text-destructive">
            {error}
          </div>
        ) : (
          <div className="flex justify-center">
            <Document
              file={url}
              options={options}
              onLoadSuccess={({ numPages: n }) => setNumPages(n)}
              onLoadError={(err) => setError(err.message || 'Failed to load PDF')}
              loading={
                <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  Loading PDF…
                </div>
              }
            >
              <Page
                pageNumber={pageNumber}
                scale={scale}
                renderAnnotationLayer
                renderTextLayer
                aria-label={fileName ? `${fileName}, page ${pageNumber}` : `Page ${pageNumber}`}
              />
            </Document>
          </div>
        )}
      </div>
    </div>
  );
}
