import React, { useState, useEffect, useRef } from 'react';
// 使用 pdf.js 在左侧容器中渲染 PDF 页面，支持自由滑动与页码定位
import * as pdfjsLib from 'pdfjs-dist';

// 线上 Nginx 默认不识别 .mjs 的 MIME（会返回 application/octet-stream），
// 这里统一使用 .js 扩展以确保 Content-Type 为 application/javascript
const PDFJS_WORKER_MJS = '/pdfjs-dist/pdf.worker.min.js';
// @ts-ignore
pdfjsLib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER_MJS;
// @ts-ignore
pdfjsLib.GlobalWorkerOptions.disableWorker = true;

import { useSearchParams } from "react-router-dom";
import {
  Box,
  Typography,
  TextField,
  InputAdornment,
  Paper,
  Alert,
  Button,
  Card,
  CardContent
} from "@mui/material";
import { Search as SearchIcon, Download as DownloadIcon } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import { useChunkList } from '@/hooks/chunk-hooks';
import ChunkListResult from './components/ChunkListResult';
import knowledgeService from '@/services/knowledge_service';
import type { IKnowledge, IKnowledgeFile, IChunk } from '@/interfaces/database/knowledge';
import KnowledgeBreadcrumbs from '@/pages/knowledge/components/KnowledgeBreadcrumbs';
import logger from '@/utils/logger';

function ChunkParsedResult() {
  const { t } = useTranslation();
  const [searchParams] = useSearchParams();
  const kb_id = searchParams.get('kb_id');
  const doc_id = searchParams.get('doc_id');

  const [knowledgeBase, setKnowledgeBase] = useState<IKnowledge | null>(null);
  const [document, setDocument] = useState<IKnowledgeFile | null>(null);
  const [searchKeyword, setSearchKeyword] = useState('');
  const [documentFile, setDocumentFile] = useState<Blob | null>(null);
  const [fileUrl, setFileUrl] = useState<string>('');
  const [fileLoading, setFileLoading] = useState(false);
  const [previewOverrideUrl, setPreviewOverrideUrl] = useState<string>('');
  const [focusPage, setFocusPage] = useState<number | null>(null);
  const abortControllerRef = useRef<AbortController | null>(null);
  const pdfContainerRef = useRef<HTMLDivElement | null>(null);
  const [pdfRendered, setPdfRendered] = useState<boolean>(false);

  // 使用chunk列表hook
  const {
    chunks,
    total,
    loading,
    error,
    currentPage,
    pageSize,
    setCurrentPage,
    setKeywords,
    refresh
  } = useChunkList(doc_id || '', {
    page: 1,
    size: 10,
    keywords: searchKeyword
  });

  // 获取知识库和文档信息
  useEffect(() => {
    const fetchData = async () => {
      if (!kb_id || !doc_id) return;

      try {
        // 获取知识库信息
        const kbResponse = await knowledgeService.getKnowledgeDetail({ kb_id });
        if (kbResponse.data.code === 0) {
          console.log('KnowledgeBase:', kbResponse.data);
          setKnowledgeBase(kbResponse.data.data);
        }

        // 获取文档信息
        const docResponse = await knowledgeService.getDocumentInfos({ doc_ids: [doc_id] });
        if (docResponse.data.code === 0) {
          const docArr: IKnowledgeFile[] = docResponse.data.data;
          if (docArr.length > 0) {
            setDocument(docArr[0]);
          }
        }

        // 自动加载文档文件用于预览
        await loadDocumentFile();
      } catch (error) {
        console.error('Failed to fetch data:', error);
      }
    };

    fetchData();
  }, [kb_id, doc_id]);

  // 处理搜索
  const handleSearch = (keyword: string) => {
    setSearchKeyword(keyword);
    setKeywords(keyword);
    setCurrentPage(1);
  };

  // 异步加载文档文件
  const loadDocumentFile = async () => {
    if (!doc_id || fileLoading) return;

    try {
      // 取消之前的请求
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
      setFileLoading(true);
      // 创建新的AbortController
      abortControllerRef.current = new AbortController();

      const fileResponse: { data: Blob } = await knowledgeService.getDocumentFile({
        doc_id
      }, {
        signal: abortControllerRef.current.signal
      });
      setFileLoading(false);
      if (fileResponse.data instanceof Blob) {
        setDocumentFile(fileResponse.data);
        const url = URL.createObjectURL(fileResponse.data);
        setFileUrl(url);
      }
    } catch (err: any) {
      if (err?.name !== 'AbortError' && err?.name !== 'CanceledError') {
        logger.error('获取文档文件失败:', err);
        setFileLoading(false);
      } else {
        logger.info('请求被取消:', err);
      }
    }
  };

  // 清理fileUrl
  useEffect(() => {
    return () => {
      if (fileUrl) {
        URL.revokeObjectURL(fileUrl);
      }
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [fileUrl]);

  // 使用 pdf.js 渲染 PDF 到左侧容器，替代 iframe，保证滚动与定位可用
  useEffect(() => {
    const renderPdf = async () => {
      if (!documentFile || documentFile.type !== 'application/pdf') {
        // 非 PDF 或无文件，不渲染 PDF
        setPdfRendered(false);
        return;
      }
      try {
        const arrayBuffer = await documentFile.arrayBuffer();
        const container = pdfContainerRef.current;
        if (!container) return;

        const renderPages = async (pdfDoc: any) => {
          container.innerHTML = '';
          // 根据容器宽度自适应缩放
          const containerRect = container.getBoundingClientRect();
          const containerWidth = Math.max(1, Math.floor(containerRect.width || container.clientWidth || 800));

          for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            const page = await pdfDoc.getPage(pageNum);
            const viewport = page.getViewport({ scale: 1 });
            const scale = containerWidth / viewport.width;
            const scaledViewport = page.getViewport({ scale });
            const dpr = Math.max(1, window.devicePixelRatio || 1);

            const canvas = window.document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.style.display = 'block';
            canvas.style.marginBottom = '12px';
            canvas.style.width = `${Math.floor(scaledViewport.width)}px`;
            canvas.style.height = `${Math.floor(scaledViewport.height)}px`;
            canvas.width = Math.floor(scaledViewport.width * dpr);
            canvas.height = Math.floor(scaledViewport.height * dpr);

            if (ctx) {
              // 提升清晰度：将绘制与 CSS 尺寸解耦并使用设备像素比
              // @ts-ignore
              ctx.imageSmoothingEnabled = true;
              // @ts-ignore
              ctx.imageSmoothingQuality = 'high';
            }
            // @ts-ignore
            await page.render({
              canvasContext: ctx as CanvasRenderingContext2D,
              viewport: scaledViewport,
              transform: dpr !== 1 ? [dpr, 0, 0, dpr, 0, 0] : undefined,
            }).promise;

            const pageWrapper = window.document.createElement('div');
            pageWrapper.setAttribute('data-page-index', String(pageNum));
            pageWrapper.appendChild(canvas);
            container.appendChild(pageWrapper);
          }
        };

        // 尝试使用 Worker（优先模块，其次经典）
        try {
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          const task = pdfjsLib.getDocument({ data: arrayBuffer });
          const pdfDoc = await task.promise;
          await renderPages(pdfDoc);
          setPdfRendered(true);
        } catch (err1) {
          console.error('第一次渲染失败，尝试主线程渲染:', err1);
          // 失败则回退主线程
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          // @ts-ignore
          const fallbackTask = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker: true });
          const pdfDoc2 = await fallbackTask.promise;
          await renderPages(pdfDoc2);
          setPdfRendered(true);
        }
      } catch (err) {
        console.error('渲染 PDF 过程中发生错误: ', err);
        setPdfRendered(false);
      }
    };

    renderPdf();

    // 清理渲染内容，避免内存泄露
    return () => {
      const container = pdfContainerRef.current;
      if (container) container.innerHTML = '';
    };
    // 仅在文件或其类型变化时重新渲染
  }, [documentFile]);

  // 当 focusPage 变化时，滚动到对应页（仅对 PDF 有效）
  useEffect(() => {
    if (documentFile?.type !== 'application/pdf' || !pdfRendered || !focusPage) return;
    const container = pdfContainerRef.current;
    if (!container) return;
    const children = Array.from(container.children);
    const target = children.find((el) => (el as HTMLElement).dataset?.pageIndex === String(focusPage));
    if (target) {
      (target as HTMLElement).scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }, [focusPage, pdfRendered, documentFile]);

  // 下载文件
  const handleDownload = () => {
    if (fileUrl && window.document) {
      const link = window.document.createElement('a');
      link.href = fileUrl;
      link.download = document?.name || 'document';
      window.document.body.appendChild(link);
      link.click();
      window.document.body.removeChild(link);
    }
  };

  // 处理定位：点击某个chunk后联动预览
  const handleLocate = (chunk: IChunk) => {
    // 使用 positions 的第一个元素的第一个值作为页码（若存在）
    const page = Array.isArray(chunk.positions) && chunk.positions.length > 0 && Array.isArray(chunk.positions[0])
      ? Number(chunk.positions[0][0])
      : null;

    // 保持左侧预览为文档视图，定位仅改变 PDF 页码，不替换为切片图片
    if (documentFile?.type === 'application/pdf') {
      setFocusPage(page && !Number.isNaN(page) ? page : null);
      setPreviewOverrideUrl('');
      return;
    }

    // 非 PDF 文档暂不处理页码定位，保持可滚动预览
    setPreviewOverrideUrl('');
    setFocusPage(null);
  };

  // 渲染左侧预览
  const renderPreview = () => {
    // 如果有覆盖的图片URL，直接显示图片
    if (previewOverrideUrl) {
      return (
        <Box
          component="img"
          src={previewOverrideUrl}
          alt={document?.name || t('chunkPage.documentPreview')}
          sx={{ width: '100%', height: '100%', objectFit: 'contain', borderRadius: 1 }}
        />
      );
    }
    if (!documentFile || !fileUrl) return null;

    const fileType = documentFile.type;
    if (fileType.startsWith('image/')) {
      return (
        <Box
          component="img"
          src={fileUrl}
          alt={document?.name || t('chunkPage.documentPreview')}
          sx={{ width: '100%', height: '100%', objectFit: 'contain', borderRadius: 1 }}
        />
      );
    } else if (fileType === 'application/pdf') {
      // 使用 pdf.js 渲染的容器，支持滚动与页码定位
      return (
        <Box
          ref={pdfContainerRef}
          sx={{ width: '100%', height: '100%', overflow: 'auto', borderRadius: 1 }}
        />
      );
    } else if (fileType.startsWith('text/')) {
      return (
        <Box
          component="iframe"
          src={fileUrl}
          sx={{ width: '100%', height: '100%', border: '1px solid', borderColor: 'grey.300', borderRadius: 1 }}
        />
      );
    } else {
      return (
        <Alert severity="info" sx={{ mt: 2 }}>
          {t('chunkPage.fileTypeNotSupportedPreview')}
        </Alert>
      );
    }
  };

  if (!kb_id || !doc_id) {
    return (
      <Box sx={{ p: 3 }}>
        <Alert severity="error">
          {t('chunkPage.missingParams')}
        </Alert>
      </Box>
    );
  }

  return (
    <Box sx={{ p: 3 }}>
      {/* 面包屑导航 */}
      <KnowledgeBreadcrumbs
        kbItems={[
          {
            label: t('chunkPage.knowledgeBase'),
            path: '/knowledge'
          },
          {
            label: knowledgeBase?.name || t('chunkPage.knowledgeBaseDetail'),
            path: `/knowledge/${kb_id}`
          }
        ]}
        extraItems={[
          {
            label: document?.name || t('chunkPage.documentDetail')
          },
        ]}
      />
      {/* 顶部信息与下载 */}
      <Paper sx={{ p: 3, mb: 2 }}>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <Box>
            <Typography variant="h4" gutterBottom>
              {document?.name || t('chunkPage.documentDetail')}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              {t('chunkPage.documentChunkResult')}
            </Typography>
          </Box>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
            <Card>
              <CardContent sx={{ textAlign: 'center' }}>
                <Typography variant="h4" color="primary">
                  {total}
                </Typography>
                <Typography variant="body2" color="text.secondary">
                  {t('chunkPage.totalChunkCount')}
                </Typography>
              </CardContent>
            </Card>
            {fileUrl && (
              <Button variant="contained" startIcon={<DownloadIcon />} onClick={handleDownload}>
                {t('chunkPage.downloadFile')}
              </Button>
            )}
          </Box>
        </Box>
      </Paper>

      {/* 左右布局：左预览，右切片结果 */}
      <Box sx={{ display: 'flex', gap: 2 }}>
        {/* 左侧文档预览 */}
        <Box sx={{ flex: 1 }}>
          <Paper sx={{ p: 2, height: '80vh' }}>
            {/* 文件加载状态 */}
            {fileLoading && (
              <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '200px' }}>
                <Alert severity="info">{t('chunkPage.loadingFile')}</Alert>
              </Box>
            )}

            {renderPreview()}
          </Paper>
        </Box>

        {/* 右侧切片结果与搜索 */}
        <Box sx={{ flex: 1 }}>
          <Paper sx={{ p: 2, height: '80vh', display: 'flex', flexDirection: 'column' }}>
            <TextField
              fullWidth
              placeholder={t('chunkPage.searchChunkPlaceholder')}
              value={searchKeyword}
              onChange={(e) => handleSearch(e.target.value)}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <SearchIcon />
                  </InputAdornment>
                ),
              }}
            />
            <Box sx={{ flex: 1, overflow: 'auto', pt: 2 }}>
              <ChunkListResult
                doc_id={doc_id}
                chunks={chunks}
                total={total}
                loading={loading}
                error={error}
                page={currentPage}
                pageSize={pageSize}
                onPageChange={setCurrentPage}
                onRefresh={refresh}
                docName={document?.name}
                onLocate={handleLocate}
              />
            </Box>
          </Paper>
        </Box>
      </Box>
    </Box>
  );
}

export default ChunkParsedResult;