"use client";

import * as React from "react";
import { Loading } from "@/components/ui/loading";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { Button } from "@/components/ui/button";

// Type definitions for the dynamically loaded library
interface PdfLib {
  Document: any;
  Page: any;
  pdfjs: any;
}

export interface PdfViewerDocumentProps {
  url: string;
  canDownload?: boolean;
  onNumPages: (n: number) => void;
  pageNumber: number;
  scale: number;
  onError?: (error: Error) => void;
  token?: string | null;
}

export function PdfViewerDocument({
  url,
  onNumPages,
  pageNumber,
  scale,
  onError,
  token,
}: PdfViewerDocumentProps) {
  const [pdfLib, setPdfLib] = React.useState<PdfLib | null>(null);
  const [fileBlob, setFileBlob] = React.useState<Blob | null>(null);
  const [loadError, setLoadError] = React.useState<string | null>(null);

  // 1. Polyfill & Load Library
  React.useEffect(() => {
    async function init() {
      try {
        // Polyfill Promise.withResolvers for PDF.js 4+
        if (typeof Promise.withResolvers === "undefined") {
          // @ts-ignore
          Promise.withResolvers = function () {
            let resolve, reject;
            const promise = new Promise((res, rej) => {
              resolve = res;
              reject = rej;
            });
            return { promise, resolve, reject };
          };
        }

        // Dynamically import react-pdf ONLY on client
        const lib = await import("react-pdf");
        
        // Import styles
        // @ts-ignore - CSS modules may not have type declarations but are handled by the bundler
        await import("react-pdf/dist/Page/AnnotationLayer.css");
        // @ts-ignore
        await import("react-pdf/dist/Page/TextLayer.css");

        // Set worker
        const version = lib.pdfjs.version || "4.4.168";
        lib.pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${version}/legacy/build/pdf.worker.min.js`;

        setPdfLib({
          Document: lib.Document,
          Page: lib.Page,
          pdfjs: lib.pdfjs,
        });
      } catch (err) {
        console.error("Failed to initialize PDF library:", err);
        setLoadError("Failed to initialize PDF engine");
        onError?.(err instanceof Error ? err : new Error("Init failed"));
      }
    }
    init();
  }, [onError]);

  // 2. Fetch authenticated blob if needed
  React.useEffect(() => {
    if (!url || !token) {
      setFileBlob(null);
      return;
    }

    async function fetchPdf() {
      try {
        console.log("Fetching PDF from:", url);
        const response = await fetch(url, {
          headers: { Authorization: `Bearer ${token}` },
        });
        
        if (!response.ok) {
          const text = await response.text().catch(() => "Unknown error");
          throw new Error(`Failed to download: ${response.status} ${text}`);
        }

        const contentType = response.headers.get("content-type");
        if (contentType && !contentType.includes("application/pdf")) {
          console.warn("Received non-PDF content type:", contentType);
          // If it's JSON, it might be a hidden error
          if (contentType.includes("application/json")) {
            const json = await response.json().catch(() => ({}));
            throw new Error(json.message || "Server returned an error instead of a PDF");
          }
        }

        const blob = await response.blob();
        console.log("PDF Blob received, size:", blob.size);
        
        const blobUrl = URL.createObjectURL(blob);
        setFileBlob(blob);
        
        // Use a state for the object URL to cleanup later
        setInternalUrl(blobUrl);
      } catch (err) {
        console.error("PDF Fetch Error:", err);
        setLoadError(err instanceof Error ? err.message : "Failed to download secure document");
        onError?.(err instanceof Error ? err : new Error("Fetch failed"));
      }
    }
    fetchPdf();
  }, [url, token, onError]);

  const [internalUrl, setInternalUrl] = React.useState<string | null>(null);

  React.useEffect(() => {
    return () => {
      if (internalUrl) URL.revokeObjectURL(internalUrl);
    };
  }, [internalUrl]);

  if (loadError) {
    return (
      <div className="py-20 text-center text-red-500 font-medium">
        {loadError}
      </div>
    );
  }

  if (!pdfLib || (token && !fileBlob)) {
    return (
      <Loading
        layout="section"
        className="py-40"
        size="lg"
        spinnerClassName="text-[#6C63FF]"
        message={!pdfLib ? "Loading PDF engine…" : "Fetching document…"}
      />
    );
  }

  const { Document, Page } = pdfLib;

  return (
    <Document
      file={token ? internalUrl! : url}
      onLoadSuccess={({ numPages }: { numPages: number }) => onNumPages(numPages)}
      loading={
        <Loading
          layout="section"
          className="py-40 animate-pulse"
          size="lg"
          spinnerClassName="text-[#6C63FF]"
          message="Initializing viewer…"
        />
      }
      onLoadError={(error: Error) => {
        console.error("PDF Load Error:", error);
        onError?.(error);
      }}
    >
      <div className="shadow-[0_20px_50px_rgba(0,0,0,0.1)] border border-gray-100 rounded-sm bg-white transition-transform duration-300 ease-out">
        <Page
          pageNumber={pageNumber}
          scale={scale}
          renderAnnotationLayer={true}
          renderTextLayer={true}
          className="max-w-full"
          width={Math.min(
            typeof window !== "undefined" ? window.innerWidth * 0.9 : 800,
            800,
          )}
        />
      </div>
    </Document>
  );
}

export function PdfViewerPager({
  pageNumber,
  numPages,
  onPrev,
  onNext,
}: {
  pageNumber: number;
  numPages: number;
  onPrev: () => void;
  onNext: () => void;
}) {
  if (numPages <= 1) return null;
  return (
    <div className="p-4 border-t border-gray-100 flex items-center justify-center gap-4 bg-white/50 shrink-0">
      <Button
        variant="outline"
        size="sm"
        disabled={pageNumber <= 1}
        onClick={onPrev}
        className="rounded-xl px-4 h-9 font-bold text-[11px] uppercase tracking-widest border-gray-200"
      >
        <ChevronLeft size={16} className="mr-1" />
        Prev
      </Button>
      <div className="flex items-center gap-1.5 px-4 py-1.5 rounded-xl bg-gray-100/80 border border-gray-200/50">
        <span className="text-[10px] font-bold text-gray-400 uppercase tracking-tighter">
          Pg.
        </span>
        <span className="text-sm font-black text-gray-700">{pageNumber}</span>
        <span className="text-[10px] font-bold text-gray-400">/</span>
        <span className="text-sm font-bold text-gray-400 tracking-tighter">
          {numPages}
        </span>
      </div>
      <Button
        variant="outline"
        size="sm"
        disabled={pageNumber >= numPages}
        onClick={onNext}
        className="rounded-xl px-4 h-9 font-bold text-[11px] uppercase tracking-widest border-gray-200"
      >
        Next
        <ChevronRight size={16} className="ml-1" />
      </Button>
    </div>
  );
}
