import { useEffect, useRef, useState } from 'react';
import * as pdfjsLib from 'pdfjs-dist';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?url';

import { getDaojiandanPdf as getDaojiandanPdfApi, submitDaojiandanSign, editDaojiandanPrintStatus } from '../../api';
import type { ExamClient } from '../../data/mockData';
import type { SignaturePadHandle } from '../ui';
import { Button, SignaturePad } from '../ui';

// Polyfill for Promise.withResolvers
if (typeof (Promise as any).withResolvers === 'undefined') {
  (Promise as any).withResolvers = function <T>() {
    let resolve!: (value: T | PromiseLike<T>) => void;
    let reject!: (reason?: any) => void;
    const promise = new Promise<T>((res, rej) => {
      resolve = res;
      reject = rej;
    });
    return { promise, resolve, reject };
  };
}

// 配置 PDF.js worker
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;

export const ExamPrintPanel = ({ client }: { client: ExamClient }) => {
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [pdfReady, setPdfReady] = useState(false);
  const [pdfBlobUrl, setPdfBlobUrl] = useState<string | null>(null);
  const [signatureSubmitted, setSignatureSubmitted] = useState(false);
  const [submitLoading, setSubmitLoading] = useState(false);
  const [submitMessage, setSubmitMessage] = useState<string | null>(null);
  const [showPreview, setShowPreview] = useState(false);
  const [fetchLoading, setFetchLoading] = useState(false);
  const [pdfData, setPdfData] = useState<ArrayBuffer | null>(null);
  const signaturePadRef = useRef<SignaturePadHandle | null>(null);
  const printRef = useRef<HTMLDivElement>(null);
  const canvasContainerRef = useRef<HTMLDivElement>(null);

  const handleSubmitSign = async () => {
    const examId = Number(client.id);
    if (!examId) {
      setSubmitMessage('无效的体检ID');
      return;
    }

    const dataUrl = signaturePadRef.current?.toDataURL('image/png');
    if (!dataUrl) {
      setSubmitMessage('请先完成签名');
      return;
    }

    setSubmitLoading(true);
    setSubmitMessage(null);
    try {
      // 将 base64 转换为 Blob
      const blob = await fetch(dataUrl).then(r => r.blob());

      // 提交签名生成导检单PDF
      const res = await submitDaojiandanSign({
        exam_id: examId,
        sign_file: blob,
      });

      if (res.Status === 200 && res.Data?.pdf_url) {
        setSubmitMessage('签名提交成功，正在加载导检单...');
        setSignatureSubmitted(true);
        const pdfUrlValue = res.Data.pdf_url;
        setPdfUrl(pdfUrlValue);
        // 更新导检单打印状态
        try {
          await editDaojiandanPrintStatus({ exam_id: examId });
        } catch (err) {
          console.error('更新导检单打印状态失败', err);
          // 不阻塞主流程，仅记录错误
        }
      } else {
        setSubmitMessage(res.Message || '签名提交失败');
      }
    } catch (err) {
      console.error('提交签名失败', err);
      setSubmitMessage('签名提交失败，请稍后重试');
    } finally {
      setSubmitLoading(false);
    }
  };

  // 组件加载时自动获取导检单（未签名版本也可以查看）
  useEffect(() => {
    const examId = Number(client.id);
    if (!examId) return;

    // 自动加载未签名的导检单用于查看
    const fetchPdf = async () => {
      setFetchLoading(true);
      setError(null);

      try {
        const res = await getDaojiandanPdfApi({ exam_id: examId });
        if (res.Status === 200 && res.Data?.pdf_url) {
          const pdfUrlValue = res.Data.pdf_url;
          console.log('获取到导检单PDF URL:', pdfUrlValue);
          setPdfUrl(pdfUrlValue);
          setShowPreview(true);
        } else {
          console.error('获取导检单失败，响应:', res);
          setError(res.Message || '获取导检单失败');
        }
      } catch (err) {
        console.error('获取导检单失败', err);
        setError('获取导检单失败，请稍后重试');
      } finally {
        setFetchLoading(false);
      }
    };

    fetchPdf();
  }, [client.id]);

  // 获取导检单PDF（优先使用localStorage，没有则调用接口）
  const handleFetchPdf = async () => {
    const examId = Number(client.id);
    if (!examId) {
      setError('无效的体检ID');
      return;
    }

    setFetchLoading(true);
    setError(null);

    try {
      const res = await getDaojiandanPdfApi({ exam_id: examId });
      if (res.Status === 200 && res.Data?.pdf_url) {
        const pdfUrlValue = res.Data.pdf_url;
        setPdfUrl(pdfUrlValue);
        // 获取到的导检单是未签名的，不保存到localStorage，只用于显示
        setShowPreview(true);
      } else {
        setError(res.Message || '获取导检单失败');
      }
    } catch (err) {
      console.error('获取导检单失败', err);
      setError('获取导检单失败，请稍后重试');
    } finally {
      setFetchLoading(false);
    }
  };

  // 第一步：加载 PDF 数据
  useEffect(() => {
    if (!pdfUrl) return;

    let objectUrl: string | null = null;
    setPdfReady(false);
    setLoading(true);
    setPdfData(null);

    fetch(pdfUrl)
      .then((resp) => {
        if (!resp.ok) throw new Error('获取PDF文件失败');
        return resp.blob();
      })
      .then((blob) => {
        objectUrl = URL.createObjectURL(blob);
        setPdfBlobUrl(objectUrl);
        return blob.arrayBuffer();
      })
      .then((arrayBuffer) => {
        setPdfData(arrayBuffer);
        setLoading(false);
      })
      .catch((err) => {
        console.error('PDF 拉取失败', err);
        setError('PDF 加载失败，请稍后重试');
        setLoading(false);
      });

    return () => {
      if (objectUrl) {
        URL.revokeObjectURL(objectUrl);
      }
    };
  }, [pdfUrl]);

  // 第二步：渲染 PDF
  useEffect(() => {
    if (!pdfData || !canvasContainerRef.current) return;

    console.log('开始渲染 PDF');
    setPdfReady(false);

    const renderAllPages = async () => {
      try {
        const pdf = await pdfjsLib.getDocument({ data: pdfData }).promise;
        console.log('PDF 加载成功，共 ' + pdf.numPages + ' 页');

        if (!canvasContainerRef.current) {
          console.log('canvasContainerRef 仍为 null');
          return;
        }

        // 清空容器
        canvasContainerRef.current.innerHTML = '';

        const scale = 1.2;

        for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
          const page = await pdf.getPage(pageNum);
          const viewport = page.getViewport({ scale });

          const canvas = document.createElement('canvas');
          const context = canvas.getContext('2d');

          if (!context) {
            console.log('无法获取 canvas context');
            continue;
          }

          canvas.height = viewport.height;
          canvas.width = viewport.width;
          canvas.style.display = 'block';
          canvas.style.marginBottom = '10px';
          canvas.className = 'mx-auto border rounded-lg shadow-sm';

          canvasContainerRef.current.appendChild(canvas);

          const renderContext = {
            canvasContext: context,
            viewport: viewport,
          } as any;

          await page.render(renderContext).promise;
          console.log('渲染完成第 ' + pageNum + ' 页');
        }

        setPdfReady(true);
        console.log('所有页面渲染完成');
      } catch (err) {
        console.error('PDF 渲染失败', err);
        setError('PDF 渲染失败，请稍后重试: ' + err);
      }
    };

    renderAllPages();
  }, [pdfData]);

  const handlePrint = () => {
    if (!pdfBlobUrl || !pdfReady || !canvasContainerRef.current) return;

    // 创建打印窗口
    const printWindow = window.open('', '_blank');
    if (!printWindow) return;

    // 获取所有的 canvas
    const canvases = canvasContainerRef.current.querySelectorAll('canvas');

    // 构建打印页面
    printWindow.document.write(`
      <!DOCTYPE html>
      <html>
        <head>
          <title>导检单打印</title>
          <style>
            @media print {
              body {
                margin: 0;
                padding: 0;
              }
              img {
                max-width: 100%;
                page-break-after: always;
                page-break-inside: avoid;
              }
              img:last-child {
                page-break-after: auto;
              }
            }
            body {
              margin: 0;
              padding: 0;
            }
            img {
              display: block;
              width: 100%;
              height: auto;
            }
          </style>
        </head>
        <body>
    `);

    // 将每个 canvas 转换为图片并添加到打印窗口
    canvases.forEach((canvas) => {
      const imgData = (canvas as HTMLCanvasElement).toDataURL('image/png');
      printWindow.document.write(`<img src="${imgData}" />`);
    });

    printWindow.document.write(`
        </body>
      </html>
    `);

    printWindow.document.close();

    // 等待图片加载完成后执行打印
    printWindow.onload = () => {
      printWindow.focus();
      setTimeout(() => {
        printWindow.print();
      }, 1000);
    };
  };

  return (
    <div className='flex justify-center'>
      <div className='w-full max-w-[95%] bg-white rounded-2xl border shadow-sm px-6 py-4 text-xs text-gray-800'>
        <div className='flex items-center justify-between border-b pb-3 mb-3'>
          <div>
            <div className='text-sm font-semibold'>圆和医疗体检中心 · 导检单预览</div>
            <div className='text-[11px] text-gray-500 mt-1'>
              {signatureSubmitted || showPreview
                ? '此为预览页面，实际打印效果以院内打印机为准。'
                : '请先完成签名，签名后将生成导检单PDF'}
            </div>
          </div>
          <div className='flex items-center gap-3'>
            <div className='text-right text-[11px] text-gray-500'>
              <div>体检号：{client.id}</div>
              <div>日期：{new Date().toLocaleDateString('zh-CN')}</div>
            </div>
            {!showPreview && !signatureSubmitted && (
              <Button
                className='px-4 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50 disabled:cursor-not-allowed'
                onClick={handleFetchPdf}
                disabled={fetchLoading}
              >
                {fetchLoading ? '加载中...' : '查看'}
              </Button>
            )}
            {showPreview && !signatureSubmitted && (
              <>
                <Button
                  className='px-4 py-1.5 text-xs bg-gray-600 hover:bg-gray-700 text-white'
                  onClick={() => {
                    setShowPreview(false);
                    setPdfUrl(null);
                    setPdfBlobUrl(null);
                    setPdfReady(false);
                    setError(null);
                  }}
                >
                  签名
                </Button>
                <Button
                  className='px-4 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50 disabled:cursor-not-allowed'
                  onClick={handlePrint}
                  disabled={loading || !pdfReady || !pdfUrl}
                >
                  打印
                </Button>
              </>
            )}
            {signatureSubmitted && (
              <Button
                className='px-4 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50 disabled:cursor-not-allowed'
                onClick={handlePrint}
                disabled={loading || !pdfReady || !pdfUrl}
              >
                打印
              </Button>
            )}
          </div>
        </div>

        {!signatureSubmitted && !showPreview ? (
          <div className='flex flex-col gap-4'>
            <div className='text-sm font-medium text-gray-900'>请在下方区域签名</div>
            <div className='ui7-signature-wrapper border rounded-xl overflow-hidden bg-gray-50'>
              <SignaturePad
                ref={signaturePadRef}
                className='ui7-signature-canvas w-full h-72 bg-white touch-none'
              />
              <div className='flex items-center justify-between px-3 py-2 bg-gray-50 border-t'>
                <div className='text-xs text-gray-500'>请在上方区域签名</div>
                <Button
                  className='ui7-clear-button py-1 px-3'
                  onClick={() => signaturePadRef.current?.clear()}
                  disabled={submitLoading}
                >
                  清除
                </Button>
              </div>
            </div>
            {submitMessage && (
              <div
                className={`text-sm text-center ${submitMessage.includes('成功') ? 'text-green-600' : 'text-amber-600'
                  }`}
              >
                {submitMessage}
              </div>
            )}
            <div className='flex items-center justify-end gap-3'>
              <Button
                className='py-2 px-6 bg-blue-600 text-white hover:bg-blue-700'
                onClick={handleSubmitSign}
                disabled={submitLoading}
              >
                {submitLoading ? '提交中...' : '提交签名'}
              </Button>
            </div>
          </div>
        ) : fetchLoading ? (
          <div className='flex items-center justify-center py-12 text-gray-500'>
            <div>正在加载导检单...</div>
          </div>
        ) : error ? (
          <div className='flex flex-col items-center justify-center py-12 text-gray-500'>
            <div className='mb-2'>{error}</div>
            {signatureSubmitted ? (
              <Button
                className='px-4 py-1.5 text-xs'
                onClick={() => {
                  setError(null);
                  setPdfUrl(null);
                  setSignatureSubmitted(false);
                  setShowPreview(false);
                  signaturePadRef.current?.clear();
                }}
              >
                重新签名
              </Button>
            ) : (
              <Button
                className='px-4 py-1.5 text-xs'
                onClick={() => {
                  setError(null);
                  setShowPreview(false);
                }}
              >
                关闭
              </Button>
            )}
          </div>
        ) : loading ? (
          <div className='flex items-center justify-center py-12 text-gray-500'>
            <div>正在加载PDF...</div>
          </div>
        ) : pdfUrl ? (
          <div className='w-full'>
            <div ref={printRef} className='print-content'>
              <div className='flex justify-center border rounded-lg p-4 bg-gray-50 overflow-auto max-h-[600px]'>
                <div ref={canvasContainerRef} className='w-full' />
              </div>
            </div>
          </div>
        ) : showPreview ? (
          <div className='flex items-center justify-center py-12 text-gray-500'>
            <div>正在准备导检单...</div>
          </div>
        ) : null}
      </div>
    </div>
  );
};


