import { useMapsLibrary } from "@vis.gl/react-google-maps";
import { useState, useEffect, Dispatch, SetStateAction } from "react";
import {
  UseFormGetValues,
  UseFormRegister,
  FieldErrors,
} from "react-hook-form";
import { Place } from "../../../data/datasource/api/entities/place";
import { Position } from "../map/map_google";
import "./assets/css/styles.css";

// Define the props interface for the component
interface props {
  getValues: UseFormGetValues<Place>;
  register: UseFormRegister<Place>;
  errors: FieldErrors<Place>;
  setPosition: Dispatch<SetStateAction<Position | null>>;
  setLoading: Dispatch<SetStateAction<boolean>>;
}

// GeocodingGoogle component
export const GeocodingGoogle = ({
  getValues,
  register,
  errors,
  setPosition,
  setLoading,
}: props) => {
  // Load the geocoding API from Google Maps
  const geocodingApiLoaded = useMapsLibrary("geocoding");
  // State to store the geocoding service instance
  const [geocodingService, setGeocodingService] =
    useState<google.maps.Geocoder>();
  // State to store the geocoding result
  const [geocodingResult, setGeocodingResult] =
    useState<google.maps.GeocoderResult>();

  // Function to get the position by address
  const getPositionByAddress = () => {
    const address = getValues("address");
    if (!geocodingService || !address) return;
    setLoading(true);
    geocodingService?.geocode({ address }, (results, status) => {
      if (results && status === "OK") {
        setGeocodingResult(results[0]);
      }
    });
    setLoading(false);
  };

  // Effect to initialize the geocoding service when the API is loaded
  useEffect(() => {
    if (!geocodingApiLoaded) return;
    setGeocodingService(new window.google.maps.Geocoder());
  }, [geocodingApiLoaded]);

  // Effect to update the position state when a new geocoding result is available
  useEffect(() => {
    if (!geocodingResult) return;
    setPosition({
      latitude: geocodingResult.geometry.location.lat(),
      longitude: geocodingResult.geometry.location.lng(),
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [geocodingResult]);

  return (
    <div className="address_input_cnt">
      <label>Dirección</label>
      <div className="address_locate_cnt">
        <button type="button" onClick={getPositionByAddress}>
          {" "}
          Ubicar
        </button>
        <input
          type="text"
          {...register("address")}
          onKeyDown={(event) => {
            if (event.key === "Enter") {
              getPositionByAddress();
            }
          }}
        />
      </div>
      <p className="error">{errors.address?.message}</p>
    </div>
  );
};
