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

// Utility function for API requests
const apiRequest = async (apiFn, api, data, errorMessage) => {
  try {
    const response = await apiFn(api, data);

    if (response?.success) {
      return response?.data;
    } else {
      throw new Error(response || errorMessage);
    }
  } catch (error) {
    throw new Error(error || errorMessage);
  }
};

// Thunk to validate token (Async)
export const checkTokenValidity = createAsyncThunk(
  "auth/checkTokenValidity",
  async (_, { rejectWithValue }) => {
    const token = Cookies.get("shreeram_agro_security");
    if (!token) {
      return rejectWithValue("No token found");
    }

    try {
      const decodedToken = JSON.parse(atob(token.split(".")[1]));
      const currentTime = Date.now() / 1000;
      if (decodedToken.exp < currentTime) {
        Cookies.remove("shreeram_agro_security", { path: "/" });
        return rejectWithValue("Token expired");
      }
      return decodedToken;
    } catch (error) {
      return rejectWithValue(error.message || "Token validation failed");
    }
  },
);

// Thunk for sending OTP
export const sendMobileOtp = createAsyncThunk(
  "auth/sendOtp",
  async (data, { rejectWithValue }) => {
    try {
      const otp = await apiRequest(POST, API.SEND_OTP, data, " found.");
      return otp;
      //   return rejectWithValue(otp);
    } catch (error) {
      return rejectWithValue(error);
    }
  },
);

// Thunk for verifying login
export const verifyOtp = createAsyncThunk(
  "auth/verifyotp",
  async (data, { rejectWithValue }) => {
    try {
      //   const res  = await apiRequest(
      //     POST,
      //     API.VERIFY_OTP,
      //     data,
      //     "Login failed"
      //   );

      //   return res;

      const response = await POST(API.VERIFY_OTP, data);

      if (response?.success) {
        return response;
      }

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

export const forgotPassword = createAsyncThunk(
  "auth/forgot-password",
  async (data, { rejectWithValue }) => {
    try {
      const response = await POST(API.UPDATE_PASSWORD, data);
      if (response?.success) {
        return response;
      }
      return rejectWithValue(response);
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

// Thunk for Logout
export const logout = createAsyncThunk(
  "auth/logout",
  async ({ navigate }, { dispatch, rejectWithValue }) => {
    try {
      Cookies.remove("shreeram_agro_security");

      navigate("/"); // Redirect to homepage or login
      // Optionally dispatch logout-related state
      dispatch(setIsSignedOut());
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);

export const userSignUp = createAsyncThunk(
  "auth/sing-up",
  async (data, { rejectWithValue }) => {
    try {
      const response = await POST(API.USER_SINGUP, data);

      if (response?.data?.token) {
        Cookies.set("shreeram_agro_security", response?.data?.token);
        return response?.data?.token;
      }

      return rejectWithValue(response);
    } catch (error) {
      return rejectWithValue(error.message);
    }
  },
);
export const B2BSignUp = createAsyncThunk(
  "auth/b2b-sing-up",
  async (data, { rejectWithValue }) => {
    try {
      const response = await POST(API.B2B_SINGUP, data);

      if (response?.data?.token) {
        Cookies.set("shreeram_agro_security", response?.data?.token);
        return response?.data?.token;
      }

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

export const UserLogin = createAsyncThunk(
  "auth/userLogin",
  async (data, { rejectWithValue }) => {
    try {
      const response = await POST(API.USER_LOGIN, data);

      if (response?.data?.token) {
        Cookies.set("shreeram_agro_security", response?.data?.token);
        return response?.data?.token;
      }

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

// Helper function to handle common async state transitions
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;
  }
};

const token = Cookies.get("shreeram_agro_security");
// Create the slice
const authSlice = createSlice({
  name: "auth",
  initialState: {
    token: "",
    name: "",
    error: null,
    status: "idle",
    // is_signin: false,
    is_signin: !!token,
  },

  reducers: {
    setIsSignedOut: (state) => {
      state.is_signin = false;
      state.token = "";
      state.name = "";
    },
  },
  extraReducers: (builder) => {
    builder
      // Handling verifyLogin actions
      .addCase(verifyOtp.pending, (state) =>
        handleAsyncState(state, { type: "pending" }, true),
      )
      .addCase(verifyOtp.fulfilled, (state, action) =>
        handleAsyncState(
          state,
          { type: "fulfilled", payload: action.payload },
          // true
        ),
      )
      .addCase(verifyOtp.rejected, (state, action) =>
        handleAsyncState(
          state,
          { type: "rejected", payload: action.payload },
          // true
        ),
      )
      .addCase(forgotPassword.pending, (state) =>
        handleAsyncState(state, { type: "pending" }, true),
      )
      .addCase(forgotPassword.fulfilled, (state, action) =>
        handleAsyncState(
          state,
          { type: "fulfilled", payload: action.payload },
          // true
        ),
      )
      .addCase(forgotPassword.rejected, (state, action) =>
        handleAsyncState(
          state,
          { type: "rejected", payload: action.payload },
          // true
        ),
      )

      // Handling sendMobileOtp actions
      .addCase(sendMobileOtp.pending, (state) =>
        handleAsyncState(state, { type: "pending" }),
      )
      .addCase(sendMobileOtp.fulfilled, (state) =>
        handleAsyncState(state, { type: "fulfilled" }),
      )
      .addCase(sendMobileOtp.rejected, (state, action) =>
        handleAsyncState(state, { type: "rejected", payload: action.payload }),
      )

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

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

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

      // Handling checkTokenValidity actions
      .addCase(checkTokenValidity.pending, (state) =>
        handleAsyncState(state, { type: "pending" }),
      )
      .addCase(checkTokenValidity.fulfilled, (state) =>
        handleAsyncState(state, { type: "fulfilled" }, true),
      )
      .addCase(checkTokenValidity.rejected, (state, action) =>
        handleAsyncState(state, { type: "rejected", payload: action.payload }),
      );
  },
});

export const { setIsSignedOut } = authSlice.actions;

export default authSlice.reducer;
