import axios, { AxiosResponse } from "axios";
import { AnyAction } from "redux";
import { ThunkAction } from "redux-thunk";

import {
  GET_NOTIFICATION_FAILED,
  GET_NOTIFICATION_REQUEST,
  GET_NOTIFICATION_SUCCESS,
} from "./types";


import config from '../../config/config';
import { RootState } from "../../store/store";
import { setRefreshedNewToken } from "../../utils/authentication";
import { axiosErrorMessage } from "../../utils/helper";

// Thunk Type
type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  AnyAction
>;

/**
 * ✅ Fetch Notifications
 */
export const getNotifications = (): AppThunk<Promise<void>> => {
  return async (dispatch, getState) => {
    dispatch({ type: GET_NOTIFICATION_REQUEST });

    const { notificationData } = getState();

    try {
      const res: AxiosResponse<any> = await axios.get(
        `${config.apiserver}/api/v1/notifications/get-user-notifications`
      );

      if (res.data?.status === "error" && notificationData?.notifications) {
        dispatch({
          type: GET_NOTIFICATION_SUCCESS,
          payload: notificationData.notifications,
        });
      } else {
        dispatch({
          type: GET_NOTIFICATION_SUCCESS,
          payload: res.data,
        });
      }
    } catch (error: any) {
      if (error.response?.status === 401) {
        await setRefreshedNewToken();
        // Remove the explicit typing - let TypeScript infer it
        setTimeout(() => dispatch(getNotifications() as any), 2000);
      } else {
        axiosErrorMessage("Something went wrong while fetching notifications", error);
        dispatch({
          type: GET_NOTIFICATION_FAILED,
          payload: error,
        });
      }
    }
  };
};

/**
 * ✅ Mark Single Notification as Read
 */
export const readNotification = (notificationId: string): AppThunk<Promise<void>> => {
  return async (dispatch) => {
    try {
      await axios.get(`${config.apiserver}/api/v1/notifications/set-message-read/${notificationId}`);
      // Refresh notifications after marking read
      dispatch(getNotifications());
    } catch (error) {
      console.log("Notification read error", error);
      axiosErrorMessage("Notification read error", error);
    }
  };
};

/**
 * ✅ Mark All Notifications as Read
 */
export const setAllRead = (): AppThunk<Promise<void>> => {
  return async () => {
    try {
      await axios.get(`${config.apiserver}/api/v1/notifications/set-all-message-read`);
    } catch (error) {
      console.log("Set all notifications read error", error);
      axiosErrorMessage("Set all notifications read error", error);
    }
  };
};

/**
 * ✅ Clear All Notifications
 */
export const clearAllNotifications = (): AppThunk<Promise<void>> => {
  return async () => {
    try {
      await axios.get(`${config.apiserver}/api/v1/notifications/clear-all-messages`);
    } catch (error) {
      console.log("Clear all notifications error", error);
      axiosErrorMessage("Clear all notifications error", error);
    }
  };
};
