import { GoogleMap, Marker, useLoadScript } from "@react-google-maps/api";
import Cookies from "js-cookie";
import { useEffect, useState } from "react";
import usePlacesAutocomplete, {
  getGeocode,
  getLatLng,
} from "use-places-autocomplete";
import { GoogleMapsAPI } from "./client-config";
import Geocode from "react-geocode";
import { PlacesCombobox } from "@/components/ui/combobox";

Geocode.setApiKey(GoogleMapsAPI);

export default function Places(props: {
  center: { lat: number; lng: number };
  draggable?: boolean;
  onLocationChange?: (location: string) => void; // Tambahkan onLocationChange
}) {
  const { isLoaded } = useLoadScript({
    googleMapsApiKey: GoogleMapsAPI,
    libraries: ["places"],
    language: "id",
  });

  const { center, draggable, onLocationChange } = props;

  if (!isLoaded) return <div>Loading...</div>;

  return (
    <Map
      lat={center.lat}
      lng={center.lng}
      draggable={draggable}
      onLocationChange={onLocationChange} // Kirimkan properti onLocationChange
    />
  );
}

interface MapProps {
  lat: number;
  lng: number;
  draggable?: boolean;
  onLocationChange?: (location: string) => void; // Tambahkan properti ini
}

function Map(props: MapProps) {
  const containerStyle = {
    width: "100%",
    height: "400px",
  };

  const center = {
    lat: -6.1754,
    lng: 106.8272,
  };

  const [selected, setSelected] = useState<{ lat: number; lng: number } | null>(
    null
  );

  const { lat, lng, draggable, onLocationChange } = props;

  useEffect(() => {
    if (lat !== undefined && lng !== undefined) {
      setSelected({ lat, lng });
      getAddressFromLatLong(lat, lng);
    }
  }, [lat, lng]);

  const onMarkerDragEnd = (e: google.maps.MapMouseEvent) => {
    const lat = e.latLng?.lat() ?? 0;
    const lng = e.latLng?.lng() ?? 0;
    console.log(lat, lng);
    getAddressFromLatLong(lat, lng);
    if (onLocationChange) {
      onLocationChange(`Latitude: ${lat}, Longitude: ${lng}`); // Kirimkan lokasi ke parent melalui onLocationChange
    }
  };

  async function getAddressFromLatLong(lat: number, lng: number) {
    try {
      const response = await Geocode.fromLatLng(lat.toString(), lng.toString());
      const address = response.results[0].formatted_address;
      Cookies.set("map_lat", `${lat}`, { expires: 1 });
      Cookies.set("map_long", `${lng}`, { expires: 1 });
      console.log("Address:", address);
      if (onLocationChange) {
        onLocationChange(address); // Kirimkan alamat jika berhasil
      }
    } catch (error) {
      console.error(error);
    }
  }

  return (
    <>
      <div>
        <PlacesAutocomplete setSelected={setSelected} />
      </div>
      <GoogleMap
        zoom={selected == null ? 10 : 15}
        center={selected == null ? center : selected}
        mapContainerStyle={containerStyle}
      >
        {selected && (
          <Marker
            draggable={draggable}
            position={selected}
            onDragEnd={onMarkerDragEnd}
          />
        )}
      </GoogleMap>
    </>
  );
}

interface PlacesAutocompleteProps {
  setSelected: (coords: { lat: number; lng: number }) => void;
}

function PlacesAutocomplete({ setSelected }: PlacesAutocompleteProps) {
  const {
    ready,
    value,
    setValue,
    suggestions: { status, data },
    clearSuggestions,
  } = usePlacesAutocomplete();

  const handleSelect = async (address: string) => {
    setValue(address, false);
    clearSuggestions();

    try {
      const results = await getGeocode({ address });
      const { lat, lng } = await getLatLng(results[0]);

      setSelected({ lat, lng });
      console.log("Selected Lat/Lng:", { lat, lng });
      Cookies.set("map_lat", `${lat}`, { expires: 1 });
      Cookies.set("map_long", `${lng}`, { expires: 1 });
    } catch (error) {
      console.error("Error fetching coordinates:", error);
    }
  };

  return (
    <PlacesCombobox
      value={value}
      onValueChange={(newValue) => setValue(newValue)}
      onSelect={handleSelect}
      suggestions={data}
      status={status}
      disabled={!ready}
      placeholder="Cari Alamat"
      className="border"
    />
  );
}
