/**
 * 空间数据管理组件
 * 集成PostGIS风格的空间查询、几何计算和数据导出功能
 */

import { useState, useEffect } from 'react';
import { loadAMapScript } from '../../lib/mapLoader';
import { Card } from '../ui/card';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Badge } from '../ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '../ui/dialog';
import { 
  MapPin, 
  Search, 
  Download,
  Calculator,
  Copy,
  FileJson,
  Map as MapIcon,
  Target,
  GitMerge,
  Circle,
  CheckCircle2,
  AlertCircle,
  FileText,
  Database,
  Ruler,
  Plus,
  Trash2,
  MousePointer2,
  Edit3
} from 'lucide-react';
import { toast } from 'sonner@2.0.3';
import {
  SpatialQuery,
  GeometryCalculator,
  DataExporter,
  Field,
  Point,
  Polygon,
  SpatialQueryResult
} from '../../lib/spatialDataService';
import { MapPointPicker } from './MapPointPicker';

export function FieldSpatialQuery() {
  const [queryType, setQueryType] = useState<'point-in-polygon' | 'polygon-intersect' | 'polygon-adjacent' | 'buffer'>('point-in-polygon');
  const [pointLat, setPointLat] = useState('39.9042');
  const [pointLng, setPointLng] = useState('116.4074');
  const [selectedFieldId, setSelectedFieldId] = useState('');
  const [bufferDistance, setBufferDistance] = useState('500');
  const [queryResult, setQueryResult] = useState<any>(null);
  const [isQuerying, setIsQuerying] = useState(false);

  // 几何计算对话框状态
  const [showGeometryDialog, setShowGeometryDialog] = useState(false);
  const [geomCalcType, setGeomCalcType] = useState<'area' | 'perimeter' | 'centroid' | 'distance' | 'bbox'>('area');
  const [geomPoints, setGeomPoints] = useState<Point[]>([
    { lat: 39.9040, lng: 116.4070 },
    { lat: 39.9080, lng: 116.4070 },
    { lat: 39.9080, lng: 116.4120 },
    { lat: 39.9040, lng: 116.4120 },
  ]);
  const [distPoint1, setDistPoint1] = useState<Point>({ lat: 39.9042, lng: 116.4074 });
  const [distPoint2, setDistPoint2] = useState<Point>({ lat: 39.9150, lng: 116.4150 });
  const [geomResult, setGeomResult] = useState<any>(null);
  
  // 地图选点模式
  const [mapPickMode, setMapPickMode] = useState<'polygon' | 'distance-p1' | 'distance-p2' | null>(null);
  const [editingPointIndex, setEditingPointIndex] = useState<number | null>(null);

  // 地图加载状态
  const [isMapLoaded, setIsMapLoaded] = useState(false);

  // 加载高德地图SDK
  useEffect(() => {
    if (typeof window.AMap === 'undefined') {
      loadAMapScript()
        .then(() => {
          setIsMapLoaded(true);
          console.log('✅ 高德地图SDK加载成功');
        })
        .catch((error) => {
          console.error('❌ 高德地图SDK加载失败:', error);
          toast.error('地图加载失败，部分功能可能不可用');
        });
    } else {
      setIsMapLoaded(true);
    }
  }, []);

  // 模拟地块数据（实际应从后端获取）
  const mockFields: Field[] = [
    {
      id: 'field-1',
      name: '东区1号地',
      code: 'DB001',
      geometry: {
        points: [
          { lat: 39.9040, lng: 116.4070 },
          { lat: 39.9080, lng: 116.4070 },
          { lat: 39.9080, lng: 116.4120 },
          { lat: 39.9040, lng: 116.4120 },
        ],
      },
      properties: { crop: '小麦', owner: '张三' },
    },
    {
      id: 'field-2',
      name: '西区2号地',
      code: 'DB002',
      geometry: {
        points: [
          { lat: 39.9045, lng: 116.4120 },
          { lat: 39.9085, lng: 116.4120 },
          { lat: 39.9085, lng: 116.4170 },
          { lat: 39.9045, lng: 116.4170 },
        ],
      },
      properties: { crop: '玉米', owner: '李四' },
    },
    {
      id: 'field-3',
      name: '南区3号地',
      code: 'DB003',
      geometry: {
        points: [
          { lat: 39.9000, lng: 116.4070 },
          { lat: 39.9040, lng: 116.4070 },
          { lat: 39.9040, lng: 116.4120 },
          { lat: 39.9000, lng: 116.4120 },
        ],
      },
      properties: { crop: '水稻', owner: '王五' },
    },
    {
      id: 'field-4',
      name: '北区4号地',
      code: 'DB004',
      geometry: {
        points: [
          { lat: 39.9080, lng: 116.4070 },
          { lat: 39.9120, lng: 116.4070 },
          { lat: 39.9120, lng: 116.4120 },
          { lat: 39.9080, lng: 116.4120 },
        ],
      },
      properties: { crop: '大豆', owner: '赵六' },
    },
  ];

  // 点面查询
  const handlePointInPolygonQuery = () => {
    setIsQuerying(true);
    
    setTimeout(() => {
      const point: Point = {
        lat: parseFloat(pointLat),
        lng: parseFloat(pointLng),
      };

      const result = SpatialQuery.pointInPolygon(point, mockFields);
      
      setQueryResult({
        type: 'point-in-polygon',
        point,
        ...result.data,
        executionTime: result.executionTime,
        timestamp: result.timestamp,
      });
      
      setIsQuerying(false);
      
      if (result.data.matched) {
        toast.success(`查询完成！该点位于 ${result.data.fields[0].field.name} 内 (耗时: ${result.executionTime.toFixed(2)}ms)`);
      } else {
        toast.info('查询完成！该点不在任何地块内');
      }
    }, 100);
  };

  // 面面相交查询
  const handlePolygonIntersectQuery = () => {
    setIsQuerying(true);
    
    setTimeout(() => {
      const sourceField = mockFields.find((f) => f.id === selectedFieldId);
      if (!sourceField) {
        toast.error('请选择地块');
        setIsQuerying(false);
        return;
      }

      const result = SpatialQuery.polygonIntersect(
        sourceField,
        mockFields.filter((f) => f.id !== selectedFieldId)
      );
      
      setQueryResult({
        type: 'polygon-intersect',
        sourceField,
        ...result.data,
        executionTime: result.executionTime,
        timestamp: result.timestamp,
      });
      
      setIsQuerying(false);
      toast.success(`查询完成！发现 ${result.data.intersections.length} 个相交地块 (耗时: ${result.executionTime.toFixed(2)}ms)`);
    }, 100);
  };

  // 相邻地块查询
  const handleAdjacentQuery = () => {
    setIsQuerying(true);
    
    setTimeout(() => {
      const sourceField = mockFields.find((f) => f.id === selectedFieldId);
      if (!sourceField) {
        toast.error('请选择地块');
        setIsQuerying(false);
        return;
      }

      const result = SpatialQuery.adjacentPolygons(
        sourceField,
        mockFields.filter((f) => f.id !== selectedFieldId)
      );
      
      setQueryResult({
        type: 'polygon-adjacent',
        sourceField,
        ...result.data,
        executionTime: result.executionTime,
        timestamp: result.timestamp,
      });
      
      setIsQuerying(false);
      toast.success(`查询完成！发现 ${result.data.adjacentFields.length} 个相邻地块 (耗时: ${result.executionTime.toFixed(2)}ms)`);
    }, 100);
  };

  // 缓冲区分析
  const handleBufferQuery = () => {
    setIsQuerying(true);
    
    setTimeout(() => {
      const sourceField = mockFields.find((f) => f.id === selectedFieldId);
      if (!sourceField) {
        toast.error('请选择地块');
        setIsQuerying(false);
        return;
      }

      const result = SpatialQuery.bufferAnalysis(
        sourceField,
        parseFloat(bufferDistance),
        mockFields.filter((f) => f.id !== selectedFieldId)
      );
      
      setQueryResult({
        type: 'buffer',
        sourceField,
        bufferDistance: parseFloat(bufferDistance),
        ...result.data,
        executionTime: result.executionTime,
        timestamp: result.timestamp,
      });
      
      setIsQuerying(false);
      toast.success(`查询完成！在${bufferDistance}米范围内发现 ${result.data.fieldsInBuffer.length} 个地块 (耗时: ${result.executionTime.toFixed(2)}ms)`);
    }, 100);
  };

  const handleQuery = () => {
    switch (queryType) {
      case 'point-in-polygon':
        handlePointInPolygonQuery();
        break;
      case 'polygon-intersect':
        handlePolygonIntersectQuery();
        break;
      case 'polygon-adjacent':
        handleAdjacentQuery();
        break;
      case 'buffer':
        handleBufferQuery();
        break;
    }
  };

  // 几何计�� - 添加/删除/更新点
  const handleAddGeomPoint = () => {
    setGeomPoints([...geomPoints, { lat: 0, lng: 0 }]);
  };

  const handleRemoveGeomPoint = (index: number) => {
    if (geomPoints.length <= 3) {
      toast.error('至少需要3个点才能形成多边形');
      return;
    }
    setGeomPoints(geomPoints.filter((_, i) => i !== index));
  };

  const handleUpdateGeomPoint = (index: number, field: 'lat' | 'lng', value: string) => {
    const newPoints = [...geomPoints];
    newPoints[index][field] = parseFloat(value) || 0;
    setGeomPoints(newPoints);
  };

  // 几何计算 - 计算面积
  const handleCalculateArea = () => {
    try {
      const polygon: Polygon = { points: geomPoints };
      const areaM2 = GeometryCalculator.calculateArea(polygon);
      const areaMu = areaM2 / 666.67;
      const areaHa = areaM2 / 10000;

      setGeomResult({
        type: 'area',
        areaM2: areaM2.toFixed(2),
        areaMu: areaMu.toFixed(2),
        areaHa: areaHa.toFixed(4),
        timestamp: Date.now()
      });

      toast.success(`计算完成！面积：${areaMu.toFixed(2)} 亩`);
    } catch (error) {
      toast.error('计算失败，请检查坐标点');
    }
  };

  // 几何计算 - 计算周长
  const handleCalculatePerimeter = () => {
    try {
      const polygon: Polygon = { points: geomPoints };
      const perimeter = GeometryCalculator.calculatePerimeter(polygon);
      const perimeterKm = perimeter / 1000;

      setGeomResult({
        type: 'perimeter',
        perimeter: perimeter.toFixed(2),
        perimeterKm: perimeterKm.toFixed(3),
        timestamp: Date.now()
      });

      toast.success(`计算完成！周长：${perimeter.toFixed(2)} 米`);
    } catch (error) {
      toast.error('计算失败，请检查坐标点');
    }
  };

  // 几何计算 - 计算中心点
  const handleCalculateCentroid = () => {
    try {
      const polygon: Polygon = { points: geomPoints };
      const centroid = GeometryCalculator.calculateCentroid(polygon);

      setGeomResult({
        type: 'centroid',
        centroid,
        timestamp: Date.now()
      });

      toast.success(`计算完成！中心点：(${centroid.lat.toFixed(6)}, ${centroid.lng.toFixed(6)})`);
    } catch (error) {
      toast.error('计算失败，请检查坐标点');
    }
  };

  // 几何计算 - 计算距离
  const handleCalculateDistance = () => {
    try {
      const distance = GeometryCalculator.haversineDistance(distPoint1, distPoint2);
      const distanceKm = distance / 1000;

      setGeomResult({
        type: 'distance',
        distance: distance.toFixed(2),
        distanceKm: distanceKm.toFixed(3),
        point1: distPoint1,
        point2: distPoint2,
        timestamp: Date.now()
      });

      toast.success(`计算完成！距离：${distance.toFixed(2)} 米`);
    } catch (error) {
      toast.error('计算失败，请检查坐标点');
    }
  };

  // 几何计算 - 计算包围盒
  const handleCalculateBBox = () => {
    try {
      const polygon: Polygon = { points: geomPoints };
      const bbox = GeometryCalculator.calculateBoundingBox(polygon);

      setGeomResult({
        type: 'bbox',
        bbox,
        timestamp: Date.now()
      });

      toast.success('计算完成！');
    } catch (error) {
      toast.error('计算失败，请检查坐标点');
    }
  };

  // 打开几何计算对话框
  const handleGeometryCalculation = () => {
    setShowGeometryDialog(true);
  };
  
  // 几何计算演示（已废弃，改用对话框）
  const handleGeometryCalculationOld = () => {
    const field = mockFields[0];
    
    const area = GeometryCalculator.calculateArea(field.geometry);
    const perimeter = GeometryCalculator.calculatePerimeter(field.geometry);
    const centroid = GeometryCalculator.calculateCentroid(field.geometry);
    const bbox = GeometryCalculator.calculateBoundingBox(field.geometry);
    
    toast.success(
      `${field.name}:\n` +
      `面积: ${area.toFixed(2)} 亩\n` +
      `周长: ${perimeter.toFixed(0)} 米\n` +
      `中心点: (${centroid.lat.toFixed(6)}, ${centroid.lng.toFixed(6)})\n` +
      `包围盒: [${bbox.minLat.toFixed(4)}, ${bbox.minLng.toFixed(4)}, ${bbox.maxLat.toFixed(4)}, ${bbox.maxLng.toFixed(4)}]`,
      { duration: 5000 }
    );
  };

  // 导出为GeoJSON
  const exportToGeoJSON = () => {
    try {
      const geoJSON = DataExporter.exportToGeoJSON(mockFields);
      DataExporter.downloadFile(
        geoJSON,
        `fields-${Date.now()}.geojson`,
        'application/json'
      );
      toast.success('成功导出为GeoJSON格式');
    } catch (error) {
      toast.error('导出失败');
    }
  };

  // 导出为KML
  const exportToKML = () => {
    try {
      const kml = DataExporter.exportToKML(mockFields);
      DataExporter.downloadFile(
        kml,
        `fields-${Date.now()}.kml`,
        'application/vnd.google-earth.kml+xml'
      );
      toast.success('成功导出为KML格式');
    } catch (error) {
      toast.error('导出失败');
    }
  };

  // 导出为CSV
  const exportToCSV = () => {
    try {
      const csv = DataExporter.exportToCSV(mockFields);
      DataExporter.downloadFile(
        csv,
        `fields-${Date.now()}.csv`,
        'text/csv'
      );
      toast.success('成功导出为CSV格式');
    } catch (error) {
      toast.error('导出失败');
    }
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-green-800">空间数据管理</h2>
          <p className="text-muted-foreground">
            PostGIS风格的空间查询、几何计算与数据导出
          </p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" onClick={handleGeometryCalculation}>
            <Calculator className="w-4 h-4 mr-2" />
            几何计算演示
          </Button>
          <Button
            variant="outline"
            onClick={exportToGeoJSON}
          >
            <FileJson className="w-4 h-4 mr-2" />
            导出GeoJSON
          </Button>
          <Button
            variant="outline"
            onClick={exportToKML}
          >
            <MapIcon className="w-4 h-4 mr-2" />
            导出KML
          </Button>
          <Button
            variant="outline"
            onClick={exportToCSV}
          >
            <FileText className="w-4 h-4 mr-2" />
            导出CSV
          </Button>
        </div>
      </div>

      {/* 数据库信息卡片 */}
      <Card className="p-4 bg-gradient-to-r from-green-50 to-blue-50 border-green-200">
        <div className="flex items-start gap-3">
          <Database className="w-5 h-5 text-green-600 mt-0.5" />
          <div className="flex-1">
            <h4 className="text-green-900 mb-2">空间数据库 (PostGIS风格)</h4>
            <div className="grid grid-cols-4 gap-4 text-sm">
              <div>
                <div className="text-muted-foreground">坐标系统</div>
                <div className="text-green-700">WGS-84 (EPSG:4326)</div>
              </div>
              <div>
                <div className="text-muted-foreground">几何类型</div>
                <div className="text-green-700">Polygon, Point</div>
              </div>
              <div>
                <div className="text-muted-foreground">空间索引</div>
                <div className="text-green-700">R-Tree (启用)</div>
              </div>
              <div>
                <div className="text-muted-foreground">精度算法</div>
                <div className="text-green-700">球面几何 (Haversine)</div>
              </div>
            </div>
          </div>
        </div>
      </Card>

      <Tabs value={queryType} onValueChange={(v) => setQueryType(v as any)}>
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="point-in-polygon">
            <Target className="w-4 h-4 mr-2" />
            点面查询
          </TabsTrigger>
          <TabsTrigger value="polygon-intersect">
            <Copy className="w-4 h-4 mr-2" />
            面面相交
          </TabsTrigger>
          <TabsTrigger value="polygon-adjacent">
            <GitMerge className="w-4 h-4 mr-2" />
            相邻查询
          </TabsTrigger>
          <TabsTrigger value="buffer">
            <Circle className="w-4 h-4 mr-2" />
            缓冲区分析
          </TabsTrigger>
        </TabsList>

        {/* 点面查询 */}
        <TabsContent value="point-in-polygon" className="space-y-4">
          <div className="grid grid-cols-3 gap-6">
            <div className="col-span-2">
              <Card className="p-6">
                <div className="flex items-center gap-2 mb-4">
                  <Target className="w-5 h-5 text-green-600" />
                  <h3>点在面内查询 (ST_Contains)</h3>
                </div>
                <p className="text-sm text-muted-foreground mb-4">
                  输入坐标点，查询该点落在哪个地块内 - 使用射线法（Ray Casting Algorithm）
                </p>

                <div className="space-y-4">
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <Label>纬度 (Latitude)</Label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={pointLat}
                        onChange={(e) => setPointLat(e.target.value)}
                        placeholder="39.9042"
                      />
                    </div>
                    <div>
                      <Label>经度 (Longitude)</Label>
                      <Input
                        type="number"
                        step="0.000001"
                        value={pointLng}
                        onChange={(e) => setPointLng(e.target.value)}
                        placeholder="116.4074"
                      />
                    </div>
                  </div>

                  <Button 
                    onClick={handleQuery}
                    disabled={isQuerying}
                    className="w-full bg-green-600 hover:bg-green-700"
                  >
                    <Search className="w-4 h-4 mr-2" />
                    {isQuerying ? '查询中...' : '执行空间查询'}
                  </Button>
                </div>

                {/* 查询结果 */}
                {queryResult && queryResult.type === 'point-in-polygon' && (
                  <div className="mt-6">
                    {queryResult.matched ? (
                      <div className="p-4 bg-green-50 border border-green-200 rounded-lg">
                        <div className="flex items-start gap-3">
                          <CheckCircle2 className="w-5 h-5 text-green-600 mt-0.5" />
                          <div className="flex-1">
                            <h4 className="text-green-900 mb-2">查询结果</h4>
                            {queryResult.fields.map((item: any, index: number) => (
                              <div key={index} className="space-y-2 text-sm mb-4">
                                <div className="flex justify-between">
                                  <span className="text-muted-foreground">所属地块：</span>
                                  <span className="font-medium">
                                    {item.field.name} ({item.field.code})
                                  </span>
                                </div>
                                <div className="flex justify-between">
                                  <span className="text-muted-foreground">地块面积：</span>
                                  <span className="font-medium">
                                    {GeometryCalculator.calculateArea(item.field.geometry).toFixed(2)} 亩
                                  </span>
                                </div>
                                <div className="flex justify-between">
                                  <span className="text-muted-foreground">距离边界：</span>
                                  <span className="font-medium">{item.distanceToBorder.toFixed(0)} 米</span>
                                </div>
                              </div>
                            ))}
                            <div className="pt-2 border-t border-green-200 text-xs text-muted-foreground">
                              执行时间: {queryResult.executionTime.toFixed(2)}ms | 
                              查询时间: {new Date(queryResult.timestamp).toLocaleString()}
                            </div>
                          </div>
                        </div>
                      </div>
                    ) : (
                      <div className="p-4 bg-gray-50 border border-gray-200 rounded-lg">
                        <div className="flex items-center gap-2 text-muted-foreground">
                          <AlertCircle className="w-5 h-5" />
                          <span>该点不在任何地块内</span>
                        </div>
                      </div>
                    )}
                  </div>
                )}
              </Card>
            </div>

            <div>
              <Card className="p-6">
                <h4 className="mb-4">SQL示例</h4>
                <div className="p-3 bg-gray-900 rounded-md text-xs text-green-400 font-mono">
                  SELECT * FROM fields<br />
                  WHERE ST_Contains(<br />
                  &nbsp;&nbsp;geometry,<br />
                  &nbsp;&nbsp;ST_Point({pointLng}, {pointLat})<br />
                  );
                </div>
                <h4 className="mt-4 mb-2">使用说明</h4>
                <ul className="space-y-1 text-sm text-muted-foreground">
                  <li>• 输入WGS-84坐标系经纬度</li>
                  <li>• 射线法判断点是否在多边形内</li>
                  <li>• 计算点到边界的最短距离</li>
                  <li>• 考虑地球曲率修正</li>
                </ul>
              </Card>
            </div>
          </div>
        </TabsContent>

        {/* 面面相交查询 */}
        <TabsContent value="polygon-intersect" className="space-y-4">
          <div className="grid grid-cols-3 gap-6">
            <div className="col-span-2">
              <Card className="p-6">
                <div className="flex items-center gap-2 mb-4">
                  <Copy className="w-5 h-5 text-blue-600" />
                  <h3>面面相交查询 (ST_Intersects)</h3>
                </div>
                <p className="text-sm text-muted-foreground mb-4">
                  查询与指定地块相交的所有地块 - 使用Sutherland-Hodgman裁剪算法
                </p>

                <div className="space-y-4">
                  <div>
                    <Label>选择地块</Label>
                    <Select value={selectedFieldId} onValueChange={setSelectedFieldId}>
                      <SelectTrigger>
                        <SelectValue placeholder="选择要查询的地块" />
                      </SelectTrigger>
                      <SelectContent>
                        {mockFields.map((field) => (
                          <SelectItem key={field.id} value={field.id}>
                            {field.name} ({field.code})
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  <Button 
                    onClick={handleQuery}
                    disabled={isQuerying || !selectedFieldId}
                    className="w-full bg-blue-600 hover:bg-blue-700"
                  >
                    <Search className="w-4 h-4 mr-2" />
                    {isQuerying ? '查询中...' : '执行空间查询'}
                  </Button>
                </div>

                {/* 查询结果 */}
                {queryResult && queryResult.type === 'polygon-intersect' && (
                  <div className="mt-6 space-y-3">
                    <div className="flex items-center justify-between p-3 bg-blue-50 border border-blue-200 rounded-lg">
                      <span>发现相交地块</span>
                      <Badge className="bg-blue-600">{queryResult.intersections.length} 个</Badge>
                    </div>
                    {queryResult.intersections.length > 0 ? (
                      queryResult.intersections.map((item: any, index: number) => (
                        <div key={index} className="p-4 border rounded-lg">
                          <div className="flex items-center justify-between mb-2">
                            <span className="font-medium">{item.field.name}</span>
                            <Badge variant="outline">{item.field.code}</Badge>
                          </div>
                          <div className="grid grid-cols-2 gap-2 text-sm">
                            <div className="text-muted-foreground">
                              相交面积: <span className="text-foreground font-medium">{item.intersectArea.toFixed(2)} 亩</span>
                            </div>
                            <div className="text-muted-foreground">
                              相交比例: <span className="text-foreground font-medium">{item.intersectRatio.toFixed(1)}%</span>
                            </div>
                          </div>
                        </div>
                      ))
                    ) : (
                      <div className="p-4 bg-gray-50 border border-gray-200 rounded-lg text-center text-muted-foreground">
                        没有发现相交地块
                      </div>
                    )}
                    <div className="text-xs text-muted-foreground">
                      执行时间: {queryResult.executionTime.toFixed(2)}ms
                    </div>
                  </div>
                )}
              </Card>
            </div>

            <div>
              <Card className="p-6">
                <h4 className="mb-4">SQL示例</h4>
                <div className="p-3 bg-gray-900 rounded-md text-xs text-blue-400 font-mono">
                  SELECT f2.*,<br />
                  &nbsp;&nbsp;ST_Area(ST_Intersection(<br />
                  &nbsp;&nbsp;&nbsp;&nbsp;f1.geometry,<br />
                  &nbsp;&nbsp;&nbsp;&nbsp;f2.geometry<br />
                  &nbsp;&nbsp;)) as area<br />
                  FROM fields f2<br />
                  WHERE ST_Intersects(<br />
                  &nbsp;&nbsp;f1.geometry,<br />
                  &nbsp;&nbsp;f2.geometry<br />
                  );
                </div>
                <h4 className="mt-4 mb-2">应用场景</h4>
                <ul className="space-y-1 text-sm text-muted-foreground">
                  <li>• 检测地块边界重叠</li>
                  <li>• 分析土地利用冲突</li>
                  <li>• 计算共享区域面积</li>
                  <li>• 优化地块划分</li>
                </ul>
              </Card>
            </div>
          </div>
        </TabsContent>

        {/* 相邻查询 */}
        <TabsContent value="polygon-adjacent" className="space-y-4">
          <div className="grid grid-cols-3 gap-6">
            <div className="col-span-2">
              <Card className="p-6">
                <div className="flex items-center gap-2 mb-4">
                  <GitMerge className="w-5 h-5 text-purple-600" />
                  <h3>相邻地块查询 (ST_Touches)</h3>
                </div>
                <p className="text-sm text-muted-foreground mb-4">
                  查询与指定地块相邻（共享边界）的所有地块
                </p>

                <div className="space-y-4">
                  <div>
                    <Label>选择地块</Label>
                    <Select value={selectedFieldId} onValueChange={setSelectedFieldId}>
                      <SelectTrigger>
                        <SelectValue placeholder="选择要查询的地块" />
                      </SelectTrigger>
                      <SelectContent>
                        {mockFields.map((field) => (
                          <SelectItem key={field.id} value={field.id}>
                            {field.name} ({field.code})
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  <Button 
                    onClick={handleQuery}
                    disabled={isQuerying || !selectedFieldId}
                    className="w-full bg-purple-600 hover:bg-purple-700"
                  >
                    <Search className="w-4 h-4 mr-2" />
                    {isQuerying ? '查询中...' : '执行空间查询'}
                  </Button>
                </div>

                {/* 查询结果 */}
                {queryResult && queryResult.type === 'polygon-adjacent' && (
                  <div className="mt-6 space-y-3">
                    <div className="flex items-center justify-between p-3 bg-purple-50 border border-purple-200 rounded-lg">
                      <span>发现相邻地块</span>
                      <Badge className="bg-purple-600">{queryResult.adjacentFields.length} 个</Badge>
                    </div>
                    {queryResult.adjacentFields.length > 0 ? (
                      queryResult.adjacentFields.map((item: any, index: number) => (
                        <div key={index} className="p-4 border rounded-lg">
                          <div className="flex items-center justify-between mb-2">
                            <span className="font-medium">{item.field.name}</span>
                            <Badge variant="outline">{item.field.code}</Badge>
                          </div>
                          <div className="text-sm text-muted-foreground">
                            共享边界长度: <span className="text-foreground font-medium">{item.sharedBorderLength.toFixed(0)} 米</span>
                          </div>
                        </div>
                      ))
                    ) : (
                      <div className="p-4 bg-gray-50 border border-gray-200 rounded-lg text-center text-muted-foreground">
                        没有发现相邻地块
                      </div>
                    )}
                    <div className="text-xs text-muted-foreground">
                      执行时间: {queryResult.executionTime.toFixed(2)}ms
                    </div>
                  </div>
                )}
              </Card>
            </div>

            <div>
              <Card className="p-6">
                <h4 className="mb-4">SQL示例</h4>
                <div className="p-3 bg-gray-900 rounded-md text-xs text-purple-400 font-mono">
                  SELECT f2.*<br />
                  FROM fields f2<br />
                  WHERE ST_Touches(<br />
                  &nbsp;&nbsp;f1.geometry,<br />
                  &nbsp;&nbsp;f2.geometry<br />
                  )<br />
                  AND f1.id != f2.id;
                </div>
                <h4 className="mt-4 mb-2">应用场景</h4>
                <ul className="space-y-1 text-sm text-muted-foreground">
                  <li>• 规划连片种植区域</li>
                  <li>• 分析地块连通性</li>
                  <li>• 优��灌溉系统布局</li>
                  <li>• 协调相邻地块作业</li>
                </ul>
              </Card>
            </div>
          </div>
        </TabsContent>

        {/* 缓冲区分析 */}
        <TabsContent value="buffer" className="space-y-4">
          <div className="grid grid-cols-3 gap-6">
            <div className="col-span-2">
              <Card className="p-6">
                <div className="flex items-center gap-2 mb-4">
                  <Circle className="w-5 h-5 text-orange-600" />
                  <h3>缓冲区分析 (ST_Buffer)</h3>
                </div>
                <p className="text-sm text-muted-foreground mb-4">
                  在地块周围生成缓冲区，查询范围内的地块
                </p>

                <div className="space-y-4">
                  <div>
                    <Label>选择地块</Label>
                    <Select value={selectedFieldId} onValueChange={setSelectedFieldId}>
                      <SelectTrigger>
                        <SelectValue placeholder="选择要查询的地块" />
                      </SelectTrigger>
                      <SelectContent>
                        {mockFields.map((field) => (
                          <SelectItem key={field.id} value={field.id}>
                            {field.name} ({field.code})
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  <div>
                    <Label>缓冲区距离（米）</Label>
                    <Input
                      type="number"
                      value={bufferDistance}
                      onChange={(e) => setBufferDistance(e.target.value)}
                      placeholder="500"
                    />
                  </div>

                  <Button 
                    onClick={handleQuery}
                    disabled={isQuerying || !selectedFieldId}
                    className="w-full bg-orange-600 hover:bg-orange-700"
                  >
                    <Search className="w-4 h-4 mr-2" />
                    {isQuerying ? '查询中...' : '执行空间查询'}
                  </Button>
                </div>

                {/* 查询结果 */}
                {queryResult && queryResult.type === 'buffer' && (
                  <div className="mt-6 space-y-3">
                    <div className="grid grid-cols-2 gap-3">
                      <div className="p-3 bg-orange-50 border border-orange-200 rounded-lg">
                        <div className="text-sm text-muted-foreground">缓冲区面积</div>
                        <div className="mt-1 text-orange-600">{queryResult.bufferArea.toFixed(2)} 亩</div>
                      </div>
                      <div className="p-3 bg-orange-50 border border-orange-200 rounded-lg">
                        <div className="text-sm text-muted-foreground">包含地块</div>
                        <div className="mt-1 text-orange-600">{queryResult.fieldsInBuffer.length} 个</div>
                      </div>
                    </div>
                    {queryResult.fieldsInBuffer.length > 0 ? (
                      queryResult.fieldsInBuffer.map((item: any, index: number) => (
                        <div key={index} className="p-4 border rounded-lg">
                          <div className="flex items-center justify-between mb-2">
                            <span className="font-medium">{item.field.name}</span>
                            <Badge variant={item.overlap ? 'default' : 'outline'}>
                              {item.overlap ? '重叠' : '范围内'}
                            </Badge>
                          </div>
                          <div className="text-sm text-muted-foreground">
                            距离: <span className="text-foreground font-medium">{item.distance.toFixed(0)} 米</span>
                          </div>
                        </div>
                      ))
                    ) : (
                      <div className="p-4 bg-gray-50 border border-gray-200 rounded-lg text-center text-muted-foreground">
                        缓冲区内没有其他地块
                      </div>
                    )}
                    <div className="text-xs text-muted-foreground">
                      执行时间: {queryResult.executionTime.toFixed(2)}ms
                    </div>
                  </div>
                )}
              </Card>
            </div>

            <div>
              <Card className="p-6">
                <h4 className="mb-4">SQL示例</h4>
                <div className="p-3 bg-gray-900 rounded-md text-xs text-orange-400 font-mono">
                  SELECT f2.*,<br />
                  &nbsp;&nbsp;ST_Distance(<br />
                  &nbsp;&nbsp;&nbsp;&nbsp;f1.geometry,<br />
                  &nbsp;&nbsp;&nbsp;&nbsp;f2.geometry<br />
                  &nbsp;&nbsp;) as distance<br />
                  FROM fields f2<br />
                  WHERE ST_DWithin(<br />
                  &nbsp;&nbsp;f1.geometry,<br />
                  &nbsp;&nbsp;f2.geometry,<br />
                  &nbsp;&nbsp;{bufferDistance}<br />
                  );
                </div>
                <h4 className="mt-4 mb-2">应用场景</h4>
                <ul className="space-y-1 text-sm text-muted-foreground">
                  <li>• 分析影响范围</li>
                  <li>• 规划防护林带</li>
                  <li>• 评估污染扩散</li>
                  <li>• 设置安全距离</li>
                </ul>
              </Card>
            </div>
          </div>
        </TabsContent>

        {/* 几何计算 */}
        <TabsContent value="geometry" className="space-y-4">
          <Tabs value={geomCalcType} onValueChange={(v) => setGeomCalcType(v as any)}>
            <TabsList className="grid w-full grid-cols-5">
              <TabsTrigger value="area">
                <Calculator className="w-4 h-4 mr-2" />
                面积
              </TabsTrigger>
              <TabsTrigger value="perimeter">
                <Ruler className="w-4 h-4 mr-2" />
                周长
              </TabsTrigger>
              <TabsTrigger value="centroid">
                <MapPin className="w-4 h-4 mr-2" />
                中心点
              </TabsTrigger>
              <TabsTrigger value="distance">
                <MapIcon className="w-4 h-4 mr-2" />
                距离
              </TabsTrigger>
              <TabsTrigger value="bbox">
                <Circle className="w-4 h-4 mr-2" />
                包围盒
              </TabsTrigger>
            </TabsList>

            {/* 面积计算 */}
            <TabsContent value="area" className="space-y-4">
              <Card className="p-6">
                <div className="flex items-center justify-between mb-4">
                  <h3>多边形坐标点</h3>
                  <Button size="sm" onClick={handleAddGeomPoint}>
                    <Plus className="w-4 h-4 mr-2" />
                    添加点
                  </Button>
                </div>
                
                <div className="space-y-3 max-h-96 overflow-y-auto">
                  {geomPoints.map((point, index) => (
                    <div key={index} className="flex items-center gap-2">
                      <Badge variant="outline" className="w-16">
                        点 {index + 1}
                      </Badge>
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lat}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                        placeholder="纬度"
                        className="flex-1"
                      />
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lng}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                        placeholder="经度"
                        className="flex-1"
                      />
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => handleRemoveGeomPoint(index)}
                        disabled={geomPoints.length <= 3}
                      >
                        <Trash2 className="w-4 h-4 text-red-500" />
                      </Button>
                    </div>
                  ))}
                </div>

                <Button 
                  onClick={handleCalculateArea}
                  className="w-full mt-4 bg-green-600 hover:bg-green-700"
                >
                  <Calculator className="w-4 h-4 mr-2" />
                  计算面积 (ST_Area)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'area' && (
                <Card className="p-6 bg-green-50 border-green-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-green-600" />
                    <h3 className="text-green-900">计算结果</h3>
                  </div>
                  <div className="grid grid-cols-3 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">平方米</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaM2}</div>
                      <div className="text-xs text-muted-foreground mt-1">m²</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">亩</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaMu}</div>
                      <div className="text-xs text-muted-foreground mt-1">亩</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">公顷</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaHa}</div>
                      <div className="text-xs text-muted-foreground mt-1">ha</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 周长计算 */}
            <TabsContent value="perimeter" className="space-y-4">
              <Card className="p-6">
                <h3 className="mb-4">多边形坐标点</h3>
                
                <div className="space-y-3 max-h-96 overflow-y-auto">
                  {geomPoints.map((point, index) => (
                    <div key={index} className="flex items-center gap-2">
                      <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lat}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                        placeholder="纬度"
                        className="flex-1"
                      />
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lng}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                        placeholder="经度"
                        className="flex-1"
                      />
                    </div>
                  ))}
                </div>

                <Button 
                  onClick={handleCalculatePerimeter}
                  className="w-full mt-4 bg-blue-600 hover:bg-blue-700"
                >
                  <Ruler className="w-4 h-4 mr-2" />
                  计算周长 (ST_Perimeter)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'perimeter' && (
                <Card className="p-6 bg-blue-50 border-blue-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-blue-600" />
                    <h3 className="text-blue-900">计算结果</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">米</div>
                      <div className="text-2xl text-blue-600 mt-1">{geomResult.perimeter}</div>
                      <div className="text-xs text-muted-foreground mt-1">m</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">千米</div>
                      <div className="text-2xl text-blue-600 mt-1">{geomResult.perimeterKm}</div>
                      <div className="text-xs text-muted-foreground mt-1">km</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 中心点计算 */}
            <TabsContent value="centroid" className="space-y-4">
              <Card className="p-6">
                <h3 className="mb-4">多边形坐标点</h3>
                
                <div className="space-y-3 max-h-96 overflow-y-auto">
                  {geomPoints.map((point, index) => (
                    <div key={index} className="flex items-center gap-2">
                      <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lat}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                        placeholder="纬度"
                        className="flex-1"
                      />
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lng}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                        placeholder="经度"
                        className="flex-1"
                      />
                    </div>
                  ))}
                </div>

                <Button 
                  onClick={handleCalculateCentroid}
                  className="w-full mt-4 bg-purple-600 hover:bg-purple-700"
                >
                  <MapPin className="w-4 h-4 mr-2" />
                  计算中心点 (ST_Centroid)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'centroid' && (
                <Card className="p-6 bg-purple-50 border-purple-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-purple-600" />
                    <h3 className="text-purple-900">几何中心坐标</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">纬度</div>
                      <div className="text-xl text-purple-600 mt-1 font-mono">
                        {geomResult.centroid.lat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">经度</div>
                      <div className="text-xl text-purple-600 mt-1 font-mono">
                        {geomResult.centroid.lng.toFixed(6)}
                      </div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 距离计算 */}
            <TabsContent value="distance" className="space-y-4">
              <Card className="p-6">
                <h3 className="mb-4">两点坐标</h3>
                
                <div className="space-y-4">
                  <div>
                    <div className="mb-2 font-medium">点1坐标</div>
                    <div className="grid grid-cols-2 gap-3">
                      <div>
                        <label className="text-sm text-muted-foreground">纬度</label>
                        <Input
                          type="number"
                          step="0.000001"
                          value={distPoint1.lat}
                          onChange={(e) => setDistPoint1({ ...distPoint1, lat: parseFloat(e.target.value) || 0 })}
                        />
                      </div>
                      <div>
                        <label className="text-sm text-muted-foreground">经度</label>
                        <Input
                          type="number"
                          step="0.000001"
                          value={distPoint1.lng}
                          onChange={(e) => setDistPoint1({ ...distPoint1, lng: parseFloat(e.target.value) || 0 })}
                        />
                      </div>
                    </div>
                  </div>

                  <div>
                    <div className="mb-2 font-medium">点2坐标</div>
                    <div className="grid grid-cols-2 gap-3">
                      <div>
                        <label className="text-sm text-muted-foreground">纬度</label>
                        <Input
                          type="number"
                          step="0.000001"
                          value={distPoint2.lat}
                          onChange={(e) => setDistPoint2({ ...distPoint2, lat: parseFloat(e.target.value) || 0 })}
                        />
                      </div>
                      <div>
                        <label className="text-sm text-muted-foreground">经度</label>
                        <Input
                          type="number"
                          step="0.000001"
                          value={distPoint2.lng}
                          onChange={(e) => setDistPoint2({ ...distPoint2, lng: parseFloat(e.target.value) || 0 })}
                        />
                      </div>
                    </div>
                  </div>
                </div>

                <Button 
                  onClick={handleCalculateDistance}
                  className="w-full mt-4 bg-orange-600 hover:bg-orange-700"
                >
                  <MapIcon className="w-4 h-4 mr-2" />
                  计算距离 (ST_Distance)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'distance' && (
                <Card className="p-6 bg-orange-50 border-orange-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-orange-600" />
                    <h3 className="text-orange-900">两点间距离</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">米</div>
                      <div className="text-2xl text-orange-600 mt-1">{geomResult.distance}</div>
                      <div className="text-xs text-muted-foreground mt-1">m</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">千米</div>
                      <div className="text-2xl text-orange-600 mt-1">{geomResult.distanceKm}</div>
                      <div className="text-xs text-muted-foreground mt-1">km</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 包围盒计算 */}
            <TabsContent value="bbox" className="space-y-4">
              <Card className="p-6">
                <h3 className="mb-4">多边形坐标点</h3>
                
                <div className="space-y-3 max-h-96 overflow-y-auto">
                  {geomPoints.map((point, index) => (
                    <div key={index} className="flex items-center gap-2">
                      <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lat}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                        placeholder="纬度"
                        className="flex-1"
                      />
                      <Input
                        type="number"
                        step="0.000001"
                        value={point.lng}
                        onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                        placeholder="经度"
                        className="flex-1"
                      />
                    </div>
                  ))}
                </div>

                <Button 
                  onClick={handleCalculateBBox}
                  className="w-full mt-4 bg-indigo-600 hover:bg-indigo-700"
                >
                  <Circle className="w-4 h-4 mr-2" />
                  计算包围盒 (ST_Envelope)
                </Button>
              </Card>

              {geomResult && geomResult.type === 'bbox' && (
                <Card className="p-6 bg-indigo-50 border-indigo-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-indigo-600" />
                    <h3 className="text-indigo-900">包围盒坐标</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最小纬度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.minLat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最大纬度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.maxLat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最小经度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.minLng.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最大经度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.maxLng.toFixed(6)}
                      </div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>
          </Tabs>
        </TabsContent>
      </Tabs>

      {/* 几何计算工具说明 */}
      <Card className="p-6">
        <h3 className="mb-4">几何计算工具 (Geometry Functions)</h3>
        <div className="grid grid-cols-4 gap-4">
          <Card className="p-4 bg-green-50">
            <div className="flex items-center gap-2 mb-2">
              <Calculator className="w-4 h-4 text-green-600" />
              <span className="text-sm">ST_Area</span>
            </div>
            <p className="text-xs text-muted-foreground">
              球面几何精确面积计算（L'Huilier定理）
            </p>
          </Card>
          <Card className="p-4 bg-blue-50">
            <div className="flex items-center gap-2 mb-2">
              <MapIcon className="w-4 h-4 text-blue-600" />
              <span className="text-sm">ST_Perimeter</span>
            </div>
            <p className="text-xs text-muted-foreground">
              Haversine公式计算周长
            </p>
          </Card>
          <Card className="p-4 bg-purple-50">
            <div className="flex items-center gap-2 mb-2">
              <MapPin className="w-4 h-4 text-purple-600" />
              <span className="text-sm">ST_Centroid</span>
            </div>
            <p className="text-xs text-muted-foreground">
              计算几何中心坐标
            </p>
          </Card>
          <Card className="p-4 bg-orange-50">
            <div className="flex items-center gap-2 mb-2">
              <FileJson className="w-4 h-4 text-orange-600" />
              <span className="text-sm">ST_AsGeoJSON</span>
            </div>
            <p className="text-xs text-muted-foreground">
              导出为GeoJSON格式
            </p>
          </Card>
        </div>
      </Card>

      {/* 使用说明 */}
      <Card className="p-4 bg-blue-50 border-blue-200">
        <div className="flex gap-2">
          <AlertCircle className="w-5 h-5 text-blue-600 flex-shrink-0" />
          <div className="text-sm text-blue-800">
            <p className="mb-2">空间数据服务API特性：</p>
            <ul className="space-y-1 text-xs">
              <li>• <strong>PostGIS兼容</strong>：提供ST_Contains, ST_Intersects, ST_Touches等函数</li>
              <li>• <strong>精确计算</strong>：考虑地球曲率，使用WGS-84椭球参数</li>
              <li>• <strong>高性能</strong>：R-Tree空间索引，包围盒预筛选</li>
              <li>• <strong>标准格式</strong>：支持GeoJSON、KML、WKT、CSV导出</li>
              <li>• <strong>球面几何</strong>：Haversine距离公式，L'Huilier面积算法</li>
              <li>• <strong>拓扑关系</strong>：点面、面面、相邻、缓冲区等空间关系查询</li>
            </ul>
          </div>
        </div>
      </Card>

      {/* 几何计算对话框 */}
      <Dialog open={showGeometryDialog} onOpenChange={setShowGeometryDialog}>
        <DialogContent className="max-w-6xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>几何计算工具</DialogTitle>
            <DialogDescription>
              精确计算多边形面积、周长、中心点等（考虑地球曲率）
            </DialogDescription>
          </DialogHeader>

          <Tabs value={geomCalcType} onValueChange={(v) => setGeomCalcType(v as any)}>
            <TabsList className="grid w-full grid-cols-5">
              <TabsTrigger value="area">
                <Calculator className="w-4 h-4 mr-2" />
                面积
              </TabsTrigger>
              <TabsTrigger value="perimeter">
                <Ruler className="w-4 h-4 mr-2" />
                周长
              </TabsTrigger>
              <TabsTrigger value="centroid">
                <MapPin className="w-4 h-4 mr-2" />
                中心点
              </TabsTrigger>
              <TabsTrigger value="distance">
                <MapIcon className="w-4 h-4 mr-2" />
                距离
              </TabsTrigger>
              <TabsTrigger value="bbox">
                <Circle className="w-4 h-4 mr-2" />
                包围盒
              </TabsTrigger>
            </TabsList>

            {/* 面积计算 */}
            <TabsContent value="area" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'polygon' ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(mapPickMode === 'polygon' ? null : 'polygon')}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {mapPickMode === 'polygon' ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {mapPickMode === 'polygon' ? (
                <MapPointPicker
                  points={geomPoints}
                  mode="polygon"
                  onPointsChange={setGeomPoints}
                  height="400px"
                  title="在地图上选择多边形顶点"
                />
              ) : (
                <Card className="p-6">
                  <div className="flex items-center justify-between mb-4">
                    <h3>多边形坐标点</h3>
                    <Button size="sm" onClick={handleAddGeomPoint}>
                      <Plus className="w-4 h-4 mr-2" />
                      添加点
                    </Button>
                  </div>
                  
                  <div className="space-y-3 max-h-96 overflow-y-auto">
                    {geomPoints.map((point, index) => (
                      <div key={index} className="flex items-center gap-2">
                        <Badge variant="outline" className="w-16">
                          点 {index + 1}
                        </Badge>
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lat}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                          placeholder="纬度"
                          className="flex-1"
                        />
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lng}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                          placeholder="经度"
                          className="flex-1"
                        />
                        <Button
                          size="sm"
                          variant="ghost"
                          onClick={() => handleRemoveGeomPoint(index)}
                          disabled={geomPoints.length <= 3}
                        >
                          <Trash2 className="w-4 h-4 text-red-500" />
                        </Button>
                      </div>
                    ))}
                  </div>
                </Card>
              )}

              <Button 
                onClick={handleCalculateArea}
                className="w-full bg-green-600 hover:bg-green-700"
              >
                <Calculator className="w-4 h-4 mr-2" />
                计算面积 (ST_Area)
              </Button>

              {geomResult && geomResult.type === 'area' && (
                <Card className="p-6 bg-green-50 border-green-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-green-600" />
                    <h3 className="text-green-900">计算结果</h3>
                  </div>
                  <div className="grid grid-cols-3 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">平方米</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaM2}</div>
                      <div className="text-xs text-muted-foreground mt-1">m²</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">亩</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaMu}</div>
                      <div className="text-xs text-muted-foreground mt-1">亩</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">公顷</div>
                      <div className="text-2xl text-green-600 mt-1">{geomResult.areaHa}</div>
                      <div className="text-xs text-muted-foreground mt-1">ha</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 周长计算 */}
            <TabsContent value="perimeter" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'polygon' ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(mapPickMode === 'polygon' ? null : 'polygon')}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {mapPickMode === 'polygon' ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {mapPickMode === 'polygon' ? (
                <MapPointPicker
                  points={geomPoints}
                  mode="polygon"
                  onPointsChange={setGeomPoints}
                  height="400px"
                  title="在地图上选择多边形顶点"
                />
              ) : (
                <Card className="p-6">
                  <h3 className="mb-4">多边形坐标点</h3>
                
                  <div className="space-y-3 max-h-96 overflow-y-auto">
                    {geomPoints.map((point, index) => (
                      <div key={index} className="flex items-center gap-2">
                        <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lat}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                          placeholder="纬度"
                          className="flex-1"
                        />
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lng}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                          placeholder="经度"
                          className="flex-1"
                        />
                      </div>
                    ))}
                  </div>
                </Card>
              )}

              <Button 
                onClick={handleCalculatePerimeter}
                className="w-full bg-blue-600 hover:bg-blue-700"
              >
                <Ruler className="w-4 h-4 mr-2" />
                计算周长 (ST_Perimeter)
              </Button>

              {geomResult && geomResult.type === 'perimeter' && (
                <Card className="p-6 bg-blue-50 border-blue-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-blue-600" />
                    <h3 className="text-blue-900">计算结果</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">米</div>
                      <div className="text-2xl text-blue-600 mt-1">{geomResult.perimeter}</div>
                      <div className="text-xs text-muted-foreground mt-1">m</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">千米</div>
                      <div className="text-2xl text-blue-600 mt-1">{geomResult.perimeterKm}</div>
                      <div className="text-xs text-muted-foreground mt-1">km</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 中心点计算 */}
            <TabsContent value="centroid" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'polygon' ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(mapPickMode === 'polygon' ? null : 'polygon')}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {mapPickMode === 'polygon' ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {mapPickMode === 'polygon' ? (
                <MapPointPicker
                  points={geomPoints}
                  mode="polygon"
                  onPointsChange={setGeomPoints}
                  height="400px"
                  title="在地图上选择多边形顶点"
                />
              ) : (
                <Card className="p-6">
                  <h3 className="mb-4">多边形坐标点</h3>
                  
                  <div className="space-y-3 max-h-96 overflow-y-auto">
                    {geomPoints.map((point, index) => (
                      <div key={index} className="flex items-center gap-2">
                        <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lat}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                          placeholder="纬度"
                          className="flex-1"
                        />
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lng}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                          placeholder="经度"
                          className="flex-1"
                        />
                      </div>
                    ))}
                  </div>
                </Card>
              )}

              <Button 
                onClick={handleCalculateCentroid}
                className="w-full bg-purple-600 hover:bg-purple-700"
              >
                <MapPin className="w-4 h-4 mr-2" />
                计算中心点 (ST_Centroid)
              </Button>

              {geomResult && geomResult.type === 'centroid' && (
                <Card className="p-6 bg-purple-50 border-purple-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-purple-600" />
                    <h3 className="text-purple-900">几何中心坐标</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">纬度</div>
                      <div className="text-xl text-purple-600 mt-1 font-mono">
                        {geomResult.centroid.lat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">经度</div>
                      <div className="text-xl text-purple-600 mt-1 font-mono">
                        {geomResult.centroid.lng.toFixed(6)}
                      </div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 距离计算 */}
            <TabsContent value="distance" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'distance-p1' || mapPickMode === 'distance-p2' ? 'default' : 'outline'}
                  onClick={() => {
                    if (mapPickMode === 'distance-p1' || mapPickMode === 'distance-p2') {
                      setMapPickMode(null);
                    } else {
                      setMapPickMode('distance-p1');
                    }
                  }}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {(mapPickMode === 'distance-p1' || mapPickMode === 'distance-p2') ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {(mapPickMode === 'distance-p1' || mapPickMode === 'distance-p2') ? (
                <div className="space-y-4">
                  <Card className="p-4 bg-orange-50 border-orange-200">
                    <p className="text-sm text-orange-800">
                      💡 当前模式：选择{mapPickMode === 'distance-p1' ? '点1' : '点2'}坐标
                    </p>
                  </Card>
                  
                  <MapPointPicker
                    points={mapPickMode === 'distance-p1' ? [distPoint1] : [distPoint2]}
                    mode="single"
                    onPointsChange={(points) => {
                      if (points.length > 0) {
                        if (mapPickMode === 'distance-p1') {
                          setDistPoint1(points[0]);
                        } else {
                          setDistPoint2(points[0]);
                        }
                      }
                    }}
                    height="400px"
                    title={`在地图上选择${mapPickMode === 'distance-p1' ? '点1' : '点2'}位置`}
                  />
                  
                  <div className="flex gap-2">
                    <Button
                      variant="outline"
                      className="flex-1"
                      onClick={() => setMapPickMode('distance-p1')}
                      disabled={mapPickMode === 'distance-p1'}
                    >
                      选择点1
                    </Button>
                    <Button
                      variant="outline"
                      className="flex-1"
                      onClick={() => setMapPickMode('distance-p2')}
                      disabled={mapPickMode === 'distance-p2'}
                    >
                      选择点2
                    </Button>
                  </div>
                </div>
              ) : (
                <Card className="p-6">
                  <h3 className="mb-4">两点坐标</h3>
                  
                  <div className="space-y-4">
                    <div>
                      <div className="mb-2 font-medium">点1坐标</div>
                      <div className="grid grid-cols-2 gap-3">
                        <div>
                          <label className="text-sm text-muted-foreground">纬度</label>
                          <Input
                            type="number"
                            step="0.000001"
                            value={distPoint1.lat}
                            onChange={(e) => setDistPoint1({ ...distPoint1, lat: parseFloat(e.target.value) || 0 })}
                          />
                        </div>
                        <div>
                          <label className="text-sm text-muted-foreground">经度</label>
                          <Input
                            type="number"
                            step="0.000001"
                            value={distPoint1.lng}
                            onChange={(e) => setDistPoint1({ ...distPoint1, lng: parseFloat(e.target.value) || 0 })}
                          />
                        </div>
                      </div>
                    </div>

                    <div>
                      <div className="mb-2 font-medium">点2坐标</div>
                      <div className="grid grid-cols-2 gap-3">
                        <div>
                          <label className="text-sm text-muted-foreground">纬度</label>
                          <Input
                            type="number"
                            step="0.000001"
                            value={distPoint2.lat}
                            onChange={(e) => setDistPoint2({ ...distPoint2, lat: parseFloat(e.target.value) || 0 })}
                          />
                        </div>
                        <div>
                          <label className="text-sm text-muted-foreground">经度</label>
                          <Input
                            type="number"
                            step="0.000001"
                            value={distPoint2.lng}
                            onChange={(e) => setDistPoint2({ ...distPoint2, lng: parseFloat(e.target.value) || 0 })}
                          />
                        </div>
                      </div>
                    </div>
                  </div>
                </Card>
              )}

              <Button 
                onClick={handleCalculateDistance}
                className="w-full bg-orange-600 hover:bg-orange-700"
              >
                <MapIcon className="w-4 h-4 mr-2" />
                计算距离 (ST_Distance)
              </Button>

              {geomResult && geomResult.type === 'distance' && (
                <Card className="p-6 bg-orange-50 border-orange-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-orange-600" />
                    <h3 className="text-orange-900">两点间距离</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">米</div>
                      <div className="text-2xl text-orange-600 mt-1">{geomResult.distance}</div>
                      <div className="text-xs text-muted-foreground mt-1">m</div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">千米</div>
                      <div className="text-2xl text-orange-600 mt-1">{geomResult.distanceKm}</div>
                      <div className="text-xs text-muted-foreground mt-1">km</div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>

            {/* 包围盒计算 */}
            <TabsContent value="bbox" className="space-y-4">
              {/* 选择方式切换 */}
              <div className="flex gap-2">
                <Button
                  variant={mapPickMode === 'polygon' ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(mapPickMode === 'polygon' ? null : 'polygon')}
                  className="flex-1"
                >
                  <MousePointer2 className="w-4 h-4 mr-2" />
                  {mapPickMode === 'polygon' ? '正在使用地图选点' : '地图选点'}
                </Button>
                <Button
                  variant={mapPickMode === null ? 'default' : 'outline'}
                  onClick={() => setMapPickMode(null)}
                  className="flex-1"
                >
                  <Edit3 className="w-4 h-4 mr-2" />
                  手动输入坐标
                </Button>
              </div>

              {mapPickMode === 'polygon' ? (
                <MapPointPicker
                  points={geomPoints}
                  mode="polygon"
                  onPointsChange={setGeomPoints}
                  height="400px"
                  title="在地图上选择多边形顶点"
                />
              ) : (
                <Card className="p-6">
                  <h3 className="mb-4">多边形坐标点</h3>
                  
                  <div className="space-y-3 max-h-96 overflow-y-auto">
                    {geomPoints.map((point, index) => (
                      <div key={index} className="flex items-center gap-2">
                        <Badge variant="outline" className="w-16">点 {index + 1}</Badge>
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lat}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lat', e.target.value)}
                          placeholder="纬度"
                          className="flex-1"
                        />
                        <Input
                          type="number"
                          step="0.000001"
                          value={point.lng}
                          onChange={(e) => handleUpdateGeomPoint(index, 'lng', e.target.value)}
                          placeholder="经度"
                          className="flex-1"
                        />
                      </div>
                    ))}
                  </div>
                </Card>
              )}

              <Button 
                onClick={handleCalculateBBox}
                className="w-full bg-indigo-600 hover:bg-indigo-700"
              >
                <Circle className="w-4 h-4 mr-2" />
                计算包围盒 (ST_Envelope)
              </Button>

              {geomResult && geomResult.type === 'bbox' && (
                <Card className="p-6 bg-indigo-50 border-indigo-200">
                  <div className="flex items-center gap-2 mb-4">
                    <CheckCircle2 className="w-5 h-5 text-indigo-600" />
                    <h3 className="text-indigo-900">包围盒坐标</h3>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最小纬度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.minLat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最大纬度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.maxLat.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最小经度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.minLng.toFixed(6)}
                      </div>
                    </div>
                    <div className="p-4 bg-white rounded-lg">
                      <div className="text-sm text-muted-foreground">最大经度</div>
                      <div className="text-lg text-indigo-600 mt-1 font-mono">
                        {geomResult.bbox.maxLng.toFixed(6)}
                      </div>
                    </div>
                  </div>
                </Card>
              )}
            </TabsContent>
          </Tabs>
        </DialogContent>
      </Dialog>
    </div>
  );
}
