import React, { useState, useEffect, useRef, useCallback } from "react";
import { Document, Page } from "react-pdf";
import "./UI7.css";
import "../../assets/css/basic.css";
import { useNavigate } from "react-router-dom";
import BackButton from "../../components/BackButton";
import ConfirmButton from "../../components/ConfirmButton";
import DecorLine from "../../components/DecorLine";
import WaitButton from "../../components/WaitButton";

import { getTongyishuPdf, submitDaojiandanSign } from "../../api/hisApi";

// 独立的 PDF 渲染组件，使用 React.memo 避免不必要的重新渲染
const PdfRenderer = React.memo<{
  pdfFiles: Uint8Array[];
  loading: boolean;
  error: string;
  pageCounts: Record<number, number>;
  onPageCountUpdate: (index: number, numPages: number) => void;
  loadMessage: string;
}>(({ pdfFiles, loading, error, pageCounts, onPageCountUpdate, loadMessage }) => {
  return (
    <>
      {loading && (
        <div style={{ padding: "20px", textAlign: "center", fontSize: "32px" }}>
          <span style={{ fontSize: "32px" }}>{loadMessage}</span>
        </div>
      )}
      {error && (
        <div style={{ padding: "20px", color: "red", textAlign: "center" }}>
          {error}
        </div>
      )}
      {!loading &&
        !error &&
        pdfFiles.map((fileData, index) => (
          <div key={index} style={{ marginBottom: "20px" }}>
            <Document
              file={{ data: fileData }}
              loading=""
              onLoadSuccess={({ numPages }) => onPageCountUpdate(index, numPages)}
            >
              {Array.from(
                { length: pageCounts[index] || 0 },
                (_, pageIndex) => (
                  <Page
                    key={`pdf-${index}-page-${pageIndex + 1}`}
                    pageNumber={pageIndex + 1}
                    renderTextLayer={false}
                    renderAnnotationLayer={false}
                    width={900}
                  />
                )
              )}
            </Document>
          </div>
        ))}
    </>
  );
});

PdfRenderer.displayName = "PdfRenderer";

const UI7: React.FC = () => {
  const navigate = useNavigate();
  const hasFetchedRef = useRef(false);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const dprRef = useRef<number>(1);
  const lastPointRef = useRef<{ x: number; y: number } | null>(null);
  const [countdown, setCountdown] = useState(5);
  const [showWaitButton, setShowWaitButton] = useState(true);
  const [pdfFiles, setPdfFiles] = useState<Uint8Array[]>([]);
  const [pageCounts, setPageCounts] =
    useState<Record<number, number>>({});
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string>("");
  const [loadMessage, setLoadMessage] = useState("PDF加载中...");
  const [isDrawing, setIsDrawing] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);


  // 辅助函数：从 URL 获取 PDF 的 Uint8Array
  const fetchPdfBytes = async (url: string) => {
    try {
      if (window.electronAPI?.fetchPdf) {
        window.electronAPI.log("info", `[UI7] 通过 Electron 获取 PDF: ${url}`);
        const result = await window.electronAPI.fetchPdf(url);
        if (result.success && result.data) {
          const cleanBase64 = result.data.replace(/\s/g, "");
          const binaryString = atob(cleanBase64);
          const bytes = new Uint8Array(binaryString.length);
          for (let i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
          }
          return bytes;
        }
        throw new Error(result.error || "fetchPdf 返回失败");
      }

      window.electronAPI?.log("info", `[UI7] 通过 fetch 获取 PDF: ${url}`);
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`网络请求失败: ${response.status}`);
      }
      const arrayBuffer = await response.arrayBuffer();
      return new Uint8Array(arrayBuffer);
    } catch (error) {
      throw new Error(`获取 PDF 失败: ${(error as Error).message}`);
    }
  };

  // 从多份 PDF 中获取数据
  useEffect(() => {
    if (hasFetchedRef.current) {
      window.electronAPI?.log("info", "[UI7] 已获取过 PDF，跳过重复请求");
      return;
    }
    hasFetchedRef.current = true;

    const fetchPdfs = async () => {
      try {
        const res = await getTongyishuPdf(
          Number(localStorage.getItem("selectedExamId"))
        );
        if (res.Status !== 200) {
          alert(`获取PDF数据失败: ${res.Message}`);
          setLoadMessage(res.Message || "获取PDF数据失败");
          return;
        }

        const pdfUrls: string[] = res.Data?.list_pdf_url || [];
        if (!pdfUrls.length) {
          throw new Error("未获取到任何 PDF 链接");
        }

        setLoading(true);
        setError("");
        setPdfFiles([]);
        window.electronAPI?.log("info", "[UI7] 开始获取 PDF 文件");

        const files: Uint8Array[] = [];
        for (let idx = 0; idx < pdfUrls.length; idx++) {
          const url = pdfUrls[idx];
          window.electronAPI?.log(
            "info",
            `[UI7] 下载第 ${idx + 1} 份 PDF: ${url}`
          );
          const pdfBytes = await fetchPdfBytes(url);
          files.push(pdfBytes);
        }

        setPdfFiles(files);
        setLoading(false);
        setError("");
      } catch (err) {
        const errorMsg = `PDF获取失败: ${err}`;
        console.error(errorMsg);
        window.electronAPI?.log("error", `[UI7] ${errorMsg}`);
        setError("PDF 获取失败，请检查文件");
        setLoading(false);
      }
    };

    fetchPdfs();
  }, []);

  useEffect(() => {
    if (countdown > 0) {
      const timer = setTimeout(() => {
        setCountdown(countdown - 1);
      }, 1000);
      return () => clearTimeout(timer);
    } else {
      setShowWaitButton(false);
    }
  }, [countdown]);

  useEffect(() => {
    const initCanvas = () => {
      const canvas = canvasRef.current;
      if (!canvas) return;
      const ctx = canvas.getContext("2d", {
        willReadFrequently: true,
        alpha: true,
      });
      if (!ctx) return;
      const rect = canvas.getBoundingClientRect();
      const scale = 3;
      dprRef.current = scale;
      canvas.width = rect.width * scale;
      canvas.height = rect.height * scale;
      ctx.setTransform(scale, 0, 0, scale, 0, 0);
      canvas.style.width = `${rect.width}px`;
      canvas.style.height = `${rect.height}px`;
      ctx.strokeStyle = "#000000";
      ctx.lineWidth = 10;
      ctx.lineCap = "round";
      ctx.lineJoin = "round";
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";
    };

    const timer = setTimeout(initCanvas, 150);
    window.addEventListener("resize", initCanvas);
    return () => {
      clearTimeout(timer);
      window.removeEventListener("resize", initCanvas);
    };
  }, []);

  const getCoordinates = useCallback(
    (event: React.PointerEvent<HTMLCanvasElement>) => {
      const canvas = canvasRef.current;
      if (!canvas) return { x: 0, y: 0 };
      const rect = canvas.getBoundingClientRect();
      return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top,
      };
    },
    []
  );

  const startDrawing = useCallback(
    (event: React.PointerEvent<HTMLCanvasElement>) => {
      if (event.cancelable) {
        event.preventDefault();
      }
      const canvas = canvasRef.current;
      if (!canvas) return;
      const ctx = canvas.getContext("2d");
      if (!ctx) return;
      const { x, y } = getCoordinates(event);
      lastPointRef.current = { x, y };
      ctx.beginPath();
      ctx.moveTo(x, y);
      setIsDrawing(true);
      canvas.setPointerCapture(event.pointerId);
    },
    [getCoordinates]
  );

  const draw = useCallback(
    (event: React.PointerEvent<HTMLCanvasElement>) => {
      if (event.cancelable) {
        event.preventDefault();
      }
      if (!isDrawing || !lastPointRef.current) return;
      const canvas = canvasRef.current;
      if (!canvas) return;
      const ctx = canvas.getContext("2d");
      if (!ctx) return;
      const { x, y } = getCoordinates(event);
      const lastPoint = lastPointRef.current;
      const midX = (lastPoint.x + x) / 2;
      const midY = (lastPoint.y + y) / 2;
      ctx.quadraticCurveTo(lastPoint.x, lastPoint.y, midX, midY);
      ctx.stroke();
      lastPointRef.current = { x, y };
    },
    [getCoordinates, isDrawing]
  );

  const stopDrawing = useCallback(
    (event?: React.PointerEvent<HTMLCanvasElement>) => {
      setIsDrawing(false);
      lastPointRef.current = null;
      if (event && canvasRef.current?.hasPointerCapture(event.pointerId)) {
        canvasRef.current.releasePointerCapture(event.pointerId);
      }
    },
    []
  );

  const clearCanvas = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    ctx.save();
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.restore();
    ctx.strokeStyle = "#000000";
    ctx.lineWidth = 2;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
  }, []);

  const isCanvasBlank = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas) return true;
    const ctx = canvas.getContext("2d");
    if (!ctx) return true;
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const pixelBuffer = new Uint32Array(imageData.data.buffer);
    return !pixelBuffer.some((color) => color !== 0);
  }, []);

  const canvasToBlob = useCallback((canvas: HTMLCanvasElement) => {
    return new Promise<Blob>((resolve, reject) => {
      canvas.toBlob(
        (blob) => {
          if (blob) {
            resolve(blob);
          } else {
            reject(new Error("签名生成失败，请重试"));
          }
        },
        "image/png",
        1
      );
    });
  }, []);

  const handleBack = useCallback(() => {
    navigate(-1);
  }, [navigate]);

  const handleConfirm = useCallback(() => {
    const execute = async () => {
      if (isSubmitting) {
        return;
      }
      const canvas = canvasRef.current;
      if (!canvas) {
        alert("画布初始化失败，请刷新页面");
        return;
      }
      if (isCanvasBlank()) {
        alert("请先完成签名后再继续");
        return;
      }
      const examIdStr = localStorage.getItem("selectedExamId");
      const examId = Number(examIdStr);
      if (!examIdStr || Number.isNaN(examId)) {
        alert("未找到体检ID，请返回重试");
        return;
      }

      setIsSubmitting(true);
      try {
        const blob = await canvasToBlob(canvas);

        // 仍在本地缓存一下，方便 UI8 等页面复用
        try {
          const dataUrl = canvas.toDataURL("image/png");
          localStorage.setItem("consentSignature", dataUrl);
        } catch (cacheErr) {
          window.electronAPI?.log(
            "warn",
            `[UI7] 签名缓存失败: ${(cacheErr as Error).message}`
          );
        }

        window.electronAPI?.log(
          "info",
          `[UI7] 提交导检单签名，exam_id=${examId}`
        );
        const res = await submitDaojiandanSign(examId, blob);
        if (res.Status !== 200) {
          throw new Error(res.Message || "提交签名失败");
        }
        window.electronAPI?.log("info", "[UI7] 签名提交成功");
        localStorage.setItem("consentSignature", res.Data.pdf_url || "");
        navigate("/UI8");
      } catch (err) {
        const msg = (err as Error).message || "签名提交失败，请稍后重试";
        window.electronAPI?.log("error", `[UI7] ${msg}`);
        alert(msg);
      } finally {
        setIsSubmitting(false);
      }
    };

    execute();
  }, [canvasToBlob, isCanvasBlank, isSubmitting, navigate]);

  // 稳定 PDF 页数更新回调
  const handlePageCountUpdate = useCallback((index: number, numPages: number) => {
    setPageCounts((prev) => {
      if (prev[index] === numPages) return prev;
      return { ...prev, [index]: numPages };
    });
  }, []);

  return (
    <div className="basic-root">
      <div className="basic-white-block">
        <div className="basic-content">
          <span className="basic-title">体检知情同意书确认</span>
          <DecorLine />

          <div className="ui7-text-wrapper">
            <div className="ui7-text-content">
              <PdfRenderer
                pdfFiles={pdfFiles}
                loading={loading}
                error={error}
                pageCounts={pageCounts}
                onPageCountUpdate={handlePageCountUpdate}
                loadMessage={loadMessage}
              />
            </div>
          </div>

          <span className="ui7-text_4">请阅读后在下方签名确认</span>

          <div className="ui7-signature-wrapper">
            <canvas
              ref={canvasRef}
              className="ui7-signature-canvas"
              onPointerDown={startDrawing}
              onPointerMove={draw}
              onPointerUp={stopDrawing}
              onPointerLeave={stopDrawing}
              onPointerCancel={stopDrawing}
            />
            <button className="ui7-clear-button" onClick={clearCanvas}>
              清除
            </button>
          </div>

          <div className="basic-confirm-section">
            <BackButton text="返回" onClick={handleBack} />
            {showWaitButton ? (
              <WaitButton text={`等待(${countdown})S`} />
            ) : (
              <ConfirmButton
                text={isSubmitting ? "提交中..." : "确定"}
                onClick={handleConfirm}
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

export default UI7;
