/**
 * 文件预览组件
 * 显示文档内容和评查点高亮
 */
import { useState, useEffect, useRef, ChangeEvent } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';

// 设置worker路径为public目录下的worker文件
// 使用已经下载的兼容版本 (pdfjs-dist v2.12.313)
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';

// 导入统一的ReviewPoint类型
import { type ReviewPoint } from './';
import { toastService } from '../ui/Toast';

/**
 * 自定义样式
 * 这些样式解决了PDF页面在放大时互相重叠的问题
 */
const styles = {
  pdfContainer: {
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    width: '100%',
    position: 'relative' as const,
  },
  pageContainer: {
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    width: '100%',
    position: 'relative' as const,
  }
};

// 定义文档内容类型
interface FileContent {
  title: string;
  contractNumber: string;
  path: string;
  ocrResult?: {
    __meta?: {
      page_offset?: number;
    };
  }; // 添加ocrResult属性
  parties: {
    partyA: {
      name: string;
      address: string;
      representative: string;
      phone: string;
    };
    partyB: {
      name: string;
      address: string;
      representative: string;
      phone: string;
    };
  };
  sections: {
    title: string;
    content: string;
  }[];
}

interface FilePreviewProps {
  fileContent: FileContent;
  reviewPoints?: ReviewPoint[]; // 设为可选
  activeReviewPointResultId: string | null;
  targetPage?: number; // 新增目标页码参数
  isStructuredView?: boolean; // 是否显示结构化视图
}

// export function FilePreview({ fileContent, reviewPoints, activeReviewPointResultId, targetPage }: FilePreviewProps) {
export function FilePreview({ fileContent, activeReviewPointResultId, targetPage, isStructuredView = false }: FilePreviewProps) {
  const [zoomLevel, setZoomLevel] = useState(100);
  // const [highlightsVisible, setHighlightsVisible] = useState(true);
  const contentRef = useRef<HTMLDivElement>(null);
  const [numPages, setNumPages] = useState<number | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [pageInputValue, setPageInputValue] = useState<string>('');
  
  // 拖拽状态管理
  const [dragMode, setDragMode] = useState(false); // 是否处于拖拽模式
  const [isDragging, setIsDragging] = useState(false);
  const [dragCursor, setDragCursor] = useState('default');
  const lastMousePosRef = useRef({ x: 0, y: 0 });
  
  // 放大文档
  const handleZoomIn = () => {
    if (zoomLevel < 200) {
      setZoomLevel(prevZoom => prevZoom + 10);
    }
  };
  
  // 缩小文档
  const handleZoomOut = () => {
    if (zoomLevel > 50) {
      setZoomLevel(prevZoom => prevZoom - 10);
    }
  };
  
  // 切换拖拽模式
  const toggleDragMode = () => {
    setDragMode(prev => !prev);
    setDragCursor(prev => prev === 'default' ? 'grab' : 'default');
    setIsDragging(false);
  };
  
  // 处理拖拽开始
  const handleMouseDown = (e: React.MouseEvent<HTMLButtonElement>) => {
    if (!dragMode || e.button !== 0) return; // 只在拖拽模式下响应左键点击
    
    // 防止选中文本
    e.preventDefault();
    
    // 设置拖拽状态
    setIsDragging(true);
    setDragCursor('grabbing');
    
    // 记录鼠标初始位置
    lastMousePosRef.current = {
      x: e.clientX,
      y: e.clientY
    };
  };
  
  // 处理拖拽过程
  const handleMouseMove = (e: React.MouseEvent<HTMLButtonElement>) => {
    if (!dragMode || !isDragging || !contentRef.current) return;
    
    // 计算鼠标移动距离
    const dx = e.clientX - lastMousePosRef.current.x;
    const dy = e.clientY - lastMousePosRef.current.y;
    
    // 更新容器滚动位置
    contentRef.current.scrollLeft -= dx;
    contentRef.current.scrollTop -= dy;
    
    // 更新鼠标位置记录
    lastMousePosRef.current = {
      x: e.clientX,
      y: e.clientY
    };
  };
  
  // 处理拖拽结束
  const handleMouseUp = () => {
    if (!dragMode) return;
    
    setIsDragging(false);
    setDragCursor('grab');
  };
  
  // 监听鼠标离开窗口事件
  useEffect(() => {
    const handleMouseLeave = () => {
      if (dragMode && isDragging) {
        setIsDragging(false);
        setDragCursor('grab');
      }
    };
    
    document.addEventListener('mouseleave', handleMouseLeave);
    document.addEventListener('mouseup', handleMouseUp as EventListener);
    
    return () => {
      document.removeEventListener('mouseleave', handleMouseLeave);
      document.removeEventListener('mouseup', handleMouseUp as EventListener);
    };
  }, [isDragging, dragMode]);
  
  // 处理页面跳转
  const prevTargetPageRef = useRef<number | undefined>(undefined);
  useEffect(() => {
    // 调试信息：记录组件状态
    // console.log(`FilePreview更新 - isStructuredView:${isStructuredView}, targetPage:${targetPage}, activeReviewPointResultId:${activeReviewPointResultId}, numPages:${numPages}`);
    
    // 如果有目标页码，并且与上次相同，提示用户
    if(targetPage && numPages && targetPage <= numPages && targetPage === prevTargetPageRef.current){
      toastService.success(`已跳转至目标页码`);
    }
    // 如果有目标页码，并且与上次不同或activeReviewPointId变化了，则执行跳转
    if (targetPage && numPages && targetPage <= numPages && (targetPage !== prevTargetPageRef.current || activeReviewPointResultId)) {
      prevTargetPageRef.current = targetPage;
      let newTargetPage = targetPage;
      
      // 页码偏移量
      try {
        // 安全地访问ocrResult
        if (fileContent.ocrResult && fileContent.ocrResult.__meta && fileContent.ocrResult.__meta.page_offset) {
          // 可以根据需要使用page_offset调整目标页面
           newTargetPage = targetPage + fileContent.ocrResult.__meta.page_offset;
        }
      } catch (error) {
        console.error("访问ocrResult时出错:", error);
        toastService.error("访问ocrResult时出错:" + (error instanceof Error ? error.message : '未知错误'));
      }
      
      const pageElementId = `page-${newTargetPage}${isStructuredView ? '-structured' : ''}`;
      // console.log(`尝试跳转到元素ID: ${pageElementId}`);
      
      const pageElement = document.getElementById(pageElementId);
      if (pageElement) {
        console.log(`跳转到第${newTargetPage}页，对应评查点结果ID: ${activeReviewPointResultId}`);
        pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
      } else {
        console.warn(`未找到页面元素: ${pageElementId}`);
      }
    }
  }, [targetPage, numPages, fileContent, activeReviewPointResultId, isStructuredView]);
  
  // 获取评查点对应的样式类
  // const getHighlightClass = (status: string) => {
  //   switch (status) {
  //     case 'warning':
  //       return 'warning';
  //     case 'error':
  //       return 'error';
  //     case 'success':
  //       return 'success';
  //     default:
  //       return 'warning';
  //   }
  // };
  
  // 处理页码输入变化
  const handlePageInputChange = (e: ChangeEvent<HTMLInputElement>) => {
    // 只允许输入数字
    const value = e.target.value.replace(/\D/g, '');
    setPageInputValue(value);
  };
  
  // 处理页码跳转
  const handlePageJump = () => {
    if (!pageInputValue || !numPages) return;
    
    const targetPageNum = parseInt(pageInputValue, 10);
    
    // 验证页码是否在有效范围内
    if (targetPageNum > 0 && targetPageNum <= numPages) {
      // 找到目标页面元素并滚动到该位置
      const pageElement = document.getElementById(`page-${targetPageNum}`);
      if (pageElement) {
        pageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    } else {
      // 页码超出范围，显示错误信息或重置输入
      toastService.warning(`请输入有效页码 (1-${numPages})`);
      setPageInputValue('');
    }
  };

  // 处理回车键跳转
  const handlePageInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handlePageJump();
    }
  };
  
  // PDF文档加载成功回调函数
  function onDocumentLoadSuccess({ numPages }: { numPages: number }) {
    setNumPages(numPages);
    console.log("PDF加载成功，页数:", numPages);
  }
  
  // 计算页面在缩放后的实际间距
  const calculatePageMargin = (zoomFactor: number) => {
    // 基础间距为30px，随着缩放倍数线性增加
    const baseMargin = 30; 
    // 页面缩放后，需要额外添加的间距 = (缩放倍数 - 1) * 页面高度
    const additionalMargin = Math.max(0, (zoomFactor - 1) * 800); // 800是估计的页面高度
    return baseMargin + additionalMargin;
  };

  // 滚动到顶部
  const handleScrollToTop = () => {
    if (contentRef.current) {
      contentRef.current.scrollTo({ top: 0, behavior: 'smooth' });
    }
  };
  
  /**
   * 渲染PDF文档的所有页面
   * 
   * 功能描述:
   * 1. 生成PDF所有页面的渲染数组，每个页面包含页码标识和实际页面内容
   * 2. 处理页面缩放，通过CSS transform实现页面大小调整
   * 3. 在每个页面上标记对应的评查点高亮区域
   * 4. 处理评查点的激活状态，显示特殊的高亮效果
   * 
   * @returns {JSX.Element[] | null} 返回所有页面组件的数组，如果没有页数信息则返回null
   */
  const renderAllPages = () => {
    // 如果还没有获取到PDF总页数，返回null
    if (!numPages) return null;
    
    // 用于存储所有页面组件的数组
    const pages = [];
    
    // 遍历每一页，生成对应的页面组件
    for (let i = 1; i <= numPages; i++) {
      // 计算当前缩放级别下的页面容器样式
      const zoomFactor = zoomLevel / 100;
      const pageContainerStyle = {
        ...styles.pageContainer,
        marginBottom: `${calculatePageMargin(zoomFactor)}px`, // 动态计算页面间距
      };
      
      // 为结构化视图和普通视图创建不同的ID
      const pageId = isStructuredView ? `page-${i}-structured` : `page-${i}`;
      
      // 为每一页创建组件
      pages.push(
        <div key={i} id={pageId} style={pageContainerStyle}>
          {/* 页码标识，显示在页面上方 */}
          <div className="text-center text-gray-500 text-sm mb-2">第 {i} 页</div>
          
          {/* 页面容器，应用缩放变换，设置相对定位用于放置评查点高亮 */}
          <div 
            className="page-wrapper"
            style={{ 
              transform: `scale(${zoomFactor})`, // 根据zoomLevel应用缩放
              transformOrigin: 'top center',     // 缩放原点设置为顶部中心
              position: 'relative',              // 相对定位，作为评查点高亮的定位参考
              display: 'inline-block',           // 内联块级元素，宽度由内容决定
              margin: '0 auto',                  // 水平居中
            }}
          >
            {/* 渲染PDF页面组件 */}
            <Page
              pageNumber={i}                               // 当前页码
              renderTextLayer={true}                       // 启用文本层，使文本可选择
              renderAnnotationLayer={true}                 // 启用注释层，显示PDF内置注释
              className="border border-gray-300 shadow-md" // 添加边框和阴影样式
            />
            
            {/* 渲染评查点高亮区域 */}
            {/* {highlightsVisible && pageReviewPoints.map(point => {
              // 判断当前评查点是否为激活状态（被选中）
              const isActive = point.id === activeReviewPointId;
              
              return (
                // 评查点高亮区域
                <div 
                  key={point.id}
                  // 添加多个类名：基础高亮区域、PDF专用高亮、状态样式类、激活状态类
                  className={`highlight-area pdf-highlight ${getHighlightClass(point.status)} ${isActive ? 'highlight-focus' : ''}`}
                  // 设置唯一标识，用于滚动定位和DOM查询
                  data-review-id={point.id}
                  // 设置高亮区域的样式
                  style={{
                    position: 'absolute',                  // 绝对定位，相对于页面容器
                    zIndex: isActive ? 20 : 10,            // 激活状态时提高层级，确保在最上层显示
                    boxShadow: isActive ? '0 0 0 2px yellow, 0 0 10px rgba(0,0,0,0.3)' : '', // 激活时添加特殊阴影效果
                    // 根据评查点的位置信息计算高亮区域位置，实际项目中需根据真实位置坐标计算
                    top: `${point.position?.index ? point.position.index * 20 : 20}px`,
                    left: '50px',
                    width: '300px',
                    height: '30px',
                  }}
                />
              );
            })} */}
          </div>
        </div>
      );
    }
    
    // 返回所有页面组件数组
    return pages;
  };
  
  // 渲染文档内容
  const renderDocumentContent = () => {
    // 如果路径无效，显示错误信息
    if (!fileContent.path) {
      return (
        <div className="text-red-500 p-4">
          <p>无法加载文件：路径无效</p>
        </div>
      );
    }

    // 获取文件扩展名
    const fileExtension = fileContent.path.split('.').pop()?.toLowerCase();
    
    // PDF内容渲染
    const renderPdfContent = () => (
      <div 
        style={{
          ...styles.pdfContainer,
          // 当缩放大于100%时设置最小宽度，确保出现横向滚动条
          minWidth: zoomLevel > 100 ? `${zoomLevel}%` : '100%',
          overflow: 'visible'
        }}
      >
        <Document
          file={'http://nas.7bm.co:9000/docauditai/'+fileContent.path}
          onLoadSuccess={onDocumentLoadSuccess}
          onLoadError={(error) => {
            console.error("PDF加载错误:", error);
            setLoadError("PDF文档加载失败：" + (error.message || "未知错误"));
          }}
          className="w-full"
          error={<div className="text-red-500">PDF文档加载失败，请检查链接或网络连接。</div>}
          noData={<div>无数据</div>}
          loading={<div className="text-center py-10">PDF加载中...</div>}
        >
          {renderAllPages()}
        </Document>
      </div>
    );

    // 结构化数据渲染
    const renderStructuredData = () => (
      <div className="structured-view p-4 text-left mt-4 border-t border-gray-200">
        <div className="text-xs font-medium mb-2">结构化数据：</div>
        {fileContent.ocrResult ? (
          <div className="overflow-auto max-h-[300px]">
            <pre className="text-xs whitespace-pre-wrap bg-gray-50 p-3 rounded">
              {JSON.stringify(fileContent.ocrResult, null, 2)}
            </pre>
          </div>
        ) : (
          <div className="text-gray-500 p-4 text-center">
            <p>无结构化数据可显示</p>
          </div>
        )}
      </div>
    );
    
    // 根据文件类型选择不同的渲染方式
    if (fileExtension === 'pdf') {
      // 结构化视图模式：显示PDF和结构化数据
      if (isStructuredView) {
        return (
          <div>
            {renderPdfContent()}
            {renderStructuredData()}
          </div>
        );
      }
      // 普通模式：仅显示PDF
      return renderPdfContent();
    } else {
      // 非PDF文件显示不支持消息
      return (
        <div className="text-gray-500 p-4">
          <p>暂不支持预览此类型的文件：{fileExtension}</p>
        </div>
      );
    }
  };
  
  return (
    <div className="file-preview">
      <div className="file-preview-header py-2 px-4 text-xs sm:text-xs md:text-sm max-w-full text-overflow-ellipsis">
        <div className="flex items-center">
          <i className={`${isStructuredView ? 'ri-file-list-line' : 'ri-file-text-line'} text-primary mr-2`}></i>
          <span className="font-medium text-primary">{isStructuredView ? '附件预览' : '文件预览'}</span>
        </div>
        <div className="file-preview-actions flex items-center">
          <button 
            className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs max-h-6 leading-5"
            onClick={handleScrollToTop}
            title="返回顶部"
          >
            <i className="ri-arrow-up-double-line"></i>
            <span className="ml-1 sm:inline md:inline lg:hidden xl:inline">返回顶部</span>
          </button>
          <button 
            className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs max-h-6 leading-5"
            onClick={handleZoomIn}
            title="放大"
          >
            <i className="ri-zoom-in-line"></i>
          </button>
          <button 
            className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs max-h-6 leading-5"
            onClick={handleZoomOut}
            title="缩小"
          >
            <i className="ri-zoom-out-line"></i>
          </button>
          {/* 页码跳转控件 */}
          <div className="inline-flex items-center ml-2">
            <input 
              type="text" 
              className="ant-input ant-input-sm py-0 px-1 text-xs max-h-6 leading-5 max-w-[2.5rem] text-center 
              focus:outline-none focus:ring-1 focus:ring-green-900"
              placeholder="页码"
              value={pageInputValue}
              onChange={handlePageInputChange}
              onKeyDown={handlePageInputKeyDown}
            />
            <button 
              className="ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs max-h-6 leading-5 ml-1"
              onClick={handlePageJump}
              disabled={!numPages}
              title="跳转到页面"
            >
              <i className="ri-arrow-right-line"></i>
            </button>
            {numPages && <span className="ml-1 text-xs text-gray-500 sm:inline md:inline lg:hidden xl:inline">/ {numPages}</span>}
          </div>
          <span className="ml-2 text-xs text-gray-500 inline-block sm:inline md:inline lg:hidden xl:inline">{"比例："+zoomLevel+"%"}</span>
          <button
            className={`ant-btn ant-btn-sm ant-btn-default py-0 px-1 text-xs max-h-6 leading-5 ml-2 ${dragMode ? 'active bg-green-300' : ''}`}
            title="切换拖拽模式"
            aria-pressed={dragMode}
            onClick={toggleDragMode}
          >
            <i className="ri-drag-move-line"></i>
            <span className="ml-1 sm:inline md:inline lg:hidden xl:inline">拖拽模式{dragMode ? '(已激活)' : ''}</span>
          </button>
        </div>
      </div>
      <div 
        className="file-preview-content"
        ref={contentRef}
        style={{ 
          maxHeight: 'calc(100vh - 150px)',
          overflowY: 'auto',
          overflowX: 'auto',
          cursor: dragCursor,
          userSelect: dragMode ? 'none' : 'auto', // 拖拽模式下防止文本被选中
        }}
      >
        <button
          className="pdf-interactive-container"
          aria-label="PDF文档查看区域"
          onMouseDown={handleMouseDown}
          onMouseMove={handleMouseMove}
          onMouseUp={handleMouseUp}
          onKeyDown={(e) => {
            // 添加键盘导航支持
            const scrollAmount = 50;
            if (e.key === 'ArrowUp') {
              if (contentRef.current) contentRef.current.scrollTop -= scrollAmount;
              e.preventDefault();
            } else if (e.key === 'ArrowDown') {
              if (contentRef.current) contentRef.current.scrollTop += scrollAmount;
              e.preventDefault();
            } else if (e.key === 'ArrowLeft') {
              if (contentRef.current) contentRef.current.scrollLeft -= scrollAmount;
              e.preventDefault();
            } else if (e.key === 'ArrowRight') {
              if (contentRef.current) contentRef.current.scrollLeft += scrollAmount;
              e.preventDefault();
            }
          }}
          style={{
            position: 'relative',
            height: '100%',
            width: '100%',
            display: 'block',
            border: 'none',
            background: 'transparent',
            textAlign: 'center',
            padding: 0
          }}
        >
          {loadError ? (
            <div className="text-red-500 p-4">
              <p>{loadError}</p>
            </div>
          ) : (
            renderDocumentContent()
          )}
        </button>
      </div>
    </div>
  );
} 