'use client';

import { useState, useCallback, useRef, useEffect } from 'react';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import {
  MousePointer,
  MapPin,
  Minus,
  Pentagon,
  Square,
  Circle,
  Undo,
  Trash2,
  Save,
  AlertCircle,
  CheckCircle2
} from 'lucide-react';
import { toast } from 'sonner';
import { DrawGeometry } from './drawEditReducer';

export type DrawMode = 'none' | 'point' | 'line' | 'polygon' | 'rectangle' | 'circle';

export interface DrawPoint {
  x: number;
  y: number;
  lat?: number;
  lng?: number;
}

interface DrawingToolsProps {
  onSaveRequest?: (geometry: DrawGeometry) => void;
  enableSnapping?: boolean;
  snapDistance?: number;
  canvasWidth?: number;
  canvasHeight?: number;
}

export function DrawingTools({
  onSaveRequest,
  enableSnapping = true,
  snapDistance = 10,
  canvasWidth = 800,
  canvasHeight = 600
}: DrawingToolsProps) {
  // 状态管理
  const [drawMode, setDrawMode] = useState<DrawMode>('none');
  const [currentPoints, setCurrentPoints] = useState<DrawPoint[]>([]);
  const [isDrawing, setIsDrawing] = useState(false);
  const [mousePosition, setMousePosition] = useState<DrawPoint | null>(null);
  const [snappedPoint, setSnappedPoint] = useState<DrawPoint | null>(null);
  const [zoomLevel, setZoomLevel] = useState(1);

  const canvasRef = useRef<HTMLDivElement>(null);

  // 键盘事件处理
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Ctrl+Z 撤销
      if (e.ctrlKey && e.key === 'z' && !e.shiftKey) {
        e.preventDefault();
        handleUndo();
      }
      // Delete 清除
      else if (e.key === 'Delete') {
        e.preventDefault();
        handleClear();
      }
      // Esc 取消绘制
      else if (e.key === 'Escape' && isDrawing) {
        e.preventDefault();
        handleClear();
      }
      // Ctrl+S 保存到地块档案
      else if (e.ctrlKey && e.key === 's') {
        e.preventDefault();
        handleSave();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isDrawing, currentPoints, drawMode]);

  // 撤销 - 删除最后一个点
  const handleUndo = useCallback(() => {
    if (currentPoints.length > 0) {
      const newPoints = currentPoints.slice(0, -1);
      setCurrentPoints(newPoints);

      if (newPoints.length === 0) {
        setIsDrawing(false);
      }

      toast.info(`已撤销，剩余 ${newPoints.length} 个点`);
    } else {
      toast.info('没有可撤销的操作');
    }
  }, [currentPoints]);

  // 检查点是否接近（用于吸附）
  const isNearPoint = (p1: DrawPoint, p2: DrawPoint): boolean => {
    const dx = p1.x - p2.x;
    const dy = p1.y - p2.y;
    return Math.sqrt(dx * dx + dy * dy) < snapDistance;
  };

  // 查找吸附点
  const findSnapPoint = (point: DrawPoint): DrawPoint | null => {
    if (!enableSnapping) return null;

    for (const existing of currentPoints) {
      if (isNearPoint(point, existing)) {
        return existing;
      }
    }
    return null;
  };

  // 检查多边形自相交
  const checkSelfIntersection = (points: DrawPoint[]): boolean => {
    if (points.length < 4) return false;

    for (let i = 0; i < points.length; i++) {
      const p1 = points[i];
      const p2 = points[(i + 1) % points.length];

      for (let j = i + 2; j < points.length; j++) {
        if (j === points.length - 1 && i === 0) continue; // 跳过首尾相连的边

        const p3 = points[j];
        const p4 = points[(j + 1) % points.length];

        if (segmentsIntersect(p1, p2, p3, p4)) {
          return true;
        }
      }
    }
    return false;
  };

  // 检查两条线段是否相交
  const segmentsIntersect = (p1: DrawPoint, p2: DrawPoint, p3: DrawPoint, p4: DrawPoint): boolean => {
    const ccw = (A: DrawPoint, B: DrawPoint, C: DrawPoint) => {
      return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x);
    };

    return ccw(p1, p3, p4) !== ccw(p2, p3, p4) && ccw(p1, p2, p3) !== ccw(p1, p2, p4);
  };

  // 计算多边形面积（Shoelace公式）
  const calculateArea = (points: DrawPoint[]): number => {
    if (points.length < 3) return 0;

    let area = 0;
    for (let i = 0; i < points.length; i++) {
      const j = (i + 1) % points.length;
      area += points[i].x * points[j].y;
      area -= points[j].x * points[i].y;
    }

    // 转换为亩（假设1单位 = 0.5米，1亩 = 666.67平方米）
    const squareMeters = Math.abs(area) * 0.25; // (0.5m * 0.5m)
    const mu = squareMeters / 666.67;
    return mu;
  };

  // 计算周长
  const calculatePerimeter = (points: DrawPoint[]): number => {
    if (points.length < 2) return 0;

    let perimeter = 0;
    for (let i = 0; i < points.length; i++) {
      const j = (i + 1) % points.length;
      const dx = points[j].x - points[i].x;
      const dy = points[j].y - points[i].y;
      perimeter += Math.sqrt(dx * dx + dy * dy);
    }

    // 转换为米（假设1单位 = 0.5米）
    return perimeter * 0.5;
  };

  // 鼠标移动
  const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!canvasRef.current) return;

    const rect = canvasRef.current.getBoundingClientRect();
    const x = (e.clientX - rect.left) / zoomLevel;
    const y = (e.clientY - rect.top) / zoomLevel;

    const point: DrawPoint = { x, y };
    setMousePosition(point);

    // 检查吸附
    const snapPoint = findSnapPoint(point);
    setSnappedPoint(snapPoint);
  };

  // 鼠标点击
  const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (drawMode === 'none') return;

    if (!canvasRef.current) return;

    const rect = canvasRef.current.getBoundingClientRect();
    const x = (e.clientX - rect.left) / zoomLevel;
    const y = (e.clientY - rect.top) / zoomLevel;

    let point: DrawPoint = { x, y };

    // 吸附到已有点
    if (snappedPoint) {
      point = snappedPoint;
    }

    const newPoints = [...currentPoints, point];

    // 多边形：点击起点闭合
    if (drawMode === 'polygon') {
      // 检查是否点击起点（闭合多边形）
      if (currentPoints.length >= 3 && snappedPoint && snappedPoint === currentPoints[0]) {
        // 不添加重复点，直接使用当前点
        return;
      }

      setCurrentPoints(newPoints);
      setIsDrawing(true);
    } else if (drawMode === 'rectangle') {
      if (currentPoints.length === 0) {
        setCurrentPoints([point]);
        setIsDrawing(true);
      } else if (currentPoints.length === 1) {
        // 创建矩形的四个点
        const rectanglePoints = [
          currentPoints[0],
          { x: point.x, y: currentPoints[0].y },
          point,
          { x: currentPoints[0].x, y: point.y }
        ];
        setCurrentPoints(rectanglePoints);
        setIsDrawing(false);
      }
    } else if (drawMode === 'line') {
      setCurrentPoints(newPoints);

      if (newPoints.length >= 2) {
        setIsDrawing(true);
      }
    } else if (drawMode === 'point') {
      setCurrentPoints([point]);
      setIsDrawing(false);
    }
  };

  // 保存到地块档案
  const handleSave = () => {
    // 检查点数
    if (drawMode === 'polygon' && currentPoints.length < 3) {
      toast.error('多边形至少需要3个点');
      return;
    }
    if (drawMode === 'line' && currentPoints.length < 2) {
      toast.error('线至少需要2个点');
      return;
    }
    if (currentPoints.length === 0) {
      toast.error('请先绘制图形');
      return;
    }

    // 计算几何属性
    const area = drawMode === 'polygon' || drawMode === 'rectangle' ? calculateArea(currentPoints) : 0;
    const perimeter = calculatePerimeter(currentPoints);
    const selfIntersects = drawMode === 'polygon' && checkSelfIntersection(currentPoints);

    if (selfIntersects) {
      toast.error('多边形自相交，无法保存');
      return;
    }

    const geometry: DrawGeometry = {
      type: drawMode,
      points: currentPoints,
      area,
      perimeter,
      valid: !selfIntersects
    };

    // 触发保存对话框
    if (onSaveRequest) {
      onSaveRequest(geometry);

      // 清除当前绘制
      setCurrentPoints([]);
      setIsDrawing(false);
      setDrawMode('none');
    }
  };

  // 清除绘制
  const handleClear = () => {
    if (currentPoints.length === 0) {
      toast.info('当前没有绘制内容');
      return;
    }

    if (confirm('确定要清除当前绘制吗？')) {
      setCurrentPoints([]);
      setIsDrawing(false);
      setDrawMode('none');
      toast.success('已清除绘制');
    }
  };

  // 切换绘制模式
  const switchDrawMode = (mode: DrawMode) => {
    if (currentPoints.length > 0) {
      if (!confirm('切换模式将清除当前绘制，是否继续？')) {
        return;
      }
    }

    setDrawMode(mode);
    setCurrentPoints([]);
    setIsDrawing(mode !== 'none');

    const modeNames: Record<DrawMode, string> = {
      none: '查看',
      point: '点',
      line: '线',
      polygon: '多边形',
      rectangle: '矩形',
      circle: '圆形'
    };

    if (mode !== 'none') {
      toast.success(`已切换到${modeNames[mode]}绘制模式`);
    }
  };

  // 检查几何有效性
  const isGeometryValid = (): boolean => {
    if (drawMode === 'polygon' && currentPoints.length >= 3) {
      return !checkSelfIntersection(currentPoints);
    }
    return true;
  };

  return (
    <div className="grid grid-cols-4 gap-6">
      {/* 左侧工具面板 */}
      <div className="space-y-4">
        {/* 绘制工具 */}
        <Card className="p-4 bg-card">
          <h4 className="mb-3">绘制工具</h4>
          <div className="space-y-2">
            <Button
              variant={drawMode === 'none' ? 'default' : 'outline'}
              className="w-full justify-start"
              onClick={() => switchDrawMode('none')}
            >
              <MousePointer className="w-4 h-4 mr-2" />
              选择
            </Button>
            <Button
              variant={drawMode === 'point' ? 'default' : 'outline'}
              className="w-full justify-start"
              onClick={() => switchDrawMode('point')}
            >
              <MapPin className="w-4 h-4 mr-2" />
              点
            </Button>
            <Button
              variant={drawMode === 'line' ? 'default' : 'outline'}
              className="w-full justify-start"
              onClick={() => switchDrawMode('line')}
            >
              <Minus className="w-4 h-4 mr-2" />
              线
            </Button>
            <Button
              variant={drawMode === 'polygon' ? 'default' : 'outline'}
              className="w-full justify-start"
              onClick={() => switchDrawMode('polygon')}
            >
              <Pentagon className="w-4 h-4 mr-2" />
              多边形
            </Button>
            <Button
              variant={drawMode === 'rectangle' ? 'default' : 'outline'}
              className="w-full justify-start"
              onClick={() => switchDrawMode('rectangle')}
            >
              <Square className="w-4 h-4 mr-2" />
              矩形
            </Button>
          </div>
        </Card>

        {/* 操作工具 */}
        <Card className="p-4 bg-card">
          <h4 className="mb-3">操作</h4>
          <div className="space-y-2">
            <Button
              variant="outline"
              className="w-full justify-start"
              onClick={handleUndo}
              disabled={currentPoints.length === 0}
            >
              <Undo className="w-4 h-4 mr-2" />
              撤销上一个点
            </Button>
            <Button
              variant="default"
              className="w-full justify-start bg-green-600 hover:bg-green-700 text-white"
              onClick={handleSave}
              disabled={currentPoints.length === 0}
            >
              <Save className="w-4 h-4 mr-2" />
              保存到地块档案
            </Button>
            <Button
              variant="outline"
              className="w-full justify-start text-destructive hover:text-destructive"
              onClick={handleClear}
            >
              <Trash2 className="w-4 h-4 mr-2" />
              清除
            </Button>
          </div>
        </Card>

        {/* 几何信息 */}
        <Card className="p-4 bg-card">
          <h4 className="mb-3">几何信息</h4>
          <div className="space-y-3 text-sm">
            <div>
              <div className="text-muted-foreground">顶点数</div>
              <div className="mt-1 text-green-600 dark:text-green-400">{currentPoints.length} 个</div>
            </div>
            {(drawMode === 'polygon' || drawMode === 'rectangle') && currentPoints.length >= 3 && (
              <div>
                <div className="text-muted-foreground">面积</div>
                <div className="mt-1 text-green-600 dark:text-green-400">
                  {calculateArea(currentPoints).toFixed(2)} 亩
                </div>
              </div>
            )}
            {currentPoints.length >= 2 && (
              <div>
                <div className="text-muted-foreground">周长</div>
                <div className="mt-1 text-green-600 dark:text-green-400">
                  {calculatePerimeter(currentPoints).toFixed(0)} 米
                </div>
              </div>
            )}
            <div>
              <div className="text-muted-foreground">几何校验</div>
              <div className="mt-1 flex items-center gap-2">
                {isGeometryValid() ? (
                  <>
                    <CheckCircle2 className="w-4 h-4 text-green-600" />
                    <span className="text-green-600">有效</span>
                  </>
                ) : (
                  <>
                    <AlertCircle className="w-4 h-4 text-red-600" />
                    <span className="text-red-600">自相交</span>
                  </>
                )}
              </div>
            </div>
          </div>
        </Card>

        {/* 吸附设置 */}
        <Card className="p-4 bg-card">
          <h4 className="mb-3">设置</h4>
          <div className="space-y-2 text-sm">
            <div className="flex items-center justify-between">
              <span className="text-muted-foreground">吸附</span>
              <Badge variant={enableSnapping ? 'default' : 'secondary'}>
                {enableSnapping ? '开启' : '关闭'}
              </Badge>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-muted-foreground">吸附距离</span>
              <span>{snapDistance}px</span>
            </div>
            <div className="flex items-center justify-between">
              <span className="text-muted-foreground">缩放</span>
              <span>{(zoomLevel * 100).toFixed(0)}%</span>
            </div>
          </div>
        </Card>
      </div>

      {/* 画布区域 */}
      <div className="col-span-3">
        <Card className="p-0 overflow-hidden bg-card" style={{ height: `${canvasHeight}px` }}>
          <div
            ref={canvasRef}
            className="relative w-full h-full bg-muted cursor-crosshair"
            onMouseMove={handleMouseMove}
            onClick={handleClick}
            style={{ transform: `scale(${zoomLevel})`, transformOrigin: 'top left' }}
          >
            {/* 网格背景 */}
            <div className="absolute inset-0" style={{
              backgroundImage: `
                linear-gradient(to right, #e5e7eb 1px, transparent 1px),
                linear-gradient(to bottom, #e5e7eb 1px, transparent 1px)
              `,
              backgroundSize: '20px 20px'
            }} />

            {/* 绘制的点 */}
            {currentPoints.map((point, index) => (
              <div
                key={index}
                className="absolute w-3 h-3 bg-green-600 rounded-full border-2 border-background shadow-lg"
                style={{
                  left: `${point.x - 6}px`,
                  top: `${point.y - 6}px`,
                  zIndex: 10
                }}
              />
            ))}

            {/* 绘制的线 */}
            {currentPoints.length >= 2 && (
              <svg className="absolute inset-0 pointer-events-none" style={{ zIndex: 5 }}>
                {currentPoints.map((point, index) => {
                  if (index === 0) return null;
                  const prev = currentPoints[index - 1];
                  return (
                    <line
                      key={index}
                      x1={prev.x}
                      y1={prev.y}
                      x2={point.x}
                      y2={point.y}
                      stroke="#22c55e"
                      strokeWidth="2"
                    />
                  );
                })}
                {/* 闭合多边形 */}
                {drawMode === 'polygon' && currentPoints.length >= 3 && (
                  <line
                    x1={currentPoints[currentPoints.length - 1].x}
                    y1={currentPoints[currentPoints.length - 1].y}
                    x2={currentPoints[0].x}
                    y2={currentPoints[0].y}
                    stroke="#22c55e"
                    strokeWidth="2"
                    strokeDasharray="5,5"
                  />
                )}
              </svg>
            )}

            {/* 多边形填充 */}
            {(drawMode === 'polygon' || drawMode === 'rectangle') && currentPoints.length >= 3 && (
              <svg className="absolute inset-0 pointer-events-none" style={{ zIndex: 1 }}>
                <polygon
                  points={currentPoints.map(p => `${p.x},${p.y}`).join(' ')}
                  fill="#22c55e"
                  fillOpacity="0.2"
                  stroke="none"
                />
              </svg>
            )}

            {/* 吸附点提示 */}
            {snappedPoint && (
              <div
                className="absolute w-5 h-5 border-2 border-blue-500 rounded-full"
                style={{
                  left: `${snappedPoint.x - 10}px`,
                  top: `${snappedPoint.y - 10}px`,
                  zIndex: 15
                }}
              />
            )}

            {/* 当前模式提示 */}
            {isDrawing && (
              <div className="absolute top-4 left-1/2 transform -translate-x-1/2 pointer-events-none">
                <Card className="px-4 py-2 bg-green-600 text-white border-0">
                  <div className="text-sm">
                    {drawMode === 'polygon' && `已标记 ${currentPoints.length} 个点，点击起点闭合或点击"保存"按钮`}
                    {drawMode === 'rectangle' && (currentPoints.length === 0 ? '点击第一个角点' : '点击对角点完成')}
                    {drawMode === 'line' && `已标记 ${currentPoints.length} 个点，点击"保存"按钮结束`}
                  </div>
                </Card>
              </div>
            )}

            {/* 操作提示 */}
            <div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 pointer-events-none">
              <Card className="px-4 py-2 bg-background/90 border text-xs text-muted-foreground">
                Ctrl+Z:撤销 | Ctrl+S:保存 | Delete:清除 | Esc:取消
              </Card>
            </div>
          </div>
        </Card>
      </div>
    </div>
  );
}