'use client';

import { useState, useRef, useEffect } from 'react';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card } from '@/components/ui/card';
import { SpatialQueryState, SpatialQueryAction } from './spatialQueryReducer';
import {
  MapPin,
  Shapes,
  MousePointer,
  RefreshCw,
  Check,
  X,
  Navigation
} from 'lucide-react';

interface MapPickerProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  mode: 'point' | 'polygon';
  state: SpatialQueryState;
  dispatch: React.Dispatch<SpatialQueryAction>;
  onConfirm: (result: { lat: number; lng: number } | number[][]) => void;
}

export function MapPicker({
  open,
  onOpenChange,
  mode,
  state,
  dispatch,
  onConfirm
}: MapPickerProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [currentPoint, setCurrentPoint] = useState<{ lat: number; lng: number } | null>(null);
  const [polygonPoints, setPolygonPoints] = useState<number[][]>([]);
  const [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [mapOffset, setMapOffset] = useState({ x: 0, y: 0 });
  const [mapScale, setMapScale] = useState(1);

  // 模拟地图中心坐标（北京天安门）
  const mapCenter = { lat: 39.9042, lng: 116.4074 };
  const mapBounds = {
    north: 39.9100,
    south: 39.8984,
    east: 116.4200,
    west: 116.3948
  };

  useEffect(() => {
    if (open && canvasRef.current) {
      drawMap();
    }
  }, [open, currentPoint, polygonPoints, mousePos, mapOffset, mapScale]);

  const drawMap = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const width = canvas.width;
    const height = canvas.height;

    // 清空画布
    ctx.fillStyle = '#f3f4f6';
    ctx.fillRect(0, 0, width, height);

    // 保存变换状态
    ctx.save();

    // 应用偏移和缩放
    ctx.translate(mapOffset.x, mapOffset.y);
    ctx.scale(mapScale, mapScale);

    // 绘制网格背景
    drawGrid(ctx, width, height);

    // 绘制模拟地块
    drawMockFields(ctx, width, height);

    // 绘制查询几何图形
    if (mode === 'point' && currentPoint) {
      drawPoint(ctx, currentPoint, width, height);
    }

    if (mode === 'polygon' && polygonPoints.length > 0) {
      drawPolygon(ctx, polygonPoints, width, height);
    }

    // 绘制鼠标预览
    if (mousePos && mode === 'polygon' && isDrawing) {
      drawPolygonPreview(ctx, polygonPoints, mousePos, width, height);
    }

    // 恢复变换状态
    ctx.restore();

    // 绘制UI元素（不受变换影响）
    drawUIElements(ctx, width, height);
  };

  const drawGrid = (ctx: CanvasRenderingContext2D, width: number, height: number) => {
    ctx.strokeStyle = '#e5e7eb';
    ctx.lineWidth = 1;

    const gridSize = 50 * mapScale;
    const startX = (mapOffset.x % gridSize + gridSize) % gridSize;
    const startY = (mapOffset.y % gridSize + gridSize) % gridSize;

    for (let x = startX; x < width; x += gridSize) {
      ctx.beginPath();
      ctx.moveTo(x, 0);
      ctx.lineTo(x, height);
      ctx.stroke();
    }

    for (let y = startY; y < height; y += gridSize) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(width, y);
      ctx.stroke();
    }
  };

  const drawMockFields = (ctx: CanvasRenderingContext2D, width: number, height: number) => {
    // 模拟3个地块的位置和形状
    const fields = [
      {
        points: [[100, 100], [200, 100], [200, 180], [100, 180]],
        color: '#22c55e',
        name: '东区沙质土试验田'
      },
      {
        points: [[250, 120], [350, 120], [350, 200], [250, 200]],
        color: '#3b82f6',
        name: '西区黏质土示范区'
      },
      {
        points: [[150, 250], [250, 250], [250, 330], [150, 330]],
        color: '#f97316',
        name: '南区壤质土生产基地'
      }
    ];

    fields.forEach(field => {
      // 绘制地块多边形
      ctx.fillStyle = field.color + '30';
      ctx.strokeStyle = field.color;
      ctx.lineWidth = 2;

      ctx.beginPath();
      ctx.moveTo(field.points[0][0], field.points[0][1]);
      field.points.forEach(point => {
        ctx.lineTo(point[0], point[1]);
      });
      ctx.closePath();
      ctx.fill();
      ctx.stroke();

      // 绘制地块名称
      ctx.fillStyle = '#1f2937';
      ctx.font = '12px sans-serif';
      ctx.textAlign = 'center';
      const centerX = field.points.reduce((sum, p) => sum + p[0], 0) / field.points.length;
      const centerY = field.points.reduce((sum, p) => sum + p[1], 0) / field.points.length;
      ctx.fillText(field.name, centerX, centerY);
    });
  };

  const drawPoint = (ctx: CanvasRenderingContext2D, point: { lat: number; lng: number }, width: number, height: number) => {
    const canvasCoords = latLngToCanvas(point.lat, point.lng, width, height);

    // 绘制点
    ctx.fillStyle = '#ef4444';
    ctx.strokeStyle = '#ffffff';
    ctx.lineWidth = 2;

    ctx.beginPath();
    ctx.arc(canvasCoords.x, canvasCoords.y, 8, 0, 2 * Math.PI);
    ctx.fill();
    ctx.stroke();

    // 绘制中心点
    ctx.fillStyle = '#ffffff';
    ctx.beginPath();
    ctx.arc(canvasCoords.x, canvasCoords.y, 2, 0, 2 * Math.PI);
    ctx.fill();
  };

  const drawPolygon = (ctx: CanvasRenderingContext2D, points: number[][], width: number, height: number) => {
    if (points.length === 0) return;

    ctx.fillStyle = '#3b82f630';
    ctx.strokeStyle = '#3b82f6';
    ctx.lineWidth = 2;

    ctx.beginPath();
    ctx.moveTo(points[0][0], points[0][1]);
    points.forEach(point => {
      ctx.lineTo(point[0], point[1]);
    });
    if (points.length > 2) {
      ctx.closePath();
      ctx.fill();
    }
    ctx.stroke();

    // 绘制顶点
    points.forEach((point, index) => {
      ctx.fillStyle = '#3b82f6';
      ctx.strokeStyle = '#ffffff';
      ctx.lineWidth = 2;

      ctx.beginPath();
      ctx.arc(point[0], point[1], 5, 0, 2 * Math.PI);
      ctx.fill();
      ctx.stroke();

      // 绘制顶点编号
      ctx.fillStyle = '#1f2937';
      ctx.font = '10px sans-serif';
      ctx.textAlign = 'center';
      ctx.fillText((index + 1).toString(), point[0], point[1] - 10);
    });
  };

  const drawPolygonPreview = (ctx: CanvasRenderingContext2D, points: number[][], mousePos: { x: number; y: number }, width: number, height: number) => {
    if (points.length === 0) return;

    ctx.strokeStyle = '#3b82f680';
    ctx.lineWidth = 1;
    ctx.setLineDash([5, 5]);

    ctx.beginPath();
    if (points.length > 0) {
      ctx.moveTo(points[points.length - 1][0], points[points.length - 1][1]);
      ctx.lineTo(mousePos.x, mousePos.y);
    }
    ctx.stroke();

    ctx.setLineDash([]);
  };

  const drawUIElements = (ctx: CanvasRenderingContext2D, width: number, height: number) => {
    // 绘制坐标信息
    if (mousePos) {
      const latLng = canvasToLatLng(mousePos.x, mousePos.y, width, height);
      ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
      ctx.fillRect(mousePos.x + 10, mousePos.y - 30, 120, 25);
      ctx.fillStyle = '#ffffff';
      ctx.font = '12px sans-serif';
      ctx.textAlign = 'left';
      ctx.fillText(`${latLng.lat.toFixed(4)}, ${latLng.lng.toFixed(4)}`, mousePos.x + 15, mousePos.y - 15);
    }

    // 绘制操作提示
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(10, 10, 200, 60);
    ctx.fillStyle = '#ffffff';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'left';

    let instructions = '';
    if (mode === 'point') {
      instructions = '单击地图选择查询点\n滚轮缩放，拖拽移动地图';
    } else {
      instructions = `单击添加多边形顶点 (${polygonPoints.length}个)\n右键完成绘制，滚轮缩放，拖拽移动`;
    }

    instructions.split('\n').forEach((line, index) => {
      ctx.fillText(line, 15, 30 + index * 15);
    });
  };

  const latLngToCanvas = (lat: number, lng: number, width: number, height: number) => {
    const x = ((lng - mapBounds.west) / (mapBounds.east - mapBounds.west)) * width;
    const y = ((mapBounds.north - lat) / (mapBounds.north - mapBounds.south)) * height;
    return { x, y };
  };

  const canvasToLatLng = (x: number, y: number, width: number, height: number) => {
    const lng = (x / width) * (mapBounds.east - mapBounds.west) + mapBounds.west;
    const lat = mapBounds.north - (y / height) * (mapBounds.north - mapBounds.south);
    return { lat, lng };
  };

  const handleCanvasClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    const latLng = canvasToLatLng(x, y, canvas.width, canvas.height);

    if (mode === 'point') {
      setCurrentPoint(latLng);
    } else if (mode === 'polygon') {
      if (e.button === 0) { // 左键添加顶点
        setPolygonPoints([...polygonPoints, [x, y]]);
        setIsDrawing(true);
      }
    }
  };

  const handleCanvasRightClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
    e.preventDefault();
    if (mode === 'polygon' && polygonPoints.length >= 3) {
      // 完成多边形绘制
      setIsDrawing(false);
    }
  };

  const handleCanvasMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    setMousePos({ x, y });

    if (isDragging) {
      setMapOffset({
        x: x - (mousePos?.x || 0),
        y: y - (mousePos?.y || 0)
      });
    }
  };

  const handleCanvasMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (e.button === 1 || (e.button === 0 && e.shiftKey)) { // 中键或Shift+左键拖拽
      e.preventDefault();
      setIsDragging(true);
    }
  };

  const handleCanvasMouseUp = () => {
    setIsDragging(false);
  };

  const handleCanvasWheel = (e: React.WheelEvent<HTMLCanvasElement>) => {
    e.preventDefault();
    const delta = e.deltaY > 0 ? 0.9 : 1.1;
    setMapScale(prev => Math.max(0.5, Math.min(3, prev * delta)));
  };

  const handleConfirm = () => {
    if (mode === 'point' && currentPoint) {
      onConfirm(currentPoint);
    } else if (mode === 'polygon' && polygonPoints.length >= 3) {
      // 转换为坐标数组
      const coordinates = polygonPoints.map(point => {
        const latLng = canvasToLatLng(point[0], point[1], 600, 400);
        return [latLng.lng, latLng.lat];
      });
      onConfirm(coordinates);
    }
  };

  const handleReset = () => {
    setCurrentPoint(null);
    setPolygonPoints([]);
    setIsDrawing(false);
    setMapOffset({ x: 0, y: 0 });
    setMapScale(1);
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            {mode === 'point' ? (
              <>
                <MapPin className="w-5 h-5" />
                选择查询点
              </>
            ) : (
              <>
                <Shapes className="w-5 h-5" />
                绘制查询多边形
              </>
            )}
          </DialogTitle>
          <DialogDescription>
            {mode === 'point'
              ? '在地图上单击选择空间查询的参考点'
              : '在地图上绘制多边形用于空间查询（至少3个顶点）'
            }
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-4">
          {/* 状态信息 */}
          <Card className="p-3 bg-muted/50">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-4 text-sm">
                <Badge variant="outline">
                  {mode === 'point' ? '点选择模式' : '多边形绘制模式'}
                </Badge>
                {mode === 'point' && currentPoint && (
                  <span className="text-muted-foreground">
                    已选择: {currentPoint.lat.toFixed(4)}, {currentPoint.lng.toFixed(4)}
                  </span>
                )}
                {mode === 'polygon' && (
                  <span className="text-muted-foreground">
                    顶点数: {polygonPoints.length}
                    {polygonPoints.length >= 3 && ' (可完成绘制)'}
                  </span>
                )}
              </div>
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <Navigation className="w-4 h-4" />
                缩放: {(mapScale * 100).toFixed(0)}%
              </div>
            </div>
          </Card>

          {/* 地图画布 */}
          <div className="border rounded-lg overflow-hidden">
            <canvas
              ref={canvasRef}
              width={600}
              height={400}
              className="w-full cursor-crosshair"
              onClick={handleCanvasClick}
              onContextMenu={handleCanvasRightClick}
              onMouseMove={handleCanvasMouseMove}
              onMouseDown={handleCanvasMouseDown}
              onMouseUp={handleCanvasMouseUp}
              onWheel={handleCanvasWheel}
              style={{ cursor: isDragging ? 'grabbing' : 'crosshair' }}
            />
          </div>

          {/* 操作说明 */}
          <Card className="p-4 bg-blue-50 dark:bg-blue-950 border-blue-200 dark:border-blue-800">
            <h4 className="font-medium text-blue-800 dark:text-blue-200 mb-2">操作说明</h4>
            <div className="text-sm text-blue-700 dark:text-blue-300 space-y-1">
              {mode === 'point' ? (
                <>
                  <div>• 单击地图选择查询点位置</div>
                  <div>• 使用鼠标滚轮缩放地图</div>
                  <div>• 按住Shift+左键或中键拖拽移动地图</div>
                </>
              ) : (
                <>
                  <div>• 左键单击添加多边形顶点</div>
                  <div>• 右键完成多边形绘制（至少3个顶点）</div>
                  <div>• 使用鼠标滚轮缩放地图</div>
                  <div>• 按住Shift+左键或中键拖拽移动地图</div>
                </>
              )}
            </div>
          </Card>
        </div>

        <DialogFooter className="flex gap-2">
          <Button variant="outline" onClick={handleReset}>
            <RefreshCw className="w-4 h-4 mr-2" />
            重置
          </Button>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            <X className="w-4 h-4 mr-2" />
            取消
          </Button>
          <Button
            onClick={handleConfirm}
            disabled={
              (mode === 'point' && !currentPoint) ||
              (mode === 'polygon' && polygonPoints.length < 3)
            }
            className="bg-green-600 hover:bg-green-700"
          >
            <Check className="w-4 h-4 mr-2" />
            确认选择
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}