import { useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  ZoomIn,
  ZoomOut,
  Maximize,
  Minimize,
  Layers,
  Satellite,
  Grid3x3,
  Mountain,
  MapPin,
  Ruler,
  X
} from 'lucide-react';
import {
  GISMapEngine,
  MapProvider,
  MapLayer,
  Marker,
  Polygon,
  MapPosition
} from '@/lib/gisMapEngine';
import { toast } from 'sonner';

interface BaseMapProps {
  provider?: MapProvider;
  initialCenter?: [number, number];
  initialZoom?: number;
  initialLayer?: MapLayer;
  height?: string;
  showControls?: boolean;
  showLayerSwitcher?: boolean;
  showLegend?: boolean;
  showScale?: boolean;
  showCoordinates?: boolean;
  onMapReady?: (mapEngine: GISMapEngine) => void;
  onLayerChange?: (layer: MapLayer) => void;
  className?: string;
}

export interface BaseMapRef {
  getMapEngine: () => GISMapEngine | null;
  addMarker: (marker: Marker) => void;
  addPolygon: (polygon: Polygon) => void;
  setCenter: (position: MapPosition, zoom?: number) => void;
  setZoom: (zoom: number) => void;
}

export const BaseMap = forwardRef<BaseMapRef, BaseMapProps>(({
  provider = 'leaflet',
  initialCenter = [116.4074, 39.9042],
  initialZoom = 13,
  initialLayer = 'satellite',
  height = '600px',
  showControls = true,
  showLayerSwitcher = true,
  showLegend = false,
  showScale = true,
  showCoordinates = true,
  onMapReady,
  onLayerChange,
  className = '',
}, ref) => {
  const mapContainerRef = useRef<HTMLDivElement>(null);
  const mapEngineRef = useRef<GISMapEngine | null>(null);

  const [mapLayer, setMapLayer] = useState<MapLayer>(initialLayer);
  const [zoomLevel, setZoomLevel] = useState(initialZoom);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [coordinates, setCoordinates] = useState<MapPosition>({
    lng: initialCenter[0],
    lat: initialCenter[1],
  });
  const [measuring, setMeasuring] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  // 暴露给父组件的方法
  useImperativeHandle(ref, () => ({
    getMapEngine: () => mapEngineRef.current,
    addMarker: (marker: Marker) => {
      mapEngineRef.current?.addMarker(marker);
    },
    addPolygon: (polygon: Polygon) => {
      mapEngineRef.current?.addPolygon(polygon);
    },
    setCenter: (position: MapPosition, zoom?: number) => {
      mapEngineRef.current?.setCenter(position, zoom);
    },
    setZoom: (zoom: number) => {
      mapEngineRef.current?.setZoom(zoom);
      setZoomLevel(zoom);
    },
  }));

  useEffect(() => {
    if (!mapContainerRef.current) return;

    const initMap = async () => {
      setIsLoading(true);
      try {
        // 初始化地图引擎
        const mapEngine = new GISMapEngine({
          provider,
          container: mapContainerRef.current!,
          center: initialCenter,
          zoom: initialZoom,
          layer: initialLayer,
        });

        mapEngineRef.current = mapEngine;

        // 通知父组件地图已就绪
        if (onMapReady) {
          onMapReady(mapEngine);
        }
      } catch (error) {
        console.error('地图初始化失败:', error);
      } finally {
        // 延迟设置加载完成，给地图渲染一些时间
        setTimeout(() => setIsLoading(false), 500);
      }
    };

    initMap();

    // 清理
    return () => {
      if (mapEngineRef.current) {
        mapEngineRef.current.destroy();
      }
    };
  }, []);

  const handleLayerChange = (layer: string) => {
    const newLayer = layer as MapLayer;
    setMapLayer(newLayer);
    mapEngineRef.current?.setLayer(newLayer);
    toast.success(`已切换到${getLayerName(newLayer)}`);

    if (onLayerChange) {
      onLayerChange(newLayer);
    }
  };

  const handleZoomIn = () => {
    const newZoom = Math.min(zoomLevel + 1, 18);
    setZoomLevel(newZoom);
    mapEngineRef.current?.setZoom(newZoom);
  };

  const handleZoomOut = () => {
    const newZoom = Math.max(zoomLevel - 1, 1);
    setZoomLevel(newZoom);
    mapEngineRef.current?.setZoom(newZoom);
  };

  const handleFullscreen = () => {
    setIsFullscreen(!isFullscreen);
  };

  const getLayerName = (layer: MapLayer): string => {
    const names: Record<MapLayer, string> = {
      satellite: '卫星影像',
      street: '电子地图',
      terrain: '地形图',
      hybrid: '混合图层',
    };
    return names[layer];
  };

  const getLayerIcon = (layer: MapLayer) => {
    switch (layer) {
      case 'satellite': return <Satellite className="w-4 h-4" />;
      case 'street': return <Grid3x3 className="w-4 h-4" />;
      case 'terrain': return <Mountain className="w-4 h-4" />;
      case 'hybrid': return <Layers className="w-4 h-4" />;
    }
  };

  return (
    <div className={`relative ${className}`}>
      <Card className={`overflow-hidden ${isFullscreen ? 'fixed inset-0 z-50' : ''}`}>
        <div
          ref={mapContainerRef}
          className="relative w-full"
          style={{ height: isFullscreen ? '100vh' : height }}
        >
          {/* 加载提示 */}
          {isLoading && (
            <div className="absolute inset-0 bg-background/80 backdrop-blur-sm flex items-center justify-center z-50">
              <div className="text-center">
                <div className="inline-block animate-spin rounded-full h-12 w-12 border-b-2 border-green-600 mb-4"></div>
                <p className="text-sm text-muted-foreground">正在加载地图...</p>
              </div>
            </div>
          )}

          {/* 顶部工具栏 */}
          <div className="absolute top-4 left-4 right-4 z-10 flex items-center justify-between gap-2">
            {/* 图层指示器 */}
            <Card className="p-2 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
              <div className="flex items-center gap-2">
                {getLayerIcon(mapLayer)}
                <span className="text-sm">{getLayerName(mapLayer)}</span>
              </div>
            </Card>

            {/* 右侧控制按钮 */}
            <div className="flex items-center gap-2">
              {/* 图层切换 */}
              {showLayerSwitcher && (
                <Select value={mapLayer} onValueChange={handleLayerChange}>
                  <SelectTrigger className="w-40 bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="satellite">
                      <div className="flex items-center gap-2">
                        <Satellite className="w-4 h-4" />
                        卫星影像
                      </div>
                    </SelectItem>
                    <SelectItem value="street">
                      <div className="flex items-center gap-2">
                        <Grid3x3 className="w-4 h-4" />
                        电子地图
                      </div>
                    </SelectItem>
                    <SelectItem value="terrain">
                      <div className="flex items-center gap-2">
                        <Mountain className="w-4 h-4" />
                        地形图
                      </div>
                    </SelectItem>
                    <SelectItem value="hybrid">
                      <div className="flex items-center gap-2">
                        <Layers className="w-4 h-4" />
                        混合图层
                      </div>
                    </SelectItem>
                  </SelectContent>
                </Select>
              )}

              {/* 测距工具 */}
              {showControls && (
                <Button
                  variant={measuring ? 'default' : 'outline'}
                  size="sm"
                  onClick={() => setMeasuring(!measuring)}
                  className="bg-white/95 dark:bg-gray-800/95 backdrop-blur"
                >
                  <Ruler className="w-4 h-4" />
                </Button>
              )}

              {/* 全屏切换 */}
              {showControls && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleFullscreen}
                  className="bg-white/95 dark:bg-gray-800/95 backdrop-blur"
                >
                  {isFullscreen ? (
                    <Minimize className="w-4 h-4" />
                  ) : (
                    <Maximize className="w-4 h-4" />
                  )}
                </Button>
              )}

              {/* 全屏模式关闭按钮 */}
              {isFullscreen && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleFullscreen}
                  className="bg-white/95 dark:bg-gray-800/95 backdrop-blur"
                >
                  <X className="w-4 h-4" />
                </Button>
              )}
            </div>
          </div>

          {/* 缩放控制 */}
          {showControls && (
            <div className="absolute top-20 right-4 z-10">
              <Card className="p-2 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                <div className="flex flex-col gap-1">
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={handleZoomIn}
                    disabled={zoomLevel >= 18}
                  >
                    <ZoomIn className="w-4 h-4" />
                  </Button>
                  <div className="text-center text-xs text-muted-foreground py-1 px-2">
                    {zoomLevel}
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={handleZoomOut}
                    disabled={zoomLevel <= 1}
                  >
                    <ZoomOut className="w-4 h-4" />
                  </Button>
                </div>
              </Card>
            </div>
          )}

          {/* 比例尺 */}
          {showScale && (
            <div className="absolute bottom-4 left-4 z-10">
              <Card className="p-2 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                <div className="flex items-center gap-2">
                  <div className="w-24 h-0.5 bg-black dark:bg-white"></div>
                  <span className="text-xs">
                    {Math.round(500 / Math.pow(2, zoomLevel - 13))}m
                  </span>
                </div>
              </Card>
            </div>
          )}

          {/* 坐标显示 */}
          {showCoordinates && (
            <div className="absolute bottom-4 right-4 z-10">
              <Card className="px-3 py-2 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                <div className="text-xs text-muted-foreground flex items-center gap-1">
                  <MapPin className="w-3 h-3" />
                  {coordinates.lat.toFixed(4)}°N, {coordinates.lng.toFixed(4)}°E
                </div>
              </Card>
            </div>
          )}

          {/* 图例 */}
          {showLegend && (
            <div className="absolute top-20 left-4 z-10">
              <Card className="p-3 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                <h4 className="text-sm mb-2">图例</h4>
                <div className="space-y-1.5 text-xs">
                  <div className="flex items-center gap-2">
                    <div className="w-4 h-4 bg-green-500 bg-opacity-30 border-2 border-green-500 rounded"></div>
                    <span>露地种植</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-4 h-4 bg-blue-500 bg-opacity-30 border-2 border-blue-500 rounded"></div>
                    <span>大棚种植</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-4 h-4 bg-orange-500 bg-opacity-30 border-2 border-orange-500 rounded"></div>
                    <span>果园</span>
                  </div>
                </div>
              </Card>
            </div>
          )}

          {/* 测距提示 */}
          {measuring && (
            <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10">
              <Card className="p-4 shadow-lg bg-white/95 dark:bg-gray-800/95 backdrop-blur">
                <div className="text-center">
                  <Ruler className="w-8 h-8 mx-auto mb-2 text-green-600" />
                  <p className="text-sm">点击地图开始测距</p>
                  <p className="text-xs text-muted-foreground mt-1">
                    单击添加节点，双击结束
                  </p>
                </div>
              </Card>
            </div>
          )}
        </div>
      </Card>
    </div>
  );
});

BaseMap.displayName = 'BaseMap';