import { useState, useMemo, useRef, useEffect, useCallback } from 'react'
import { createPortal } from 'react-dom'
import { Document, Page, pdfjs } from 'react-pdf'
import { Button, Space, InputNumber, message, Spin } from 'antd'
import {
    ZoomInOutlined,
    ZoomOutOutlined,
    VerticalAlignTopOutlined,
    LeftOutlined,
    RightOutlined,
    CloudDownloadOutlined,
} from '@ant-design/icons'
import 'react-pdf/dist/Page/AnnotationLayer.css'
import 'react-pdf/dist/Page/TextLayer.css'
import './VirtualPDFViewer.css'

// 配置 PDF.js worker
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf-worker/pdf.worker.min.mjs'

function VirtualPDFViewer({ url, filename, toolbarTarget }) {
    const [numPages, setNumPages] = useState(null)
    const [scale, setScale] = useState(1.0)
    const [pdfOriginalSize, setPdfOriginalSize] = useState({ width: 595, height: 842 }) // 默认 A4
    const [currentPage, setCurrentPage] = useState(1)
    const [visiblePages, setVisiblePages] = useState(new Set([1]))
    const containerRef = useRef(null)
    const pageRefs = useRef({})

    // 使用 useMemo 避免不必要的重新加载
    const fileConfig = useMemo(() => ({ url }), [url])

    // Memoize PDF.js options to prevent unnecessary reloads
    const pdfOptions = useMemo(() => ({
        cMapUrl: 'https://unpkg.com/pdfjs-dist@5.4.296/cmaps/',
        cMapPacked: true,
        standardFontDataUrl: 'https://unpkg.com/pdfjs-dist@5.4.296/standard_fonts/',
    }), [])

    // 根据 PDF 实际宽高和缩放比例计算页面高度
    const pageHeight = useMemo(() => {
        // 计算内容高度：缩放后的 PDF 高度 + 上下 padding (40px) + 页码文字区域 (20px)
        return Math.ceil(pdfOriginalSize.height * scale) + 60
    }, [scale, pdfOriginalSize.height])

    const onDocumentLoadError = (error) => {
        console.error('[PDF] Document load error:', error)
        message.error('PDF文件加载失败')
    }



    // Handle scroll to update visible pages
    const handleScroll = useCallback(() => {
        if (!containerRef.current || !numPages) return

        const container = containerRef.current
        const scrollTop = container.scrollTop
        const containerHeight = container.clientHeight

        // Calculate which pages are visible
        // Add small tolerance (1px) to handle browser scroll precision issues
        const pageIndex = scrollTop / pageHeight
        let firstVisiblePage = Math.max(1, Math.ceil(pageIndex + 0.001))

        // Special case: if scrolled to bottom, show last page
        const isAtBottom = scrollTop + containerHeight >= container.scrollHeight - 1
        if (isAtBottom) {
            firstVisiblePage = numPages
        }

        const lastVisiblePage = Math.min(numPages, Math.ceil((scrollTop + containerHeight) / pageHeight))



        // Add buffer pages (2 before and 2 after)
        const newVisiblePages = new Set()
        for (let i = Math.max(1, firstVisiblePage - 2); i <= Math.min(numPages, lastVisiblePage + 2); i++) {
            newVisiblePages.add(i)
        }

        setVisiblePages(newVisiblePages)
        setCurrentPage(firstVisiblePage)
    }, [numPages, pageHeight])

    const onDocumentLoadSuccess = useCallback(async (pdf) => {
        setNumPages(pdf.numPages)

        try {
            // 获取第一页的原始尺寸，用于计算初始缩放
            const page = await pdf.getPage(1)
            const viewport = page.getViewport({ scale: 1.0 })
            const { width, height } = viewport
            setPdfOriginalSize({ width, height })

            // 自动适应宽度：仅当 PDF 宽度超过容器时才进行缩放
            if (containerRef.current) {
                const containerWidth = containerRef.current.clientWidth - 40 // 减去左右内边距
                if (width > containerWidth) {
                    const autoScale = Math.floor((containerWidth / width) * 10) / 10 // 保留一位小数
                    setScale(Math.min(Math.max(autoScale, 0.5), 1.0)) // 限制缩放比例，最高不超 1.0
                } else {
                    setScale(1.0) // 宽度足够则保持 100%
                }
            }
        } catch (err) {
            console.error('Error calculating initial scale:', err)
        }

        // Initially show first 3 pages
        setVisiblePages(new Set([1, 2, 3]))

        // Trigger scroll calculation after a short delay to ensure DOM is ready
        setTimeout(() => {
            handleScroll()
        }, 200)
    }, [handleScroll])

    // Attach scroll listener
    useEffect(() => {
        const container = containerRef.current
        if (!container) return

        container.addEventListener('scroll', handleScroll)
        return () => container.removeEventListener('scroll', handleScroll)
    }, [handleScroll, numPages, pageHeight])

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

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

    const handlePageChange = (value) => {
        if (value >= 1 && value <= numPages && containerRef.current) {
            const scrollTop = (value - 1) * pageHeight
            const container = containerRef.current
            container.scrollTo({ top: scrollTop, behavior: 'auto' })

            // Manually trigger handleScroll after scrolling to ensure page number updates
            setTimeout(() => {
                handleScroll()
            }, 50)
        }
    }

    const scrollToTop = () => {
        if (containerRef.current) {
            containerRef.current.scrollTo({ top: 0, behavior: 'smooth' })
        }
    }

    const handleDownload = () => {
        const link = document.createElement('a')
        link.href = url
        link.download = filename || 'document.pdf'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
    }

    const toolbar = (
        <div className="pdf-toolbar">
            <Space>
                <Button icon={<ZoomOutOutlined />} onClick={zoomOut} size="small">
                    缩小
                </Button>
                <span className="pdf-toolbar-scale">
                    {Math.round(scale * 100)}%
                </span>
                <Button icon={<ZoomInOutlined />} onClick={zoomIn} size="small">
                    放大
                </Button>
                <Button
                    icon={<LeftOutlined />}
                    onClick={() => handlePageChange(currentPage - 1)}
                    disabled={currentPage <= 1}
                    size="small"
                />
                <Space.Compact>
                    <InputNumber
                        min={1}
                        max={numPages || 1}
                        value={currentPage}
                        onChange={handlePageChange}
                        size="small"
                        style={{ width: 60 }}
                    />
                    <Button size="small" disabled>
                        / {numPages || 0}
                    </Button>
                </Space.Compact>
                <Button
                    icon={<RightOutlined />}
                    onClick={() => handlePageChange(currentPage + 1)}
                    disabled={currentPage >= (numPages || 0)}
                    size="small"
                />
                <span className="pdf-toolbar-divider" />
                <Button
                    icon={<VerticalAlignTopOutlined />}
                    onClick={scrollToTop}
                    size="small"
                    disabled={currentPage === 1}
                >
                    回到顶部
                </Button>
                <Button
                    icon={<CloudDownloadOutlined />}
                    onClick={handleDownload}
                    size="small"
                >
                    下载PDF
                </Button>
            </Space>
        </div>
    )

    return (
        <div className="virtual-pdf-viewer-container">
            {toolbarTarget ? createPortal(toolbar, toolbarTarget) : toolbar}

            {/* PDF内容区 - 自定义虚拟滚动 */}
            <div className="pdf-content" ref={containerRef}>
                <Document
                    file={fileConfig}
                    onLoadSuccess={onDocumentLoadSuccess}
                    onLoadError={onDocumentLoadError}
                    loading={
                        <div className="pdf-loading">
                            <Spin size="large" />
                            <div style={{ marginTop: 16 }}>正在加载PDF...</div>
                        </div>
                    }
                    error={<div className="pdf-error">PDF加载失败，请稍后重试</div>}
                    options={pdfOptions}
                >
                    {numPages && (
                        <div style={{ height: numPages * pageHeight, position: 'relative' }}>
                            {Array.from({ length: numPages }, (_, index) => {
                                const pageNumber = index + 1
                                const isVisible = visiblePages.has(pageNumber)

                                return (
                                    <div
                                        key={pageNumber}
                                        ref={el => pageRefs.current[pageNumber] = el}
                                        className="pdf-page-wrapper"
                                        style={{
                                            position: 'absolute',
                                            top: index * pageHeight,
                                            left: 0,
                                            right: 0,
                                            height: pageHeight,
                                        }}
                                    >
                                        {isVisible ? (
                                            <>
                                                <Page
                                                    pageNumber={pageNumber}
                                                    scale={scale}
                                                    renderTextLayer={true}
                                                    renderAnnotationLayer={true}
                                                    loading={
                                                        <div className="pdf-page-loading">
                                                            <Spin size="small" />
                                                            <div>加载第 {pageNumber} 页...</div>
                                                        </div>
                                                    }
                                                />
                                                <div className="pdf-page-number">第 {pageNumber} 页</div>
                                            </>
                                        ) : (
                                            <div className="pdf-page-placeholder">
                                                <div>第 {pageNumber} 页</div>
                                            </div>
                                        )}
                                    </div>
                                )
                            })}
                        </div>
                    )}
                </Document>
            </div>
        </div>
    )
}

export default VirtualPDFViewer
