import React, { useRef, useState, useCallback, useEffect } from 'react';

interface SelectionArea {
  startRow: number;
  startCol: number;
  endRow: number;
  endCol: number;
}

interface MagnifierSelectionOverlayProps {
  isActive: boolean;
  canvasRef: React.RefObject<HTMLCanvasElement | null>;
  gridDimensions: { N: number; M: number } | null;
  cellSize: number;
  onSelectionComplete: (area: SelectionArea) => void;
}

const MagnifierSelectionOverlay: React.FC<MagnifierSelectionOverlayProps> = ({
  isActive,
  canvasRef,
  gridDimensions,
  onSelectionComplete
}) => {
  const [isSelecting, setIsSelecting] = useState(false);
  const [selectionStart, setSelectionStart] = useState<{ x: number; y: number } | null>(null);
  const [selectionEnd, setSelectionEnd] = useState<{ x: number; y: number } | null>(null);
  const overlayRef = useRef<HTMLDivElement>(null);
  
  // 滚动禁用状态
  const scrollDisabledRef = useRef<boolean>(false);
  const savedScrollPositionRef = useRef<number>(0);

  // 禁用/启用页面滚动
  const preventScrolling = useCallback((e: Event) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

  const disableScroll = useCallback(() => {
    if (scrollDisabledRef.current) return; // 避免重复禁用
    
    // 保存当前滚动位置
    savedScrollPositionRef.current = window.scrollY;
    
    // 设置CSS样式
    document.body.style.overflow = 'hidden';
    document.documentElement.style.overflow = 'hidden';
    
    // 阻止滚动事件（但不使用fixed定位，避免跳转问题）
    document.addEventListener('wheel', preventScrolling, { passive: false });
    document.addEventListener('touchmove', preventScrolling, { passive: false });
    
    scrollDisabledRef.current = true;
  }, [preventScrolling]);
  
  const enableScroll = useCallback(() => {
    if (!scrollDisabledRef.current) return; // 避免重复启用
    
    // 恢复CSS样式
    document.body.style.overflow = '';
    document.documentElement.style.overflow = '';
    
    // 移除事件监听器
    document.removeEventListener('wheel', preventScrolling);
    document.removeEventListener('touchmove', preventScrolling);
    
    scrollDisabledRef.current = false;
    // 不再强制恢复滚动位置，让浏览器保持自然状态
  }, [preventScrolling]);

  // 获取画布相对坐标 - 优化移动设备支持
  const getCanvasCoordinates = useCallback((clientX: number, clientY: number) => {
    if (!canvasRef.current) return null;
    
    const canvas = canvasRef.current;
    const rect = canvas.getBoundingClientRect();
    
    // 考虑设备像素比和画布缩放
    const scaleX = canvas.width / rect.width;
    const scaleY = canvas.height / rect.height;
    
    // 计算相对于画布的坐标
    const x = (clientX - rect.left) * scaleX;
    const y = (clientY - rect.top) * scaleY;
    
    return {
      x: Math.max(0, Math.min(canvas.width, x)),
      y: Math.max(0, Math.min(canvas.height, y))
    };
  }, [canvasRef]);

  // 将像素坐标转换为网格坐标
  const pixelToGrid = useCallback((x: number, y: number) => {
    if (!gridDimensions || !canvasRef.current) return null;
    
    const canvasWidth = canvasRef.current.width;
    const canvasHeight = canvasRef.current.height;
    const cellWidth = canvasWidth / gridDimensions.N;
    const cellHeight = canvasHeight / gridDimensions.M;
    
    const col = Math.floor(x / cellWidth);
    const row = Math.floor(y / cellHeight);
    
    return {
      row: Math.max(0, Math.min(gridDimensions.M - 1, row)),
      col: Math.max(0, Math.min(gridDimensions.N - 1, col))
    };
  }, [gridDimensions, canvasRef]);

  // 处理鼠标事件
  const handleMouseDown = useCallback((event: React.MouseEvent) => {
    if (!isActive) return;
    
    const coords = getCanvasCoordinates(event.clientX, event.clientY);
    if (!coords) return;
    
    setIsSelecting(true);
    setSelectionStart(coords);
    setSelectionEnd(coords);
    disableScroll(); // 禁用滚动
    event.preventDefault();
  }, [isActive, getCanvasCoordinates, disableScroll]);

  const handleMouseMove = useCallback((event: MouseEvent) => {
    if (!isSelecting || !selectionStart) return;
    
    const coords = getCanvasCoordinates(event.clientX, event.clientY);
    if (!coords) return;
    
    setSelectionEnd(coords);
  }, [isSelecting, selectionStart, getCanvasCoordinates]);

  const handleMouseUp = useCallback(() => {
    if (!isSelecting || !selectionStart || !selectionEnd) {
      enableScroll(); // 确保恢复滚动
      return;
    }
    
    const startGrid = pixelToGrid(selectionStart.x, selectionStart.y);
    const endGrid = pixelToGrid(selectionEnd.x, selectionEnd.y);
    
    if (startGrid && endGrid) {
      const area: SelectionArea = {
        startRow: Math.min(startGrid.row, endGrid.row),
        startCol: Math.min(startGrid.col, endGrid.col),
        endRow: Math.max(startGrid.row, endGrid.row),
        endCol: Math.max(startGrid.col, endGrid.col)
      };
      
      onSelectionComplete(area);
    }
    
    setIsSelecting(false);
    setSelectionStart(null);
    setSelectionEnd(null);
    enableScroll(); // 恢复滚动
  }, [isSelecting, selectionStart, selectionEnd, pixelToGrid, onSelectionComplete, enableScroll]);

  // 处理触摸事件
  const handleTouchStart = useCallback((event: React.TouchEvent) => {
    if (!isActive) return;
    
    // 先阻止默认行为，避免滚动干扰
    event.preventDefault();
    event.stopPropagation();
    
    const touch = event.touches[0];
    if (!touch) return;
    
    const coords = getCanvasCoordinates(touch.clientX, touch.clientY);
    if (!coords) return;
    
    setIsSelecting(true);
    setSelectionStart(coords);
    setSelectionEnd(coords);
    disableScroll(); // 禁用滚动
  }, [isActive, getCanvasCoordinates, disableScroll]);

  const handleTouchMove = useCallback((event: TouchEvent) => {
    if (!isSelecting || !selectionStart) return;
    
    // 先阻止默认行为
    event.preventDefault();
    event.stopPropagation();
    
    const touch = event.touches[0];
    if (!touch) return;
    
    const coords = getCanvasCoordinates(touch.clientX, touch.clientY);
    if (!coords) return;
    
    setSelectionEnd(coords);
  }, [isSelecting, selectionStart, getCanvasCoordinates]);

  const handleTouchEnd = useCallback(() => {
    handleMouseUp();
  }, [handleMouseUp]);

  // 事件监听器
  useEffect(() => {
    if (isSelecting) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      document.addEventListener('touchmove', handleTouchMove);
      document.addEventListener('touchend', handleTouchEnd);
      
      return () => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
        document.removeEventListener('touchmove', handleTouchMove);
        document.removeEventListener('touchend', handleTouchEnd);
        enableScroll(); // 清理时恢复滚动
      };
    }
  }, [isSelecting, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd, enableScroll]);

  // 组件卸载时恢复滚动
  useEffect(() => {
    return () => {
      enableScroll();
    };
  }, [enableScroll]);

  // 当组件变为非活跃状态时恢复滚动
  useEffect(() => {
    if (!isActive) {
      enableScroll();
      setIsSelecting(false);
      setSelectionStart(null);
      setSelectionEnd(null);
    }
  }, [isActive, enableScroll]);

  // 计算选择框的样式
  const getSelectionStyle = useCallback(() => {
    if (!selectionStart || !selectionEnd || !canvasRef.current) return {};
    
    const canvas = canvasRef.current;
    const rect = canvas.getBoundingClientRect();
    
    // 将画布坐标转换回屏幕坐标
    const scaleX = rect.width / canvas.width;
    const scaleY = rect.height / canvas.height;
    
    const screenStartX = selectionStart.x * scaleX;
    const screenStartY = selectionStart.y * scaleY;
    const screenEndX = selectionEnd.x * scaleX;
    const screenEndY = selectionEnd.y * scaleY;
    
    const minX = Math.min(screenStartX, screenEndX);
    const minY = Math.min(screenStartY, screenEndY);
    const maxX = Math.max(screenStartX, screenEndX);
    const maxY = Math.max(screenStartY, screenEndY);
    
    return {
      left: rect.left + minX,
      top: rect.top + minY,
      width: maxX - minX,
      height: maxY - minY,
      position: 'fixed' as const,
      border: '2px solid #10b981',
      backgroundColor: 'rgba(16, 185, 129, 0.1)',
      pointerEvents: 'none' as const,
      zIndex: 1000
    };
  }, [selectionStart, selectionEnd, canvasRef]);

  if (!isActive) return null;

  return (
    <>
      {/* 覆盖层 */}
      <div
        ref={overlayRef}
        className="fixed inset-0 z-50"
        style={{ 
          cursor: 'crosshair',
          pointerEvents: isActive ? 'auto' : 'none'
        }}
        onMouseDown={handleMouseDown}
        onTouchStart={handleTouchStart}
        onWheel={(e) => e.preventDefault()}
        onTouchMove={(e) => e.preventDefault()}
        onScroll={(e) => e.preventDefault()}
      />
      
      {/* 选择框 */}
      {isSelecting && selectionStart && selectionEnd && (
        <div style={getSelectionStyle()} />
      )}
    </>
  );
};

export default MagnifierSelectionOverlay; 