import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { GET, POST } from "../../utils/api";
import { API } from "../../endpoints/common_endpoints";

// Thunk for getting home banners
export const getAllProducts = createAsyncThunk(
  "all-products",
  async (
    {
      category_id,
      subcategory_id,
      childcategory_id,
      brand_id,
      name = "",
      priceOrder,
      type = "",
      need_id,
      sortBy,
      shape_id,
      page = 1,
      per_page = 9,
    },
    { rejectWithValue },
  ) => {
    try {
      const Data = await GET(
        API.GET_ALL_PRODUCTS +
          `?category_id=${category_id || ""}&sub_category_id=${
            subcategory_id || ""
          }&child_category_id=${childcategory_id || ""}` +
          `&brand_id=${brand_id || ""}&need_id=${need_id || ""}&name=${
            name || ""
          }&priceOrder=${priceOrder || ""}&sortBy=${
            sortBy || ""
          }&shape_id=${shape_id || ""}&page=${page || 1}&per_page=${per_page || 1}`,
      );

      return Data?.data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getAllTimeFavsProducts = createAsyncThunk(
  "all-products-material",
  async (
    {
      category_id,
      subcategory_id,
      childcategory_id,
      brand_id,
      name,
      priceOrder,
      type = "",
      need_id,
      shape_id,
    },
    { rejectWithValue },
  ) => {
    try {
      const Data = await GET(
        API.GET_ALL_TIME_PRODUCTS +
          `/${type}` +
          `?category_id=${category_id || ""}&sub_category_id=${
            subcategory_id || ""
          }&child_category_id=${childcategory_id || ""}` +
          `&brand_id=${brand_id || ""}&need_id=${need_id || ""}&name=${
            name || ""
          }&priceOrder=${priceOrder || ""}&shape_id=${shape_id || ""}`,
      );

      return Data?.data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getAllProductsHARVESTED = createAsyncThunk(
  "all-products-shape",
  async (
    {
      category_id,
      subcategory_id,
      childcategory_id,
      brand_id,
      name,
      priceOrder,
      type = "",
      need_id,
    },
    { rejectWithValue },
  ) => {
    try {
      const Data = await GET(
        API.GET_ALL_PRODUCTS +
          `/${type}` +
          `?category_id=${category_id || ""}&sub_category_id=${
            subcategory_id || ""
          }&child_category_id=${childcategory_id || ""}` +
          `&brand_id=${brand_id || ""}&need_id=${need_id || ""}&name=${
            name || ""
          }&priceOrder=${priceOrder || ""}`,
      );

      return Data?.data?.data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getAllProductsNewLaunch = createAsyncThunk(
  "all-products-newlaunch",
  async (
    {
      category_id,
      subcategory_id,
      childcategory_id,
      brand_id,
      name,
      priceOrder,
      type = "",
      need_id,
    },
    { rejectWithValue },
  ) => {
    try {
      const Data = await GET(
        API.GET_ALL_PRODUCTS +
          `/${type}` +
          `?category_id=${category_id || ""}&sub_category_id=${
            subcategory_id || ""
          }&child_category_id=${childcategory_id || ""}` +
          `&brand_id=${brand_id || ""}&need_id=${need_id || ""}&name=${
            name || ""
          }&priceOrder=${priceOrder || ""}`,
      );

      return Data?.data?.data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getAllOURProduct = createAsyncThunk(
  "all-products-populer",
  async (
    {
      category_id,
      subcategory_id,
      childcategory_id,
      brand_id,
      name,
      priceOrder,
      type = "",
      need_id,
    },
    { rejectWithValue },
  ) => {
    try {
      const Data = await GET(
        API.GET_ALL_OUR_PRODUCTS +
          `?category_id=${category_id || ""}&sub_category_id=${
            subcategory_id || ""
          }&child_category_id=${childcategory_id || ""}` +
          `&brand_id=${brand_id || ""}&need_id=${need_id || ""}&name=${
            name || ""
          }&priceOrder=${priceOrder || ""}`,
      );

      return Data?.data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Thunk for gettingStore
export const getProduct = createAsyncThunk(
  "product",
  async (id, { rejectWithValue }) => {
    try {
      const data = await GET(API.GET_PRODUCT + `/${id}`);
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getCommonVariant = createAsyncThunk(
  "product-variant",
  async (id, { rejectWithValue }) => {
    try {
      const data = await GET(API.GET_PRODUCT + `/variant/${id}`);
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const getSizeVariant = createAsyncThunk(
  "product-variant-size",
  async ({ id, metal_id, diamond_id }, { rejectWithValue }) => {
    try {
      const data = await GET(
        API.GET_PRODUCT +
          `/size-variant/${id}?metal_id=${metal_id}&diamond_id=${diamond_id}`,
      );
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Thunk for gettingStore
export const getLinkedProduct = createAsyncThunk(
  "linked-product",
  async (id, { rejectWithValue }) => {
    try {
      const data = await GET(API.GET_LINKED_PRODUCT + `/${id}`);
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Thunk for gettingStore
export const getGroupByProduct = createAsyncThunk(
  "group-by-product",
  async ({ p_category_id }, { rejectWithValue }) => {
    try {
      const data = await GET(
        API.GET_ALL_PRODUCT_GROUP_BY_SUB_CATEGORIES +
          `?p_category_id=${p_category_id || ""}`,
      );
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const findCombination = createAsyncThunk(
  "auth/product-combination",
  async (data, { rejectWithValue }) => {
    try {
      const combinationdata = await POST(
        API.GET_PRODUCT + `/combination`,
        data,
      );

      return combinationdata;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const pincodeCheck = createAsyncThunk(
  "auth/product-pincode",
  async (data, { rejectWithValue }) => {
    try {
      const combinationdata = await POST(
        API.GET_PRODUCT + `/${data?.product_id}`,
        data,
      );

      return combinationdata;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Thunk for getting Add banners
export const getspecialitystatus = createAsyncThunk(
  "product/add-specialstatus",
  async (_, { rejectWithValue }) => {
    try {
      const specialstatusData = await GET(API.GET_SPECIAL_STATUS);
      return specialstatusData;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

const handleAsyncState = (state, action, isSignin = false) => {
  switch (action.type) {
    case "pending":
      state.status = "loading";
      break;
    case "fulfilled":
      state.status = "succeeded";
      if (isSignin) {
        state.token = action.payload;
        state.is_signin = true;
      }
      break;
    case "rejected":
      state.status = "failed";
      state.error = action.payload;
      if (isSignin) state.is_signin = false;
      break;
    default:
      return state;
  }
};
// Create the slice
const productSlice = createSlice({
  name: "product",
  initialState: {
    allProducts: [],
    allProductsGroup: [],
    allProductsFavs: [],
    allProductsSHARED: [],
    allProductsNewLaunch: [],
    allOurProducts: [],
    product: {},

    product_variant: {},
    variant_size: [],
    linked_products: [],
    addSpecialstatus: [],
    error: null,
    status: "idle",
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(getAllProducts.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllProducts.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.allProducts = action.payload || [];
        console.log("State after fulfilled.........", state);
      })
      .addCase(getAllProducts.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected.....", state);
      })
      .addCase(getAllTimeFavsProducts.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllTimeFavsProducts.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log("Response payload in fulfilled case:", action.payload);
        state.allProductsFavs = action.payload || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getAllTimeFavsProducts.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getAllProductsHARVESTED.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllProductsHARVESTED.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log("Response payload in fulfilled case:", action.payload);
        state.allProductsSHARED = action.payload || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getAllProductsHARVESTED.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })
      .addCase(getAllProductsNewLaunch.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllProductsNewLaunch.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log("Response payload in fulfilled case:", action.payload);
        state.allProductsNewLaunch = action.payload || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getAllProductsNewLaunch.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getAllOURProduct.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getAllOURProduct.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log("Response payload in fulfilled case:", action.payload);
        state.allOurProducts = action.payload || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getAllOURProduct.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getProduct.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getProduct.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log(
          "Response payload combination in fulfilled case:",
          action.payload,
        );
        state.product = action.payload?.data || {};
        console.log("State after fulfilled", state);
      })
      .addCase(getProduct.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getSizeVariant.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getSizeVariant.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log(
          "Response payload combination in fulfilled case:",
          action.payload,
        );
        state.variant_size = action.payload?.data || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getSizeVariant.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getCommonVariant.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getCommonVariant.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log(
          "Response payload combination in fulfilled case:",
          action.payload,
        );
        state.product_variant = action.payload?.data || {};
        console.log("State after fulfilled", state);
      })
      .addCase(getCommonVariant.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getLinkedProduct.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getLinkedProduct.fulfilled, (state, action) => {
        state.status = "succeeded";
        console.log("Response payload in fulfilled case:", action.payload);
        state.linked_products = action.payload?.data || {};
        console.log("State after fulfilled", state);
      })
      .addCase(getLinkedProduct.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(getGroupByProduct.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getGroupByProduct.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.allProductsGroup = action.payload || [];
        console.log("Response payload in fulfilled case:", action.payload);
        console.log("State after fulfilled", state);
      })
      .addCase(getGroupByProduct.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      })

      .addCase(findCombination.pending, (state) =>
        handleAsyncState(state, { type: "pending" }, true),
      )
      .addCase(findCombination.fulfilled, (state, action) =>
        handleAsyncState(
          state,
          { type: "fulfilled", payload: action.payload },
          true,
        ),
      )
      .addCase(findCombination.rejected, (state, action) =>
        handleAsyncState(
          state,
          { type: "rejected", payload: action.payload },
          true,
        ),
      )
      .addCase(pincodeCheck.pending, (state) =>
        handleAsyncState(state, { type: "pending" }, true),
      )
      .addCase(pincodeCheck.fulfilled, (state, action) =>
        handleAsyncState(
          state,
          { type: "fulfilled", payload: action.payload },
          true,
        ),
      )
      .addCase(pincodeCheck.rejected, (state, action) =>
        handleAsyncState(
          state,
          { type: "rejected", payload: action.payload },
          true,
        ),
      )

      .addCase(getspecialitystatus.pending, (state) => {
        state.status = "loading";
      })
      .addCase(getspecialitystatus.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.addSpecialstatus = action.payload?.data || [];
        console.log("State after fulfilled", state);
      })
      .addCase(getspecialitystatus.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
        console.log("State after rejected", state);
      });
  },
});

export default productSlice.reducer;
