import { useCallback, useState } from "react";
import { useAppDispatch, useAppSelector } from "../redux/hooks";
import {
  setLocationAsync,
  setLocationVerifiedStatus,
  setUserLocation,
} from "../slices/common/locationSlice/locationSlice";
import { showSnackbar } from "../slices/common/customSnackBar/customSnackbarSlice";
import { getDecryptedToken } from "../auth/authHandler";

const useLocationHook = () => {
  const dispatch = useAppDispatch();
  const [permissionDenied, setPermissionDenied] = useState<boolean>(false);
  const [modalOpen, setModalOpen] = useState<boolean>(false);
  const locationVerified = useAppSelector(
    (state) => state.locationState.locationVerified
  );

  const fetchLocation = useCallback(() => {
    setModalOpen(false);
    if (!navigator.geolocation) {
      dispatch(
        setUserLocation({
          latitude: null,
          longitude: null,
          error: "Geolocation is not supported by your browser",
        })
      );
      return;
    }

    const successCallback = async (position: GeolocationPosition) => {
      const { latitude, longitude } = position.coords;

      dispatch(
        setUserLocation({
          latitude,
          longitude,
          error: null,
        })
      );
      let payload: any = { latitude, longitude };
      const aId = localStorage.getItem("aId");
      const accessToken = getDecryptedToken();

      if (aId && accessToken == null) {
        payload.anonymous_id = aId;
      }
      dispatch(setLocationAsync(payload)).then((response: any) => {
        if (response?.payload?.status === 200) {
          if (response?.payload?.data?.location?.anonymous_id) {
            localStorage.setItem(
              "aId",
              response?.payload?.data?.location?.anonymous_id
            );
          }
          // if (response?.payload?.data?.location?.shop == null) {
          //   setLocationVerifiedStatus("failed");
          //   setModalOpen(true);
          // dispatch(
          //   showSnackbar({
          //     message: "Location not serviceable",
          //     severity: "error",
          //     autoHide: 3000,
          //   })
          // );
          // }
          if (response?.payload?.data?.location) {
            setLocationVerifiedStatus("success");
            window.location.href = "/";
            setModalOpen(true);
            dispatch(
              showSnackbar({
                message: "Location added successfully",
                severity: "success",
                autoHide: 3000,
              })
            );
          }
        } else {
          dispatch(
            showSnackbar({
              message: "Please try again later.",
              severity: "error",
              autoHide: 3000,
            })
          );
        }
      });

      setPermissionDenied(false);

      // Fetch the place name using Google Maps API after successfully getting the location
      await getLocationName(latitude, longitude);
    };

    const errorCallback = (error: GeolocationPositionError) => {
      if (error?.code === error?.PERMISSION_DENIED) {
        setPermissionDenied(true);
      }
      dispatch(
        setUserLocation({
          latitude: null,
          longitude: null,
          error: error.message,
        })
      );
    };

    const geoOptions: PositionOptions = {
      enableHighAccuracy: true,
      timeout: 10000, // 10 seconds
      maximumAge: 0, // No caching
    };

    navigator.geolocation.getCurrentPosition(
      successCallback,
      errorCallback,
      geoOptions
    );
  }, [dispatch]);

  const getLocationName = async (lat: number, lng: number) => {
    if (!window.google) {
      console.error("Google Maps API is not available.");
      return;
    }

    const geocoder = new window.google.maps.Geocoder();
    const latLng = { lat, lng };

    try {
      const results = await new Promise<google.maps.GeocoderResult[]>(
        (resolve, reject) => {
          geocoder.geocode({ location: latLng }, (results, status) => {
            if (status === "OK" && results) {
              resolve(results);
            } else {
              reject(status);
            }
          });
        }
      );

      if (results[0]) {
        dispatch(
          setUserLocation({
            display_name: results[0].formatted_address,
          })
        );
      } else {
        dispatch(
          setUserLocation({
            display_name: "No address found",
          })
        );
      }
    } catch (error) {
      // Handle specific Geocoder API errors
      let errorMessage = "Unable to fetch address.";
      if (error === "ZERO_RESULTS") {
        errorMessage = "No results found for this location.";
      } else if (error === "OVER_QUERY_LIMIT") {
        errorMessage = "Query limit exceeded. Please try again later.";
      } else if (error === "REQUEST_DENIED") {
        errorMessage = "Request denied. Please check your API key.";
      } else if (error === "INVALID_REQUEST") {
        errorMessage = "Invalid request. Please provide valid location data.";
      }

      console.error("Geocoder failed due to:", error);
      dispatch(
        setUserLocation({
          display_name: errorMessage,
        })
      );
    }
  };

  return {
    fetchLocation,
    permissionDenied,
    modalOpen,
  };
};

export default useLocationHook;
