/**
 * File: authenticationThunks.ts
 * Purpose: This file contains asynchronous thunk actions for managing authentication-related workflows 
 *          such as user sign-in, sign-up, OTP verification, password reset, and more.
 *          
 * Description:
 * - Utilizes `redux-thunk` to create async actions that handle API requests and responses.
 * - Handles authentication API calls by dispatching appropriate Redux actions based on the API response.
 * - Displays error notifications using the `Toast` component in case of API failures.
*/

import apiClient from "@/src/interceptor/apiClient";
import { API_ENDPOINTS } from "@/src/utils/commonVariables";
import { authActions } from "../../slices/Auth/authentication";
import {
  CheckUserNameAvailabilityPayload,
  ForgotPasswordPayload,
  ResendOTPPayload,
  ResetPasswordPayload,
  SignInPayload,
  SignUpPayload,
  VerifyOTPPayload,
} from "../../types/authenticationTypes";
import { Toast } from "@/src/components/Toast/index";

/**
 * Asynchronous thunk action for user sign-in process.
 * @param payload - The data required for user sign-up.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const signInThunk =
  (payload: SignInPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestSignIn());
        const { data } = await apiClient.post(API_ENDPOINTS.LOGIN, payload);
        if (data?.meta?.status) {
          callback && callback(data);
          if (data?.meta?.isVerified) {
            dispatch(authActions.responseSignIn(data));
          } else {
            dispatch(authActions.responseEmailLRFData(data?.data?.email))
          }
        } else {
          Toast("error", data?.meta?.message)
        }
      } catch (error: any) {
        dispatch(authActions.errorSignIn());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };

/**
 * Asynchronous thunk action for user sign-up process.
 * @param payload - The data required for user sign-up.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const signUp =
  (payload: SignUpPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestSignUp());
        const { data } = await apiClient.post(API_ENDPOINTS.SIGNUP, payload);
        dispatch(authActions.responseSignUp(data));
        callback && callback(data);
      } catch (error: any) {
        /* Displays error alert using SweetAlert (Swal) */
        dispatch(authActions.errorSignUp());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };


/**
 * Asynchronous thunk action for username availability process.
 * @param payload - The data required for username availability.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const checkUserNameAvailability =
  (payload: CheckUserNameAvailabilityPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestCheckUserName());
        const response = await apiClient.post(API_ENDPOINTS.CHECK_USERNAME, payload);
        dispatch(authActions.responseCheckUserName());
        callback && callback(response?.data);
      } catch (error: any) {
        dispatch(authActions.errorCheckUserName());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };


/**
 * Asynchronous thunk action for user verify otp process.
 * @param payload - The data required for user verify otp.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const verifyOTP =
  (payload: VerifyOTPPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestVerifyOTP());
        const { data } = await apiClient.post(API_ENDPOINTS.VERIFY_OTP, payload);
        dispatch(authActions.responseVerifyOTP(data));
        callback && callback(data);
      } catch (error: any) {
        dispatch(authActions.errorVerifyOTP());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };

/**
 * Asynchronous thunk action for user resend otp process.
 * @param payload - The data required for user rese.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const resendOTP =
  (payload: ResendOTPPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestResendOTP());
        const { data } = await apiClient.post(API_ENDPOINTS.RESEND_OTP, payload);
        dispatch(authActions.responseResendOTP(data));
        callback && callback(data);
      } catch (error: any) {
        dispatch(authActions.errorResendOTP());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };

/**
 * Asynchronous thunk action for user forgot password process.
 * @param payload - The data required for user forgot password.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const forgotPassword =
  (payload: ForgotPasswordPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.responseEmailLRFData(payload?.email))
        dispatch(authActions.requestForgotPassword());
        const { data } = await apiClient.post(API_ENDPOINTS.FORGOT_PASSWORD, payload);
        dispatch(authActions.responseForgotPassword());
        callback && callback(data);
      } catch (error: any) {
        dispatch(authActions.errorForgotPassword());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };

/**
 * Asynchronous thunk action for user reset password process.
 * @param payload - The data required for user reset password.
 * @param callback - Optional callback function that receives API response data.
 * @returns A thunk function that dispatches actions based on API response.
 */
export const resetPassword =
  (payload: ResetPasswordPayload, callback?: (data: any) => void) =>
    async (dispatch: any) => {
      try {
        dispatch(authActions.requestResetPassword());
        const { data } = await apiClient.post(API_ENDPOINTS.RESET_PASSWORD, payload);
        dispatch(authActions.responseResetPassword());
        callback && callback(data);
      } catch (error: any) {
        dispatch(authActions.errorResetPassword());
        Toast("error", error?.response?.data?.message || error?.message)
      }
    };
