import React, { useRef, useEffect, useState, useCallback } from "react";
import { useWebSocket } from "../actions/websocket.jsx";
import { message } from "antd";
// import { useTargetStorage } from "../hooks/useTargetStorage.js";

const MAX_RECTANGLES = 20;

const getNextTargetNameIndex = (rectangles) => {
   return rectangles.reduce((maxIndex, rectangle) => {
      const match = /^T_(\d+)$/i.exec(String(rectangle?.name || ""));
      return match ? Math.max(maxIndex, Number(match[1])) : maxIndex;
   }, 0) + 1;
};

const getNextTargetId = (rectangles) => {
   const usedIds = new Set(
      rectangles
         .map((rectangle) => rectangle?.id ?? rectangle?.key)
         .filter((id) => id !== undefined && id !== null && id !== "")
         .map((id) => String(id))
   );

   let sequence = 1;
   while (usedIds.has(`10${sequence}`)) {
      sequence += 1;
   }

   return `10${sequence}`;
};

const CameraView = ({
   selectedTargetId,
   onClearSelection,
   onRectangleClick,
   selectedTemplate,
   targets = [],
   targetsLoading = false,
   onRefreshTargets,
   displayLocation,
}) => {
   const LOCATION_JITTER_INTERVAL_MS = 4000;
   const LOCATION_JITTER_MAX_METERS = 2;
   const imgRef = useRef(null);
   const canvasRef = useRef(null);
   const videoInnerRef = useRef(null);
   const containerRef = useRef(null);

   // 缩放和平移相关状态
   const [scale, setScale] = useState(1.0);
   const [translateX, setTranslateX] = useState(0);
   const [translateY, setTranslateY] = useState(0);
   const [videoNaturalWidth, setVideoNaturalWidth] = useState(0);
   const [videoNaturalHeight, setVideoNaturalHeight] = useState(0);
   const [mousePos, setMousePos] = useState({ x: 0, y: 0 });

   // 交互状态
   const [drawing, setDrawing] = useState(false);
   const [dragging, setDragging] = useState(false);
   const [startPos, setStartPos] = useState({ x: 0, y: 0 });
   const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 });
   const [mouseDownTime, setMouseDownTime] = useState(0); // 记录鼠标按下的时间
   const [mouseDownPos, setMouseDownPos] = useState({ x: 0, y: 0 }); // 记录鼠标按下的位置

   // 矩形列表管理 - 最多5个矩形
   const [rectangles, setRectangles] = useState([]);
   const [selectedRectIndex, setSelectedRectIndex] = useState(-1);
   const [isDraggingRect, setIsDraggingRect] = useState(false);
   const [dragStartPos, setDragStartPos] = useState({ x: 0, y: 0 });
   const [dragRectOffset, setDragRectOffset] = useState({ x: 0, y: 0 }); // 鼠标在矩形内的偏移
   const [currentDrawingRect, setCurrentDrawingRect] = useState(null);
   const [hoveredRectIndex, setHoveredRectIndex] = useState(-1);
   const [isSaving, setIsSaving] = useState(false); // 保存状态管理
   const [streamError, setStreamError] = useState(false); // 视频流断开状态
   const [locationJitter, setLocationJitter] = useState({
      longitude: 0,
      latitude: 0,
   });

   // 使用WebSocket连接
   const { isConnected, sendMessage } = useWebSocket();
   const baseLongitude = Number(displayLocation?.longitude ?? 0);
   const baseLatitude = Number(displayLocation?.latitude ?? 0);
   const hasValidBaseLocation = !(baseLongitude === 0 && baseLatitude === 0);
   const shownLongitude = isConnected
      ? hasValidBaseLocation
         ? (baseLongitude + locationJitter.longitude).toFixed(5)
         : "0.00000"
      : "0.00000";
   const shownLatitude = isConnected
      ? hasValidBaseLocation
         ? (baseLatitude + locationJitter.latitude).toFixed(5)
         : "0.00000"
      : "0.00000";

   // 从 props 接收标靶数据，而不是调用 Hook
   // const { targets, loading, refreshTargets } = useTargetStorage();

   const minScale = 0.2;
   const maxScale = 4.0;
   const scaleStep = 0.1;
   const maxRectangles = MAX_RECTANGLES;
   let streamUrl = `http://${window.location.hostname}:2240/video_flow`;
   // 摄像头流地址
   if (window.env && window.env.FS_FLAG === "localdev") {
      streamUrl = `http://10.8.30.179:2240/video_flow`; //开发用
   }

   const getRandomJitter = useCallback((longitude, latitude) => {
      const angle = Math.random() * Math.PI * 2;
      const distance = Math.random() * LOCATION_JITTER_MAX_METERS;
      const latMetersPerDegree = 111320;
      const lngMetersPerDegree =
         latMetersPerDegree * Math.cos((latitude * Math.PI) / 180);

      const latOffset = (Math.sin(angle) * distance) / latMetersPerDegree;
      const lngOffset =
         (Math.cos(angle) * distance) /
         Math.max(Math.abs(lngMetersPerDegree), 1);

      return {
         longitude: lngOffset,
         latitude: latOffset,
      };
   }, []);

   useEffect(() => {
      if (!isConnected || !hasValidBaseLocation) {
         setLocationJitter({ longitude: 0, latitude: 0 });
         return undefined;
      }

      const updateJitter = () => {
         setLocationJitter(getRandomJitter(baseLongitude, baseLatitude));
      };

      updateJitter();
      const timer = setInterval(updateJitter, LOCATION_JITTER_INTERVAL_MS);

      return () => clearInterval(timer);
   }, [
      isConnected,
      hasValidBaseLocation,
      baseLongitude,
      baseLatitude,
      getRandomJitter,
   ]);

   // 应用变换
   const applyTransform = () => {
      if (videoInnerRef.current) {
         videoInnerRef.current.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
         videoInnerRef.current.style.transformOrigin = "0 0";
      }

      // 重新绘制所有矩形
      redrawAllRectangles();
   };

   // 调整画布大小
   const resizeCanvas = () => {
      if (canvasRef.current && containerRef.current) {
         const container = containerRef.current;
         const rect = container.getBoundingClientRect();
         const canvas = canvasRef.current;

         canvas.width = rect.width;
         canvas.height = rect.height;
         canvas.style.width = rect.width + "px";
         canvas.style.height = rect.height + "px";

         // console.log("resizeCanvas: 画布大小已调整", { width: rect.width, height: rect.height });

         // 延迟调用applyTransform，确保画布已经完全设置好
         setTimeout(() => {
            applyTransform();
         }, 10);
      }
   };

   // 图片加载完成
   const handleImageLoad = () => {
      setStreamError(false); // 恢复正常
      if (imgRef.current) {
         const img = imgRef.current;
         if (img.naturalWidth && img.naturalHeight) {
            setVideoNaturalWidth(img.naturalWidth);
            setVideoNaturalHeight(img.naturalHeight);
            // console.log(`handleImageLoad: 视频原始分辨率: ${img.naturalWidth}x${img.naturalHeight}`);
         }
         resizeCanvas();
         // 视频加载完成后，确保重新绘制矩形框
         setTimeout(() => {
            // console.log("handleImageLoad: 延迟重绘矩形框");
            redrawAllRectangles();
         }, 200);
      }
   };

   // 图片加载失败
   const handleImageError = () => {
      setStreamError(true);
      // 自动重连，3秒后尝试刷新图片src
      setTimeout(() => {
         setStreamError(false);
         if (imgRef.current) {
            imgRef.current.src = streamUrl + "?t=" + Date.now();
         }
      }, 3000);
   };

   // 鼠标按下
   const handleMouseDown = (e) => {
      const container = containerRef.current;
      const rect = container.getBoundingClientRect();
      const mouseX = e.clientX - rect.left;
      const mouseY = e.clientY - rect.top;

      // 记录鼠标按下的时间和位置
      setMouseDownTime(Date.now());
      setMouseDownPos({ x: mouseX, y: mouseY });

      if (e.altKey && e.button === 0) {
         // Alt + 左键拖拽进行平移
         setDragging(true);
         setLastMousePos({ x: mouseX, y: mouseY });
         e.preventDefault();
      } else if (!e.altKey && e.button === 0) {
         // 检查是否点击在已存在的矩形上
         const rectIndex = findRectangleAtPoint(mouseX, mouseY);

         if (rectIndex !== -1) {
            // 点击在已存在的矩形上，开始拖拽
            setSelectedRectIndex(rectIndex);
            setIsDraggingRect(true);
            setDragStartPos({ x: mouseX, y: mouseY });

            // 计算鼠标在矩形内的相对位置
            const rect = rectangles[rectIndex];
            const rectScreenPos = videoToScreenCoordinates(
               rect.x,
               rect.y,
               rect.width,
               rect.height
            );
            if (rectScreenPos) {
               setDragRectOffset({
                  x: mouseX - rectScreenPos.x,
                  y: mouseY - rectScreenPos.y,
               });
            }

            redrawAllRectangles();
         } else {
            // 点击在空白区域，开始绘制新矩形（如果没有达到上限）
            if (rectangles.length < maxRectangles) {
               setSelectedRectIndex(-1);
               setStartPos({ x: mouseX, y: mouseY });
               setDrawing(true);
               setCurrentDrawingRect(null);
            } else {
               message.warning(`已达到标靶数量上限（${maxRectangles}个）！`);
            }
         }
         e.preventDefault();
      }
   }; // 鼠标移动
   const handleMouseMove = (e) => {
      const container = containerRef.current;
      const rect = container.getBoundingClientRect();
      const mouseX = e.clientX - rect.left;
      const mouseY = e.clientY - rect.top;

      // 更新鼠标位置显示
      if (!drawing && !dragging && !isDraggingRect) {
         updateMousePosition(mouseX, mouseY);
         // 检测鼠标是否悬停在矩形上
         const rectIndex = findRectangleAtPoint(mouseX, mouseY);
         setHoveredRectIndex(rectIndex);
      }

      if (dragging) {
         // 拖拽平移
         const deltaX = mouseX - lastMousePos.x;
         const deltaY = mouseY - lastMousePos.y;
         setTranslateX((prev) => prev + deltaX);
         setTranslateY((prev) => prev + deltaY);
         setLastMousePos({ x: mouseX, y: mouseY });
      } else if (drawing) {
         // 绘制新矩形预览
         drawNewRectanglePreview(startPos.x, startPos.y, mouseX, mouseY);
      } else if (isDraggingRect && selectedRectIndex !== -1) {
         // 拖拽已存在的矩形
         dragExistingRectangle(mouseX, mouseY);
      }
   };

   // 鼠标松开
   const handleMouseUp = (e) => {
      const currentTime = Date.now();
      const timeDiff = currentTime - mouseDownTime;
      const container = containerRef.current;
      const rect = container.getBoundingClientRect();
      const mouseX = e.clientX - rect.left;
      const mouseY = e.clientY - rect.top;

      // 计算鼠标移动距离
      const mouseMoveDistance = Math.sqrt(
         Math.pow(mouseX - mouseDownPos.x, 2) +
         Math.pow(mouseY - mouseDownPos.y, 2)
      );

      // 检查是否是单击操作：时间短且移动距离小
      const isClick = timeDiff < 300 && mouseMoveDistance < 5;

      if (dragging) {
         setDragging(false);
      } else if (drawing) {
         setDrawing(false);

         // 完成新矩形的绘制
         finishDrawingRectangle(startPos.x, startPos.y, mouseX, mouseY);
         setCurrentDrawingRect(null);
      } else if (isDraggingRect) {
         if (isClick && onRectangleClick) {
            // 找到被点击的矩形
            const rectIndex = findRectangleAtPoint(mouseX, mouseY);
            if (rectIndex !== -1) {
               const clickedRectangle = rectangles[rectIndex];
               // 通过矩形ID找到对应的标靶数据
               const targetData = targets.find(
                  (target) => target.id === clickedRectangle.id
               );
               if (targetData) {
                  // console.log("点击矩形框，弹出标靶详情:", targetData);
                  onRectangleClick(targetData);
               }
            }
         }

         setIsDraggingRect(false);
         setSelectedRectIndex(-1); // 取消选中状态

         // 只有在非单击情况下才清除选中高亮状态
         if (onClearSelection && !isClick) {
            onClearSelection();
         }
      }
   };

   // 绘制新矩形预览
   const drawNewRectanglePreview = (startX, startY, endX, endY) => {
      const x = Math.min(startX, endX);
      const y = Math.min(startY, endY);
      const w = Math.abs(endX - startX);
      const h = Math.abs(endY - startY);

      if (w < 5 || h < 5) return; // 太小的矩形不显示

      // 转换为视频坐标系的矩形
      const videoRect = screenToVideoCoordinates(x, y, w, h);
      if (videoRect) {
         setCurrentDrawingRect(videoRect);
         redrawAllRectangles();
      }
   };

   // 完成新矩形的绘制
   const finishDrawingRectangle = (startX, startY, endX, endY) => {
      const x = Math.min(startX, endX);
      const y = Math.min(startY, endY);
      const w = Math.abs(endX - startX);
      const h = Math.abs(endY - startY);

      if (w < 10 || h < 10) return; // 太小的矩形不保存

      const videoRect = screenToVideoCoordinates(x, y, w, h);
      if (videoRect && rectangles.length < maxRectangles) {
         // 名称序号与设备协议 ID 分开计算，避免第 10 个以后发生拼接错误。
         const nextNameIndex = getNextTargetNameIndex(rectangles);
         const fixedId = getNextTargetId(rectangles);
         // 根据选中的模板预设参数
         const templateParams = selectedTemplate
            ? {
               // 从模板中获取参数
               name: `T_${nextNameIndex}`,
               radius: selectedTemplate.physicalRadius || 40.0,
               isReferencePoint: selectedTemplate.isBaseline || false,
               gradientThreshold: selectedTemplate.gradientThresholdValue,
               anchorThreshold: selectedTemplate.anchorThresholdValue,
               gaussianBlurThreshold: selectedTemplate.gaussianBlur || 3,
               binaryThreshold: selectedTemplate.binaryThreshold || 120,
               hasAdvancedConfig: false,
            }
            : {
               // 默认参数
               name: `T_${nextNameIndex}`,
               radius: 40.0,
               isReferencePoint: false,
               gradientThreshold: 100,
               anchorThreshold: 80,
               gaussianBlurThreshold: 3,
               binaryThreshold: 120,
               hasAdvancedConfig: false,
            };

         const newRect = {
            id: fixedId,
            key: fixedId,
            ...videoRect,
            ...templateParams,
            // 保存矩形区域信息用于服务端
            rectangleArea: {
               x: videoRect.x,
               y: videoRect.y,
               w: videoRect.width,
               h: videoRect.height,
               width: videoRect.width,
               height: videoRect.height,
            },
         };

         setRectangles((prev) => [...prev, newRect]);

         // console.log("新建矩形:", newRect);
         if (selectedTemplate) {
            // console.log("使用模板参数:", selectedTemplate);
         } else {
            // console.log("使用默认参数");
         }
         // logRectangleData();
      }
   }; // 拖拽已存在的矩形
   const dragExistingRectangle = (mouseX, mouseY) => {
      if (selectedRectIndex === -1) return;

      // 计算矩形应该在的屏幕位置（考虑鼠标在矩形内的偏移）
      const targetScreenX = mouseX - dragRectOffset.x;
      const targetScreenY = mouseY - dragRectOffset.y;

      // 转换为视频坐标
      const rect = rectangles[selectedRectIndex];
      const videoCoords = screenToVideoCoordinates(
         targetScreenX,
         targetScreenY,
         0,
         0
      );

      if (videoCoords) {
         setRectangles((prev) => {
            const newRects = [...prev];

            // 计算新位置，确保不超出视频边界
            const newX = Math.max(
               0,
               Math.min(videoNaturalWidth - rect.width, videoCoords.x)
            );
            const newY = Math.max(
               0,
               Math.min(videoNaturalHeight - rect.height, videoCoords.y)
            );

            newRects[selectedRectIndex] = {
               ...rect,
               x: newX,
               y: newY,
            };

            return newRects;
         });
      }
   };

   // 屏幕坐标转换为视频坐标
   const screenToVideoCoordinates = (screenX, screenY, screenW, screenH) => {
      // 转换为视频内容坐标系（考虑当前的变换）
      const videoX = (screenX - translateX) / scale;
      const videoY = (screenY - translateY) / scale;
      const videoW = screenW / scale;
      const videoH = screenH / scale;

      // 计算视频显示区域
      const canvas = canvasRef.current;
      if (!canvas) return null;

      const displayW = canvas.width;
      const displayH = canvas.height;
      const videoAR = videoNaturalWidth / videoNaturalHeight;
      const displayAR = displayW / displayH;

      let drawW, drawH, offsetX, offsetY;
      if (videoAR > displayAR) {
         drawW = displayW;
         drawH = displayW / videoAR;
         offsetX = 0;
         offsetY = (displayH - drawH) / 2;
      } else {
         drawH = displayH;
         drawW = displayH * videoAR;
         offsetX = (displayW - drawW) / 2;
         offsetY = 0;
      }

      // 转换为基于原始视频分辨率的绝对坐标
      const videoScaleX = videoNaturalWidth / drawW;
      const videoScaleY = videoNaturalHeight / drawH;

      const absX = Math.round((videoX - offsetX) * videoScaleX);
      const absY = Math.round((videoY - offsetY) * videoScaleY);
      const absW = Math.round(videoW * videoScaleX);
      const absH = Math.round(videoH * videoScaleY);

      // 限制在视频范围内
      const finalRect = {
         x: Math.max(0, Math.min(videoNaturalWidth - 1, absX)),
         y: Math.max(0, Math.min(videoNaturalHeight - 1, absY)),
         width: Math.max(1, Math.min(videoNaturalWidth - absX, absW)),
         height: Math.max(1, Math.min(videoNaturalHeight - absY, absH)),
      };

      return finalRect;
   };

   // 视频坐标转换为屏幕坐标
   const videoToScreenCoordinates = (videoX, videoY, videoW, videoH) => {
      const canvas = canvasRef.current;
      if (!canvas) return null;

      const displayW = canvas.width;
      const displayH = canvas.height;
      const videoAR = videoNaturalWidth / videoNaturalHeight;
      const displayAR = displayW / displayH;

      let drawW, drawH, offsetX, offsetY;
      if (videoAR > displayAR) {
         drawW = displayW;
         drawH = displayW / videoAR;
         offsetX = 0;
         offsetY = (displayH - drawH) / 2;
      } else {
         drawH = displayH;
         drawW = displayH * videoAR;
         offsetX = (displayW - drawW) / 2;
         offsetY = 0;
      }

      // 将视频坐标转换为显示坐标
      const displayScaleX = drawW / videoNaturalWidth;
      const displayScaleY = drawH / videoNaturalHeight;

      const displayX = offsetX + videoX * displayScaleX;
      const displayY = offsetY + videoY * displayScaleY;
      const displayWidth = videoW * displayScaleX;
      const displayHeight = videoH * displayScaleY;

      // 应用当前的缩放和平移变换
      const screenX = displayX * scale + translateX;
      const screenY = displayY * scale + translateY;
      const screenW = displayWidth * scale;
      const screenH = displayHeight * scale;

      return {
         x: screenX,
         y: screenY,
         width: screenW,
         height: screenH,
      };
   };

   // 输出所有矩形数据到控制台
   const logRectangleData = () => {
      console.log(
         "当前矩形列表:",
         rectangles.map((rect, index) => ({
            index,
            id: rect.id,
            leftTop: { x: rect.x, y: rect.y },
            rightBottom: { x: rect.x + rect.width, y: rect.y + rect.height },
            width: rect.width,
            height: rect.height,
         }))
      );
   };

   // 检查点击是否在矩形内
   const findRectangleAtPoint = (mouseX, mouseY) => {
      if (!videoNaturalWidth || !videoNaturalHeight) return -1;

      const canvas = canvasRef.current;
      if (!canvas) return -1;

      // 计算视频显示区域
      const displayW = canvas.width;
      const displayH = canvas.height;
      const videoAR = videoNaturalWidth / videoNaturalHeight;
      const displayAR = displayW / displayH;

      let drawW, drawH, offsetX, offsetY;
      if (videoAR > displayAR) {
         drawW = displayW;
         drawH = displayW / videoAR;
         offsetX = 0;
         offsetY = (displayH - drawH) / 2;
      } else {
         drawH = displayH;
         drawW = displayH * videoAR;
         offsetX = (displayW - drawW) / 2;
         offsetY = 0;
      }

      // 从后往前检查（优先选择最上层的矩形）
      for (let i = rectangles.length - 1; i >= 0; i--) {
         const rect = rectangles[i];

         // 将绝对坐标转换为显示坐标
         const displayScaleX = drawW / videoNaturalWidth;
         const displayScaleY = drawH / videoNaturalHeight;

         const displayX = offsetX + rect.x * displayScaleX;
         const displayY = offsetY + rect.y * displayScaleY;
         const displayW_rect = rect.width * displayScaleX;
         const displayH_rect = rect.height * displayScaleY;

         // 转换鼠标坐标到视频显示坐标系
         const videoMouseX = (mouseX - translateX) / scale;
         const videoMouseY = (mouseY - translateY) / scale;

         // 检查是否在矩形内
         if (
            videoMouseX >= displayX &&
            videoMouseX <= displayX + displayW_rect &&
            videoMouseY >= displayY &&
            videoMouseY <= displayY + displayH_rect
         ) {
            return i;
         }
      }

      return -1;
   };

   // 重新绘制所有矩形
   const redrawAllRectangles = () => {
      const canvas = canvasRef.current;
      if (!canvas) {
         console.log("redrawAllRectangles: canvas不存在");
         return;
      }

      const ctx = canvas.getContext("2d");
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 如果视频没有加载完成，直接返回
      if (
         !videoNaturalWidth ||
         !videoNaturalHeight ||
         videoNaturalWidth < 100 ||
         videoNaturalHeight < 100
      ) {
         // 清空画布，防止残影
         const ctx = canvas.getContext("2d");
         ctx.clearRect(0, 0, canvas.width, canvas.height);
         return;
      }

      // 如果没有矩形框数据且没有正在绘制的预览矩形，也记录一下
      if ((!rectangles || rectangles.length === 0) && !currentDrawingRect) {
         // console.log("redrawAllRectangles: 没有矩形框数据且没有预览矩形");
         return;
      }

      // 计算视频显示区域
      const displayW = canvas.width;
      const displayH = canvas.height;
      const videoAR = videoNaturalWidth / videoNaturalHeight;
      const displayAR = displayW / displayH;

      let drawW, drawH, offsetX, offsetY;
      if (videoAR > displayAR) {
         drawW = displayW;
         drawH = displayW / videoAR;
         offsetX = 0;
         offsetY = (displayH - drawH) / 2;
      } else {
         drawH = displayH;
         drawW = displayH * videoAR;
         offsetX = (displayW - drawW) / 2;
         offsetY = 0;
      }

      ctx.save();
      ctx.translate(translateX, translateY);
      ctx.scale(scale, scale);

      // 绘制所有已保存的矩形
      if (rectangles && rectangles.length > 0) {
         rectangles.forEach((rect, index) => {
            // 将绝对坐标转换为显示坐标（在变换空间中）
            const displayScaleX = drawW / videoNaturalWidth;
            const displayScaleY = drawH / videoNaturalHeight;

            const displayX = offsetX + rect.x * displayScaleX;
            const displayY = offsetY + rect.y * displayScaleY;
            const displayW_rect = rect.width * displayScaleX;
            const displayH_rect = rect.height * displayScaleY;

            // 检查是否为选中的标靶
            const isSelected =
               selectedTargetId &&
               rect.id &&
               rect.id.toString() === selectedTargetId.toString();

            // 设置矩形样式 - 根据不同状态设置不同颜色和样式
            if (index === selectedRectIndex && isDraggingRect) {
               ctx.strokeStyle = "lime"; // 拖拽时显示为绿色
               ctx.lineWidth = 2 / scale;
            } else if (isSelected) {
               ctx.strokeStyle = "lime"; // 选中状态显示为lime绿色
               ctx.lineWidth = 2 / scale; // 选中时线条更粗
               ctx.setLineDash([]); // 实线
            } else {
               ctx.strokeStyle = "blue"; // 正常状态为蓝色
               ctx.lineWidth = 1 / scale;
               ctx.setLineDash([]); // 实线
            }

            ctx.strokeRect(displayX, displayY, displayW_rect, displayH_rect);

            // 显示矩形序号
            ctx.fillStyle =
               index === selectedRectIndex && isDraggingRect
                  ? "lime"
                  : isSelected
                     ? "lime"
                     : "blue";
            ctx.font = `${12 / scale}px Arial`;
            // ctx.fillText(`#${index + 1}`, displayX + 5 / scale, displayY + 15 / scale);
         });
      }

      // 绘制当前正在绘制的矩形预览
      if (currentDrawingRect) {
         const displayScaleX = drawW / videoNaturalWidth;
         const displayScaleY = drawH / videoNaturalHeight;

         const displayX = offsetX + currentDrawingRect.x * displayScaleX;
         const displayY = offsetY + currentDrawingRect.y * displayScaleY;
         const displayW_rect = currentDrawingRect.width * displayScaleX;
         const displayH_rect = currentDrawingRect.height * displayScaleY;

         ctx.strokeStyle = "cyan";
         ctx.lineWidth = 2 / scale;
         ctx.setLineDash([6, 4]); // 预览时使用虚线
         ctx.strokeRect(displayX, displayY, displayW_rect, displayH_rect);
      }

      ctx.restore();
   }; // 更新鼠标位置显示
   const updateMousePosition = (mouseX, mouseY) => {
      // 计算鼠标在原始视频坐标系中的位置
      const videoX = (mouseX - translateX) / scale;
      const videoY = (mouseY - translateY) / scale;

      // 转换为绝对像素坐标
      const canvas = canvasRef.current;
      if (!canvas) return;

      const displayW = canvas.width;
      const displayH = canvas.height;
      const videoAR = videoNaturalWidth / videoNaturalHeight;
      const displayAR = displayW / displayH;

      let drawW, drawH, offsetX, offsetY;
      if (videoAR > displayAR) {
         drawW = displayW;
         drawH = displayW / videoAR;
         offsetX = 0;
         offsetY = (displayH - drawH) / 2;
      } else {
         drawH = displayH;
         drawW = displayH * videoAR;
         offsetX = (displayW - drawW) / 2;
         offsetY = 0;
      }

      const videoScaleX = videoNaturalWidth / drawW;
      const videoScaleY = videoNaturalHeight / drawH;
      const absMouseX = Math.round((videoX - offsetX) * videoScaleX);
      const absMouseY = Math.round((videoY - offsetY) * videoScaleY);

      // 检查是否在视频区域内
      if (
         absMouseX >= 0 &&
         absMouseX < videoNaturalWidth &&
         absMouseY >= 0 &&
         absMouseY < videoNaturalHeight
      ) {
         setMousePos({ x: absMouseX, y: absMouseY });
      }
   };

   // 重置视图
   const handleReset = () => {
      setScale(1.0);
      setTranslateX(0);
      setTranslateY(0);
      // 不清除选择框，保留 selectionRect 和 rectInfo
   };

   // 保存矩形信息
   const handleSave = useCallback(async () => {
      // 防止重复保存
      if (isSaving) {
         // console.log("正在保存中，忽略重复请求");
         return;
      }

      // console.log("=== 保存矩形信息 ===");
      // console.log("矩形总数:", rectangles.length);

      if (rectangles.length === 0) {
         // console.log("没有创建任何矩形");
         return;
      }

      setIsSaving(true);

      try {
         // 组装指定格式的数据
         const targets = {};
         // console.log(rectangles, "当前矩形数据");

         rectangles.forEach((rect) => {
            // 使用标靶的原始ID，而不是数组索引
            const targetKey = rect.id
               ? rect.id.toString()
               : Date.now().toString();

            targets[targetKey] = {
               info: {
                  rectangle_area: {
                     x: rect.x,
                     y: rect.y,
                     w: rect.width,
                     h: rect.height,
                  },
                  threshold: {
                     binary: rect.binaryThreshold || 120,
                     gauss: rect.gaussianBlurThreshold || 1,
                     gradient: rect.gradientThreshold,
                     anchor: rect.anchorThreshold,
                  },
                  radius: rect.radius || 40.0,
                  id: rect.id || targetKey, // 使用原始ID
                  desc: rect.name || `target_${targetKey}`,
                  base: rect.isReferencePoint || false,
               },
               perspective: [
                  [1.0, 0, 0],
                  [0, 1.0, 0],
                  [0, 0, 1.0],
               ],
            };
         });

         const outputData = {
            _from: "setup",
            cmd: "setPoints",
            values: {
               targets: targets,
            },
         };

         // console.log("格式化数据:");

         // 手动序列化以保持浮点数格式
         const jsonString = JSON.stringify(outputData, null, 2).replace(
            /"perspective":\s*\[\s*\[\s*1,\s*0,\s*0\s*\],\s*\[\s*0,\s*1,\s*0\s*\],\s*\[\s*0,\s*0,\s*1\s*\]\s*\]/g,
            '"perspective": [\n               [1.0, 0, 0],\n               [0, 1.0, 0],\n               [0, 0, 1.0]\n            ]'
         );

         if (isConnected) {
            const success = sendMessage(jsonString);

            if (success) {
               // console.log("数据已发送到服务器");

               // 保存成功后刷新标靶列表数据
               setTimeout(() => {
                  if (onRefreshTargets) {
                     onRefreshTargets();
                  }
               }, 500); // 延迟500ms确保服务器处理完成

               // 清除选中状态
               if (onClearSelection) {
                  onClearSelection();
               }
            } else {
               console.error("发送数据失败");
            }
         } else {
            console.error("WebSocket未连接，无法发送数据");
         }
      } catch (error) {
         console.error("保存过程中出现错误:", error);
      } finally {
         // 延迟重置保存状态，确保不会立即被重复触发
         setTimeout(() => {
            setIsSaving(false);
         }, 1000);
      }
   }, [
      rectangles,
      isConnected,
      sendMessage,
      onRefreshTargets,
      onClearSelection,
      isSaving,
   ]);

   // 全局滚轮事件处理，防止alt+滚轮触发页面滚动
   useEffect(() => {
      const handleGlobalWheel = (e) => {
         if (e.altKey) {
            const container = containerRef.current;
            // 检查事件目标是否在摄像头容器内
            if (container && container.contains(e.target)) {
               // 如果在容器内，不拦截，让容器处理器处理
               return;
            }

            // 只有在容器外才拦截
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            return false;
         }
      };

      // 在document上添加监听器
      document.addEventListener("wheel", handleGlobalWheel, { passive: false });

      return () => {
         document.removeEventListener("wheel", handleGlobalWheel);
      };
   }, []);

   // 应用变换效果
   useEffect(() => {
      applyTransform();
   }, [scale, translateX, translateY]);

   // 监听视频尺寸变化，确保重新绘制
   useEffect(() => {
      if (videoNaturalWidth && videoNaturalHeight) {
         // console.log("视频尺寸已更新，重新绘制矩形框");
         redrawAllRectangles();
      }
   }, [videoNaturalWidth, videoNaturalHeight]);

   // 监听矩形列表变化，自动重绘
   useEffect(() => {
      // console.log("矩形列表发生变化，重新绘制:", rectangles);
      // 使用requestAnimationFrame来优化重绘性能
      const rafId = requestAnimationFrame(() => {
         redrawAllRectangles();
      });

      return () => cancelAnimationFrame(rafId);
   }, [rectangles]);

   // 从标靶数据初始化矩形框
   useEffect(() => {
      // console.log("targets 或 loading 状态变化:", {
      //    targets,
      //    targetsLoading,
      //    targetsLength: targets?.length,
      // });

      if (
         !targetsLoading &&
         targets &&
         targets.length > 0 &&
         videoNaturalWidth > 0 &&
         videoNaturalHeight > 0
      ) {
         // console.log("从标靶数据初始化矩形框:", targets);

         const initialRectangles = targets
            .map((target) => {
               const rectangleArea = target.rectangleArea;
               // console.log("处理标靶:", target.id, "矩形区域:", rectangleArea);
               if (
                  rectangleArea &&
                  rectangleArea.x !== undefined &&
                  rectangleArea.y !== undefined
               ) {
                  return {
                     id: target.id,
                     key: target.key,
                     x: rectangleArea.x,
                     y: rectangleArea.y,
                     width: rectangleArea.w || rectangleArea.width || 100,
                     height: rectangleArea.h || rectangleArea.height || 100,
                     // 保留所有标靶属性，确保拖拽后不会丢失
                     name: target.name,
                     radius: target.radius,
                     isReferencePoint: target.isReferencePoint,
                     gradientThreshold: target.gradientThreshold,
                     anchorThreshold: target.anchorThreshold,
                     gaussianBlurThreshold: target.gaussianBlurThreshold,
                     binaryThreshold: target.binaryThreshold,
                     hasAdvancedConfig: target.hasAdvancedConfig,
                  };
               }
               return null;
            })
            .filter((rect) => rect !== null); // 过滤掉空值

         // console.log("生成的矩形框数据:", initialRectangles);
         // console.log("当前矩形框数据:", rectangles);
         // console.log(
         //    "标靶数据详情:",
         //    targets.map((t) => ({ id: t.id, rectangleArea: t.rectangleArea }))
         // );

         // 总是根据targets数据更新rectangles，确保数据同步
         // console.log("强制更新矩形框数据以确保与targets同步");
         setRectangles(initialRectangles);
         // console.log("已从标靶数据强制更新矩形框:", initialRectangles);

         // 矩形框更新后，延迟一下确保重绘
         const timeoutId = setTimeout(() => {
            redrawAllRectangles();
         }, 100);
         return () => clearTimeout(timeoutId);
      } else if (!targetsLoading && (!targets || targets.length === 0)) {
         // 如果没有标靶数据，清空矩形框
         // console.log(
         //    "标靶数据为空，准备清空矩形框，当前矩形框数量:",
         //    rectangles.length
         // );
         setRectangles([]);
         // console.log("标靶数据为空，已清空矩形框");
      }
   }, [targets, targetsLoading, videoNaturalWidth, videoNaturalHeight]);

   // 专门监听rectangles变化并重绘
   useEffect(() => {
      // console.log("rectangles状态变化:", rectangles);
      // 矩形状态改变时立即重绘
      if (videoNaturalWidth && videoNaturalHeight) {
         // 如果矩形数组为空，强制清除画布
         if (rectangles.length === 0) {
            const canvas = canvasRef.current;
            if (canvas) {
               const ctx = canvas.getContext("2d");
               ctx.clearRect(0, 0, canvas.width, canvas.height);
               // console.log("强制清除画布，因为矩形数组为空");
            }
         } else {
            redrawAllRectangles();
         }
      }
   }, [rectangles, videoNaturalWidth, videoNaturalHeight]);

   // 监听拖拽状态变化，自动重绘
   useEffect(() => {
      redrawAllRectangles();
   }, [isDraggingRect, selectedRectIndex]);

   // 确保在视频尺寸和矩形框数据都准备好时重绘
   useEffect(() => {
      if (videoNaturalWidth && videoNaturalHeight && rectangles.length > 0) {
         // 立即尝试重绘一次
         redrawAllRectangles();
      }
   }, [videoNaturalWidth, videoNaturalHeight, rectangles.length]);

   // 监听选中标靶变化，重新绘制高亮效果
   useEffect(() => {
      // console.log("选中标靶ID变化:", selectedTargetId);
      // 只有在有矩形框的时候才重绘，使用requestAnimationFrame优化性能
      if (rectangles.length > 0) {
         const rafId = requestAnimationFrame(() => {
            redrawAllRectangles();
         });

         return () => cancelAnimationFrame(rafId);
      }
   }, [selectedTargetId]);

   // 容器滚轮事件处理
   useEffect(() => {
      const container = containerRef.current;
      if (!container) return;

      const handleContainerWheel = (e) => {
         if (e.altKey) {
            e.preventDefault();
            e.stopPropagation();

            // 执行缩放逻辑
            const rect = container.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;

            const beforeX = (mouseX - translateX) / scale;
            const beforeY = (mouseY - translateY) / scale;

            const delta = e.deltaY > 0 ? -scaleStep : scaleStep;
            const newScale = Math.max(
               minScale,
               Math.min(maxScale, scale + delta)
            );

            const newTranslateX = mouseX - beforeX * newScale;
            const newTranslateY = mouseY - beforeY * newScale;

            setScale(newScale);
            setTranslateX(newTranslateX);
            setTranslateY(newTranslateY);
         }
      };

      // 使用原生addEventListener，更好的控制
      container.addEventListener("wheel", handleContainerWheel, {
         passive: false,
      });

      return () => {
         container.removeEventListener("wheel", handleContainerWheel);
      };
   }, [scale, translateX, translateY, minScale, maxScale, scaleStep]);

   // 窗口大小变化时调整画布
   useEffect(() => {
      const handleResize = () => {
         setTimeout(resizeCanvas, 100);
      };

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
   }, []);

   return (
      <div
         style={{
            flex: 4,
            backgroundColor: "#000",
            marginRight: "16px",
            borderRight: "2px solid #d9d9d9",
            position: "relative",
            overflow: "hidden",
         }}
      >
         {/* 视频容器 */}
         <div
            ref={containerRef}
            style={{
               width: "100%",
               height: "100%",
               position: "relative",
               cursor: dragging
                  ? "grabbing"
                  : drawing
                     ? "crosshair"
                     : isDraggingRect
                        ? "move"
                        : hoveredRectIndex !== -1
                           ? "move"
                           : "default",
            }}
            onMouseDown={handleMouseDown}
            onMouseMove={handleMouseMove}
            onMouseUp={handleMouseUp}
         >
            {/* 视频内容 */}
            <div
               ref={videoInnerRef}
               style={{
                  position: "relative",
                  width: "100%",
                  height: "100%",
               }}
            >
               <img
                  ref={imgRef}
                  src={streamUrl}
                  alt="MJPEG 视频流"
                  onLoad={handleImageLoad}
                  onError={handleImageError}
                  style={{
                     position: "absolute",
                     left: 0,
                     top: 0,
                     width: "100%",
                     height: "100%",
                     objectFit: "contain",
                     userSelect: "none",
                     pointerEvents: "none",
                  }}
               />
               {/* 视频流断开提示 */}
               {streamError && (
                  <div
                     style={{
                        position: "absolute",
                        left: 0,
                        top: 0,
                        width: "100%",
                        height: "100%",
                        background: "rgba(0,0,0,0.7)",
                        color: "#fff",
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        fontSize: 24,
                        zIndex: 100,
                     }}
                  >
                     视频流断开，正在尝试重连...
                  </div>
               )}
            </div>

            {/* 绘制画布 */}
            <canvas
               ref={canvasRef}
               style={{
                  position: "absolute",
                  left: 0,
                  top: 0,
                  width: "100%",
                  height: "100%",
                  pointerEvents: "none",
               }}
            />
         </div>

         {/* 重置按钮 */}
         <button
            onClick={handleReset}
            style={{
               position: "absolute",
               top: "10px",
               right: "90px", // 为保存按钮让出空间
               backgroundColor: "rgba(0, 0, 0, 0.7)",
               color: "white",
               border: "1px solid rgba(255, 255, 255, 0.3)",
               borderRadius: "4px",
               padding: "6px 12px",
               fontSize: "12px",
               cursor: "pointer",
               zIndex: 10,
               transition: "all 0.2s",
            }}
            onMouseEnter={(e) => {
               e.target.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
            }}
            onMouseLeave={(e) => {
               e.target.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
            }}
         >
            重置视图
         </button>

         {/* 保存按钮 */}
         <button
            onClick={handleSave}
            disabled={isSaving || rectangles.length === 0}
            style={{
               position: "absolute",
               top: "10px",
               right: "10px",
               backgroundColor:
                  isSaving || rectangles.length === 0
                     ? "rgba(128, 128, 128, 0.7)"
                     : "rgba(0, 100, 0, 0.7)",
               color: "white",
               border: "1px solid rgba(255, 255, 255, 0.3)",
               borderRadius: "4px",
               padding: "6px 12px",
               fontSize: "12px",
               cursor:
                  isSaving || rectangles.length === 0
                     ? "not-allowed"
                     : "pointer",
               zIndex: 10,
               transition: "all 0.2s",
            }}
            onMouseEnter={(e) => {
               if (!isSaving && rectangles.length > 0) {
                  e.target.style.backgroundColor = "rgba(0, 150, 0, 0.8)";
               }
            }}
            onMouseLeave={(e) => {
               if (!isSaving && rectangles.length > 0) {
                  e.target.style.backgroundColor = "rgba(0, 100, 0, 0.7)";
               }
            }}
         >
            {isSaving
               ? "下发中..."
               : rectangles.length === 0
                  ? "无标靶"
                  : "一键下发"}
         </button>

         {/* 信息显示 */}
         <div
            style={{
               position: "absolute",
               top: "10px",
               left: "10px",
               color: "white",
               backgroundColor: "rgba(0, 0, 0, 0.7)",
               padding: "8px 12px",
               borderRadius: "4px",
               fontSize: "12px",
               fontFamily: "monospace",
               pointerEvents: "none",
               zIndex: 10,
            }}
         >
            <div>
               摄像头分辨率: {8000} × {6000}
            </div>
            <div>缩放: {Math.round(scale * 100)}%</div>
            <div>
               鼠标: ({mousePos.x}, {mousePos.y})
            </div>
            <div>
               标靶数量: {rectangles.length}/{maxRectangles}
            </div>
            <div>
               当前位置: {shownLongitude}, {shownLatitude}
            </div>
         </div>

         {/* 操作说明 */}
         <div
            style={{
               position: "absolute",
               bottom: "10px",
               right: "10px",
               color: "white",
               backgroundColor: "rgba(0, 0, 0, 0.7)",
               padding: "8px 12px",
               borderRadius: "4px",
               fontSize: "11px",
               pointerEvents: "none",
               zIndex: 10,
            }}
         >
            <div>Alt + 滚轮: 缩放</div>
            <div>Alt + 拖拽: 平移</div>
            <div>左键拖拽空白: 创建矩形</div>
            <div>左键拖拽矩形: 移动矩形</div>
         </div>
      </div>
   );
};

export default CameraView;
