import { useEffect, useRef, useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { OrderWithDetails } from '@shared/schema';
import { MAP_CONFIG } from '@/lib/constants';
import { MapPin, RotateCcw, Phone } from 'lucide-react';

interface MapTrackerProps {
  order: OrderWithDetails;
  className?: string;
}

export function MapTracker({ order, className }: MapTrackerProps) {
  const mapRef = useRef<HTMLDivElement>(null);
  const [mapInstance, setMapInstance] = useState<any>(null);
  const [lastUpdate, setLastUpdate] = useState<Date>(new Date());

  useEffect(() => {
    // Initialize Leaflet map when component mounts
    const initMap = async () => {
      if (!mapRef.current || mapInstance) return;

      try {
        // Dynamically import Leaflet to avoid SSR issues
        const L = await import('leaflet');
        
        // Fix default markers
        delete (L.Icon.Default.prototype as any)._getIconUrl;
        L.Icon.Default.mergeOptions({
          iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
          iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
          shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
        });

        const map = L.map(mapRef.current).setView(
          [parseFloat(order.clientLat), parseFloat(order.clientLng)],
          MAP_CONFIG.DEFAULT_ZOOM
        );

        L.tileLayer(MAP_CONFIG.TILE_URL, {
          attribution: MAP_CONFIG.ATTRIBUTION,
        }).addTo(map);

        // Add markers
        const clientIcon = L.divIcon({
          html: '<div class="bg-green-500 w-4 h-4 rounded-full border-2 border-white shadow-lg"></div>',
          className: 'custom-div-icon',
          iconSize: [16, 16],
          iconAnchor: [8, 8]
        });

        const pharmacyIcon = L.divIcon({
          html: '<div class="bg-red-500 w-4 h-4 rounded-full border-2 border-white shadow-lg"></div>',
          className: 'custom-div-icon',
          iconSize: [16, 16],
          iconAnchor: [8, 8]
        });

        const courierIcon = L.divIcon({
          html: '<div class="bg-yellow-500 w-4 h-4 rounded-full border-2 border-white shadow-lg animate-pulse"></div>',
          className: 'custom-div-icon',
          iconSize: [16, 16],
          iconAnchor: [8, 8]
        });

        // Client location
        L.marker([parseFloat(order.clientLat), parseFloat(order.clientLng)], { icon: clientIcon })
          .addTo(map)
          .bindPopup(`
            <div class="text-center">
              <strong>Destination</strong><br>
              ${order.clientAddress}<br>
              <small>${order.clientPhone}</small>
            </div>
          `);

        // Pharmacy location
        if (order.pharmacy) {
          L.marker([parseFloat(order.pharmacy.lat), parseFloat(order.pharmacy.lng)], { icon: pharmacyIcon })
            .addTo(map)
            .bindPopup(`
              <div class="text-center">
                <strong>Pharmacie</strong><br>
                ${order.pharmacy.name}<br>
                ${order.pharmacy.address}
              </div>
            `);
        }

        // Courier location (simulated - in real app would come from GPS)
        if (order.courier && order.pharmacy) {
          // Simulate courier position between pharmacy and client
          const courierLat = (parseFloat(order.pharmacy.lat) + parseFloat(order.clientLat)) / 2;
          const courierLng = (parseFloat(order.pharmacy.lng) + parseFloat(order.clientLng)) / 2;
          
          L.marker([courierLat, courierLng], { icon: courierIcon })
            .addTo(map)
            .bindPopup(`
              <div class="text-center">
                <strong>Livreur</strong><br>
                ${order.courier.user.name}<br>
                <small>Position mise à jour: ${lastUpdate.toLocaleTimeString()}</small>
              </div>
            `);

          // Draw route line
          const routePoints = [
            [parseFloat(order.pharmacy.lat), parseFloat(order.pharmacy.lng)],
            [courierLat, courierLng],
            [parseFloat(order.clientLat), parseFloat(order.clientLng)]
          ];

          L.polyline(routePoints as any, {
            color: '#3b82f6',
            weight: 4,
            opacity: 0.7,
            dashArray: '10, 5'
          }).addTo(map);
        }

        setMapInstance(map);
      } catch (error) {
        console.error('Error initializing map:', error);
      }
    };

    initMap();

    return () => {
      if (mapInstance) {
        mapInstance.remove();
        setMapInstance(null);
      }
    };
  }, [order, mapInstance]);

  const refreshMap = () => {
    setLastUpdate(new Date());
    // In a real application, this would fetch updated courier position
    // and update the map markers accordingly
  };

  const estimatedArrival = () => {
    // Simple estimation based on status
    if (order.status === 'DELIVERED') return 'Livré';
    if (order.status === 'PICKED_UP') return '8 min';
    if (order.status === 'COURIER_ASSIGNED') return '15 min';
    return 'Calcul...';
  };

  return (
    <div className={className}>
      <Card data-testid="map-tracker">
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle className="flex items-center gap-2">
            <MapPin className="h-5 w-5 text-primary" />
            Carte de suivi
          </CardTitle>
          <div className="flex items-center gap-2">
            <Badge 
              variant={order.status === 'DELIVERED' ? 'default' : 'secondary'}
              className={
                order.status === 'PICKED_UP' ? 'bg-yellow-500 text-white' :
                order.status === 'DELIVERED' ? 'bg-green-500 text-white' :
                'bg-blue-500 text-white'
              }
            >
              {order.status}
            </Badge>
            <Button 
              variant="outline" 
              size="sm" 
              onClick={refreshMap}
              data-testid="button-refresh-map"
            >
              <RotateCcw className="h-4 w-4" />
            </Button>
          </div>
        </CardHeader>
        
        <CardContent className="p-0">
          {/* Map Container */}
          <div 
            ref={mapRef} 
            className="h-96 w-full relative"
            data-testid="map-container"
          >
            {/* Fallback when Leaflet is loading */}
            <div className="absolute inset-0 flex items-center justify-center bg-gray-50">
              <div className="text-center text-muted-foreground">
                <MapPin className="h-12 w-12 mx-auto mb-4 opacity-50" />
                <h3 className="text-lg font-medium mb-2">Carte interactive</h3>
                <p className="text-sm mb-4">Position du livreur en temps réel</p>
                
                {/* Legend */}
                <div className="flex items-center justify-center gap-4 text-xs">
                  <div className="flex items-center gap-1">
                    <div className="w-3 h-3 bg-red-500 rounded-full"></div>
                    <span>Pharmacie</span>
                  </div>
                  <div className="flex items-center gap-1">
                    <div className="w-3 h-3 bg-yellow-500 rounded-full animate-pulse"></div>
                    <span>Livreur</span>
                  </div>
                  <div className="flex items-center gap-1">
                    <div className="w-3 h-3 bg-green-500 rounded-full"></div>
                    <span>Destination</span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {/* Map Controls */}
          <div className="p-4 border-t bg-muted/20">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-4">
                <div className="text-sm text-muted-foreground">
                  Dernière mise à jour: {lastUpdate.toLocaleTimeString()}
                </div>
                <div className="flex items-center gap-2">
                  <div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
                  <span className="text-sm">En temps réel</span>
                </div>
              </div>
              
              {order.courier && (
                <Button 
                  variant="outline" 
                  size="sm"
                  data-testid="button-call-courier"
                >
                  <Phone className="h-4 w-4 mr-2" />
                  Appeler le livreur
                </Button>
              )}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* ETA Card */}
      <Card className="mt-4" data-testid="eta-card">
        <CardContent className="text-center p-6">
          <div className="mb-4">
            <div className="text-3xl font-bold text-primary mb-2">
              {estimatedArrival()}
            </div>
            <p className="text-muted-foreground">Temps estimé d'arrivée</p>
          </div>
          
          <div className="text-xs text-muted-foreground">
            Distance: {order.distanceKm ? `${order.distanceKm} km` : 'Calcul...'}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
