import React, { useEffect, useRef, useState, useCallback } from 'react';
import { pdfjs } from './pdfSetup';
import type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';
import {
  ChevronLeft, ChevronRight, ZoomIn, ZoomOut, Download,
  Printer, Maximize2, Minimize2, RotateCw, Loader,
} from 'lucide-react';

interface PdfViewerProps {
  /** URL or API endpoint that returns the PDF bytes */
  src: string;
  /** JWT token for Authorization header */
  token?: string;
  fileName?: string;
  onPageCount?: (n: number) => void;
}

export default function PdfViewer({ src, token, fileName = 'documento.pdf', onPageCount }: PdfViewerProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const renderTaskRef = useRef<any>(null);

  const [pdfDoc, setPdfDoc] = useState<PDFDocumentProxy | null>(null);
  const [page, setPage] = useState(1);
  const [numPages, setNumPages] = useState(0);
  const [scale, setScale] = useState(1.2);
  const [rotation, setRotation] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [fullscreen, setFullscreen] = useState(false);
  const [pageInput, setPageInput] = useState('1');

  // Load PDF
  useEffect(() => {
    if (!src) return;
    let cancelled = false;
    setLoading(true);
    setError('');

    const headers: Record<string, string> = {};
    if (token) headers['Authorization'] = `Bearer ${token}`;

    const task = pdfjs.getDocument({ url: src, httpHeaders: headers });
    task.promise
      .then(doc => {
        if (cancelled) return;
        setPdfDoc(doc);
        setNumPages(doc.numPages);
        setPage(1);
        setPageInput('1');
        onPageCount?.(doc.numPages);
        setLoading(false);
      })
      .catch(e => {
        if (!cancelled) { setError('Erro ao carregar PDF: ' + e.message); setLoading(false); }
      });
    return () => { cancelled = true; };
  }, [src, token]);

  // Render page
  const renderPage = useCallback(async (doc: PDFDocumentProxy, pageNum: number, s: number, rot: number) => {
    if (!canvasRef.current) return;
    if (renderTaskRef.current) { renderTaskRef.current.cancel(); renderTaskRef.current = null; }
    const pdfPage: PDFPageProxy = await doc.getPage(pageNum);
    const viewport = pdfPage.getViewport({ scale: s, rotation: rot });
    const canvas = canvasRef.current;
    canvas.width = viewport.width;
    canvas.height = viewport.height;
    const ctx = canvas.getContext('2d')!;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    const task = pdfPage.render({ canvasContext: ctx, viewport, canvas });
    renderTaskRef.current = task;
    try { await task.promise; } catch (_) { /* cancelled */ }
    renderTaskRef.current = null;
  }, []);

  useEffect(() => {
    if (pdfDoc) renderPage(pdfDoc, page, scale, rotation);
  }, [pdfDoc, page, scale, rotation, renderPage]);

  const go = (delta: number) => {
    const next = Math.max(1, Math.min(numPages, page + delta));
    setPage(next); setPageInput(String(next));
  };

  const zoom = (delta: number) => setScale(s => Math.max(0.4, Math.min(4, parseFloat((s + delta).toFixed(2)))));

  const handleDownload = () => {
    const a = document.createElement('a');
    a.href = src; a.download = fileName;
    if (token) {
      // fetch and blob download for auth-protected URL
      fetch(src, { headers: { Authorization: `Bearer ${token}` } })
        .then(r => r.blob())
        .then(blob => {
          const url = URL.createObjectURL(blob);
          a.href = url; document.body.appendChild(a); a.click();
          document.body.removeChild(a); URL.revokeObjectURL(url);
        });
    } else { document.body.appendChild(a); a.click(); document.body.removeChild(a); }
  };

  const outer = fullscreen
    ? 'fixed inset-0 z-[100] bg-gray-900 flex flex-col'
    : 'flex flex-col h-full bg-gray-100 rounded-xl overflow-hidden';

  return (
    <div className={outer}>
      {/* Toolbar */}
      <div className="flex items-center gap-1.5 px-4 py-2 bg-white border-b border-gray-200 shrink-0 flex-wrap">
        {/* Navigation */}
        <button onClick={() => go(-1)} disabled={page <= 1}
          className="p-1.5 rounded hover:bg-gray-100 disabled:opacity-40 transition-colors" title="Página anterior">
          <ChevronLeft size={16} />
        </button>
        <div className="flex items-center gap-1.5">
          <input
            value={pageInput}
            onChange={e => setPageInput(e.target.value)}
            onBlur={() => {
              const n = parseInt(pageInput);
              if (!isNaN(n) && n >= 1 && n <= numPages) { setPage(n); }
              else setPageInput(String(page));
            }}
            onKeyDown={e => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur(); }}
            className="w-10 text-center border border-gray-300 rounded px-1 py-0.5 text-xs focus:outline-none focus:border-blue-400"
          />
          <span className="text-xs text-gray-500">/ {numPages}</span>
        </div>
        <button onClick={() => go(1)} disabled={page >= numPages}
          className="p-1.5 rounded hover:bg-gray-100 disabled:opacity-40 transition-colors" title="Próxima página">
          <ChevronRight size={16} />
        </button>
        <div className="w-px h-5 bg-gray-200 mx-1" />
        {/* Zoom */}
        <button onClick={() => zoom(-0.2)} className="p-1.5 rounded hover:bg-gray-100 transition-colors" title="Diminuir zoom">
          <ZoomOut size={16} />
        </button>
        <select value={scale} onChange={e => setScale(parseFloat(e.target.value))}
          className="text-xs border border-gray-200 rounded px-1.5 py-1 focus:outline-none bg-white">
          {[0.5, 0.75, 1, 1.25, 1.5, 2, 2.5, 3].map(v => (
            <option key={v} value={v}>{Math.round(v * 100)}%</option>
          ))}
        </select>
        <button onClick={() => zoom(0.2)} className="p-1.5 rounded hover:bg-gray-100 transition-colors" title="Aumentar zoom">
          <ZoomIn size={16} />
        </button>
        <div className="w-px h-5 bg-gray-200 mx-1" />
        {/* Rotate */}
        <button onClick={() => setRotation(r => (r + 90) % 360)}
          className="p-1.5 rounded hover:bg-gray-100 transition-colors" title="Girar 90°">
          <RotateCw size={16} />
        </button>
        <div className="w-px h-5 bg-gray-200 mx-1" />
        {/* Actions */}
        <button onClick={handleDownload}
          className="p-1.5 rounded hover:bg-gray-100 transition-colors" title="Baixar PDF">
          <Download size={16} />
        </button>
        <button onClick={() => window.print()}
          className="p-1.5 rounded hover:bg-gray-100 transition-colors" title="Imprimir">
          <Printer size={16} />
        </button>
        <button onClick={() => setFullscreen(f => !f)}
          className="p-1.5 rounded hover:bg-gray-100 transition-colors ml-auto" title="Tela cheia">
          {fullscreen ? <Minimize2 size={16} /> : <Maximize2 size={16} />}
        </button>
      </div>

      {/* Canvas area */}
      <div className="flex-1 overflow-auto flex items-start justify-center bg-gray-200 p-4">
        {loading && (
          <div className="flex flex-col items-center justify-center h-full gap-3 text-gray-500">
            <Loader size={32} className="animate-spin text-blue-500" />
            <p className="text-sm">Carregando PDF...</p>
          </div>
        )}
        {error && (
          <div className="flex items-center justify-center h-full">
            <p className="text-red-500 text-sm bg-red-50 border border-red-200 rounded-lg px-4 py-3">{error}</p>
          </div>
        )}
        {!loading && !error && (
          <div className="shadow-2xl">
            <canvas ref={canvasRef} className="block bg-white" />
          </div>
        )}
      </div>

      {/* Footer */}
      {!loading && !error && (
        <div className="shrink-0 px-4 py-1.5 bg-white border-t border-gray-200 flex items-center justify-between text-xs text-gray-400">
          <span>{fileName}</span>
          <span>{Math.round(scale * 100)}% · {rotation}° · p. {page}/{numPages}</span>
        </div>
      )}
    </div>
  );
}
