"use client";

import { useState, useCallback } from "react";
import Map, { Marker, NavigationControl } from "react-map-gl/mapbox";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { MapPin, Search, Loader2 } from "lucide-react";
import "mapbox-gl/dist/mapbox-gl.css";

interface LocationPickerProps {
  onLocationSelect: (lat: number, lng: number, address: string) => void;
  initialLat?: number;
  initialLng?: number;
  initialAddress?: string;
}

export function LocationPicker({
  onLocationSelect,
  initialLat,
  initialLng,
  initialAddress,
}: LocationPickerProps) {
  const [marker, setMarker] = useState<{ lat: number; lng: number } | null>(
    initialLat && initialLng ? { lat: initialLat, lng: initialLng } : null
  );
  const [address, setAddress] = useState(initialAddress || "");
  const [isGeocoding, setIsGeocoding] = useState(false);
  const [viewState, setViewState] = useState({
    longitude: initialLng || 8.5417, // Zurich default
    latitude: initialLat || 47.3769,
    zoom: initialLat && initialLng ? 14 : 12,
  });

  const mapboxToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN;

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const handleMapClick = useCallback((event: any) => {
    const { lng, lat } = event.lngLat;
    setMarker({ lat, lng });
    setViewState({
      longitude: lng,
      latitude: lat,
      zoom: 14,
    });
    onLocationSelect(lat, lng, address);
  }, [address, onLocationSelect]);

  const geocodeAddress = async () => {
    if (!address.trim() || !mapboxToken) return;

    setIsGeocoding(true);
    try {
      const encodedAddress = encodeURIComponent(address);
      const response = await fetch(
        `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodedAddress}.json?access_token=${mapboxToken}&proximity=8.5417,47.3769&limit=1`
      );
      
      const data = await response.json();
      
      if (data.features && data.features.length > 0) {
        const [lng, lat] = data.features[0].center;
        const formattedAddress = data.features[0].place_name;
        
        setMarker({ lat, lng });
        setAddress(formattedAddress);
        setViewState({
          longitude: lng,
          latitude: lat,
          zoom: 14,
        });
        onLocationSelect(lat, lng, formattedAddress);
      }
    } catch (error) {
      console.error("Geocoding error:", error);
    } finally {
      setIsGeocoding(false);
    }
  };

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === "Enter") {
      e.preventDefault();
      geocodeAddress();
    }
  };

  if (!mapboxToken) {
    return (
      <div className="space-y-4">
        <div>
          <Label htmlFor="location-search">Meeting Point Address</Label>
          <Input
            id="location-search"
            placeholder="e.g., Zurich HB, Bahnhofstrasse 1, Zurich"
            value={address}
            onChange={(e) => setAddress(e.target.value)}
          />
          <p className="text-xs text-muted-foreground mt-1">
            Map integration requires Mapbox configuration
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <div>
        <Label htmlFor="location-search">Search Meeting Point</Label>
        <div className="flex gap-2">
          <Input
            id="location-search"
            placeholder="e.g., Zurich HB, Bahnhofstrasse 1, Zurich"
            value={address}
            onChange={(e) => setAddress(e.target.value)}
            onKeyPress={handleKeyPress}
          />
          <Button
            type="button"
            variant="outline"
            onClick={geocodeAddress}
            disabled={!address.trim() || isGeocoding}
          >
            {isGeocoding ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Search className="h-4 w-4" />
            )}
          </Button>
        </div>
        <p className="text-xs text-muted-foreground mt-1">
          Search for an address or click on the map to set the meeting point
        </p>
      </div>

      <div className="h-[350px] rounded-lg overflow-hidden border">
        <Map
          initialViewState={{
            longitude: viewState.longitude,
            latitude: viewState.latitude,
            zoom: viewState.zoom,
          }}
          style={{ width: '100%', height: '100%' }}
          onClick={handleMapClick}
          mapStyle="mapbox://styles/mapbox/streets-v12"
          mapboxAccessToken={mapboxToken}
          cursor="crosshair"
        >
          <NavigationControl />
          
          {marker && (
            <Marker longitude={marker.lng} latitude={marker.lat}>
              <MapPin className="w-8 h-8 text-red-500 fill-red-500 drop-shadow-lg" />
            </Marker>
          )}
        </Map>
      </div>

      {marker && (
        <div className="text-sm text-muted-foreground bg-muted p-2 rounded">
          <strong>Selected location:</strong> {marker.lat.toFixed(6)}, {marker.lng.toFixed(6)}
        </div>
      )}
    </div>
  );
}
