import { useState, useCallback, useMemo, useRef, useEffect } from 'react'
import { Document, Page, pdfjs } from 'react-pdf'

// Type alias for PDFDocumentProxy to avoid direct pdfjs-dist import issues
type PDFDocumentProxy = ReturnType<typeof pdfjs.getDocument> extends Promise<infer T> ? T : never
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { ChevronLeft, ChevronRight, ZoomIn, ZoomOut, Loader2 } from 'lucide-react'
import 'react-pdf/dist/Page/AnnotationLayer.css'
import 'react-pdf/dist/Page/TextLayer.css'

// Configure standard font data URL for proper font rendering
const pdfOptions = {
  standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts/`,
}

interface PDFViewerProps {
  title?: string
  pdfUrl: string
  className?: string
  httpHeaders?: Record<string, string>
}

export default function PDFViewer({ title, pdfUrl, className, httpHeaders }: PDFViewerProps) {
  const [numPages, setNumPages] = useState<number>(0)
  const [pageNumber, setPageNumber] = useState<number>(1)
  const [scale, setScale] = useState<number>(1.0)
  const [documentLoaded, setDocumentLoaded] = useState<boolean>(false)
  const [error, setError] = useState<string | null>(null)

  // Store PDF document reference
  const pdfDocRef = useRef<PDFDocumentProxy | null>(null)

  // Memoize file config to prevent unnecessary reloads
  const fileConfig = useMemo(() => {
    return httpHeaders ? { url: pdfUrl, httpHeaders } : pdfUrl
  }, [pdfUrl, httpHeaders])

  // Reset state when URL changes
  useEffect(() => {
    setDocumentLoaded(false)
    setError(null)
    setNumPages(0)
    setPageNumber(1)
    pdfDocRef.current = null
  }, [pdfUrl])

  const onDocumentLoadSuccess = useCallback((pdf: { numPages: number }) => {
    pdfDocRef.current = pdf as unknown as PDFDocumentProxy
    setNumPages(pdf.numPages)
    setPageNumber(1)
    setDocumentLoaded(true)
    setError(null)
  }, [])

  const onDocumentLoadError = useCallback((err: Error) => {
    console.error('Error loading PDF:', err)
    setError('無法載入 PDF 檔案。請稍後再試。')
    setDocumentLoaded(false)
    pdfDocRef.current = null
  }, [])

  const goToPreviousPage = useCallback(() => {
    setPageNumber((prev) => Math.max(prev - 1, 1))
  }, [])

  const goToNextPage = useCallback(() => {
    setPageNumber((prev) => Math.min(prev + 1, numPages))
  }, [numPages])

  const zoomIn = useCallback(() => {
    setScale((prev) => Math.min(prev + 0.2, 3.0))
  }, [])

  const zoomOut = useCallback(() => {
    setScale((prev) => Math.max(prev - 0.2, 0.5))
  }, [])

  return (
    <Card className={className}>
      {title && (
        <CardHeader>
          <CardTitle>{title}</CardTitle>
        </CardHeader>
      )}
      <CardContent>
        {/* Controls */}
        <div className="flex items-center justify-between mb-4 gap-4 flex-wrap">
          {/* Page Navigation */}
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={goToPreviousPage}
              disabled={pageNumber <= 1 || !documentLoaded}
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <span className="text-sm whitespace-nowrap">
              第 {pageNumber} 頁 / 共 {numPages || '...'} 頁
            </span>
            <Button
              variant="outline"
              size="sm"
              onClick={goToNextPage}
              disabled={pageNumber >= numPages || !documentLoaded}
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>

          {/* Zoom Controls */}
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={zoomOut}
              disabled={scale <= 0.5 || !documentLoaded}
            >
              <ZoomOut className="h-4 w-4" />
            </Button>
            <span className="text-sm whitespace-nowrap w-16 text-center">
              {Math.round(scale * 100)}%
            </span>
            <Button
              variant="outline"
              size="sm"
              onClick={zoomIn}
              disabled={scale >= 3.0 || !documentLoaded}
            >
              <ZoomIn className="h-4 w-4" />
            </Button>
          </div>
        </div>

        {/* PDF Document */}
        <div className="border rounded-md bg-muted/10 overflow-auto max-h-[800px]">
          <div className="flex justify-center p-4">
            {error ? (
              <div className="flex items-center justify-center min-h-[400px]">
                <div className="text-center">
                  <p className="text-destructive font-semibold mb-2">錯誤</p>
                  <p className="text-sm text-muted-foreground">{error}</p>
                </div>
              </div>
            ) : (
              <Document
                key={pdfUrl}
                file={fileConfig}
                options={pdfOptions}
                onLoadSuccess={onDocumentLoadSuccess}
                onLoadError={onDocumentLoadError}
                loading={
                  <div className="flex items-center justify-center min-h-[400px]">
                    <div className="text-center">
                      <Loader2 className="w-12 h-12 animate-spin text-primary mx-auto mb-4" />
                      <p className="text-muted-foreground">載入 PDF 中...</p>
                    </div>
                  </div>
                }
              >
                {documentLoaded && (
                  <Page
                    pageNumber={pageNumber}
                    scale={scale}
                    renderTextLayer={true}
                    renderAnnotationLayer={true}
                    className="shadow-lg"
                    loading={
                      <div className="flex items-center justify-center min-h-[400px]">
                        <Loader2 className="w-8 h-8 animate-spin text-primary" />
                      </div>
                    }
                    error={
                      <div className="text-center p-4 text-destructive">
                        無法載入第 {pageNumber} 頁
                      </div>
                    }
                  />
                )}
              </Document>
            )}
          </div>
        </div>
      </CardContent>
    </Card>
  )
}
