import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { GET, POST } from "../../utils/api";
import { API } from "../../endpoints/common_endpoints";
import Cookies from "js-cookie";
import axios from "axios";
// Thunk for getting home banners
export const getCurrentLocation = createAsyncThunk(
  "location/getCurrentLocation",
  async (_, { rejectWithValue, dispatch }) => {
    return new Promise((resolve, reject) => {
      if (!navigator.geolocation) {
        return reject(
          rejectWithValue("Geolocation is not supported by this browser."),
        );
      }

      navigator.geolocation.getCurrentPosition(
        async (position) => {
          const { latitude, longitude } = position.coords;
          const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY;

          try {
            const response = await axios.get(
              `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${apiKey}`,
            );

            const results = response?.data?.results;
            const addressDetails = response.data.results[0];
            if (
              !results ||
              response.data.status !== "OK" ||
              results.length === 0
            ) {
              return reject(
                rejectWithValue("Failed to fetch accurate location data"),
              );
            }

            // Select best match
            const bestMatch =
              results.find(
                (r) =>
                  r.types.includes("street_address") ||
                  r.types.includes("premise") ||
                  r.types.includes("sublocality_level_1"),
              ) || results[0];

            const addressComponents = bestMatch.address_components;

            const getComponent = (types) => {
              const match = addressComponents.find((comp) =>
                types.some((type) => comp.types.includes(type)),
              );
              return match?.long_name || "";
            };

            const addressParts = {
              colony: getComponent(["neighborhood", "sublocality_level_2"]),
              area: getComponent(["sublocality_level_1", "sublocality"]),
              city: getComponent(["locality"]),
              state: getComponent(["administrative_area_level_1"]),
              country: getComponent(["country"]),
              pincode: getComponent(["postal_code"]),
            };

            const formattedCustomAddress = [
              addressParts.colony,
              addressParts.area,
              addressParts.city,
              addressParts.state,
              addressParts.country,
              addressParts.pincode,
            ]
              .filter(Boolean)
              .join(", ");

            const fullLocationData = {
              ...addressParts,
              formatted_address: formattedCustomAddress,
              raw: bestMatch,
              coordinates: { lat: latitude, lng: longitude },
              place_id: bestMatch.place_id,
              types: bestMatch.types,
            };

            // Save to cookies
            Cookies.set(
              "current_location_gurukrupa",
              JSON.stringify(fullLocationData),
            );

            // Dispatch to Redux store
            dispatch(setCurrentLocation(addressDetails));

            resolve(fullLocationData);
          } catch (error) {
            console.error("Error fetching location from Google Maps:", error);
            reject(rejectWithValue("Google Maps API error"));
          }
        },
        (error) => {
          console.error("Geolocation error:", error);
          reject(rejectWithValue("Failed to get geolocation data"));
        },
      );
    });
  },
);

export const getLocationFromSession = createAsyncThunk(
  "getLocationFromSession",
  async (_, { rejectWithValue }) => {
    const current_location = Cookies.get("current_location_gurukrupa");
    if (!current_location) {
      return rejectWithValue("No Location Found");
    }
    try {
      const response = JSON.parse(current_location);
      return response;
    } catch (error) {
      return rejectWithValue(error.message || "Cuurent location get Faild");
    }
  },
);

export const getAllGooglePlaces = createAsyncThunk(
  "master/get-all-google-places",
  async ({ name }, { rejectWithValue }) => {
    try {
      const response = await GET(`${API.GET_ALL_GOOGLE_PLACES}?input=${name}`);
      const result = response;
      return result;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Create the slice
const locationSlice = createSlice({
  name: "location",
  initialState: {
    error: null,
    locationError: null,
    status: "idle",
    location: null,
    current_location: {},
    google_location: {},
  },
  reducers: {
    setCurrentLocation: (state, action) => {
      // state.current_location = {};
      state.current_location = action.payload;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(getCurrentLocation.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getCurrentLocation.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.location = action.payload; // Store the geolocation coordinates
      })
      .addCase(getCurrentLocation.rejected, (state, action) => {
        state.status = "failed";
        state.locationError = action.payload; // Store the location error
      })

      .addCase(getLocationFromSession.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getLocationFromSession.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.current_location = action.payload || {};
        // Logging for debugging
      })
      .addCase(getLocationFromSession.rejected, (state, action) => {
        state.status = "failed";
        state.locationError = action.payload;
        console.error("Error in rejected case:", action.payload); // Log the error for debugging
      })

      .addCase(getAllGooglePlaces.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllGooglePlaces.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.google_location = action.payload || {};
        // Logging for debugging
      })
      .addCase(getAllGooglePlaces.rejected, (state, action) => {
        state.status = "failed";
        state.locationError = action.payload;
        console.error("Error in rejected case:", action.payload); // Log the error for debugging
      });
  },
});
export const { setCurrentLocation } = locationSlice.actions;
export default locationSlice.reducer;
