/**
 * Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
 */
import {Dispatch} from 'redux';
import userStore from 'services/user-store';
import {TimeFormats} from 'utility';
import {transformToPortalError} from 'utility/error-handler';

/**
 * ACTION TYPES
 */

export const GET_PREFERRED_TIME_FORMAT = 'preferred-time-format::GET_PREFERRED_TIME_FORMAT' as const;
export const GET_PREFERRED_TIME_FORMAT_DONE = 'preferred-time-format::GET_PREFERRED_TIME_FORMAT_DONE' as const;
export const GET_PREFERRED_TIME_FORMAT_ERROR = 'preferred-time-format::GET_PREFERRED_TIME_FORMAT_ERROR' as const;
export const SET_PREFERRED_TIME_FORMAT = 'preferred-time-format::SET_PREFERRED_TIME_FORMAT' as const;
export const SET_PREFERRED_TIME_FORMAT_DONE = 'preferred-time-format::SET_PREFERRED_TIME_FORMAT_DONE' as const;
export const SET_PREFERRED_TIME_FORMAT_ERROR = 'preferred-time-format::SET_PREFERRED_TIME_FORMAT_ERROR' as const;

/**
 * INTERFACES
 */

interface IRequestGetPreferredTimeFormat {
  type: typeof GET_PREFERRED_TIME_FORMAT;
}
interface IReceiveGetPreferredTimeFormat {
  type: typeof GET_PREFERRED_TIME_FORMAT_DONE;
  payload: {data: TimeFormats};
}
interface IFailedGetPreferredTimeFormat {
  type: typeof GET_PREFERRED_TIME_FORMAT_ERROR;
  error: null | string;
}
interface IRequestSetPreferredTimeFormat {
  type: typeof SET_PREFERRED_TIME_FORMAT;
}
interface IReceiveSetPreferredTimeFormat {
  type: typeof SET_PREFERRED_TIME_FORMAT_DONE;
  payload: {data: TimeFormats};
}
interface IFailedSetPreferredTimeFormat {
  type: typeof SET_PREFERRED_TIME_FORMAT_ERROR;
  error: null | string;
}

export type GetPreferredTimeFormatActionType = IRequestGetPreferredTimeFormat | IReceiveGetPreferredTimeFormat | IFailedGetPreferredTimeFormat;
export type SetPreferredTimeFormatActionType = IRequestSetPreferredTimeFormat | IReceiveSetPreferredTimeFormat | IFailedSetPreferredTimeFormat;

interface IGetPreferredTimeFormatActions {
  request: () => GetPreferredTimeFormatActionType;
  receive: (payload) => GetPreferredTimeFormatActionType;
  failed: (error: null | string) => GetPreferredTimeFormatActionType;
}
interface ISetPreferredTimeFormatActions {
  request: () => SetPreferredTimeFormatActionType;
  receive: (payload) => SetPreferredTimeFormatActionType;
  failed: (error: null | string) => SetPreferredTimeFormatActionType;
}

/**
 * ACTIONS
 */

const getPreferredTimeFormatActions: IGetPreferredTimeFormatActions = {
  request: () => ({type: GET_PREFERRED_TIME_FORMAT}),
  receive: payload => ({
    type: GET_PREFERRED_TIME_FORMAT_DONE,
    payload
  }),
  failed: error => ({
    type: GET_PREFERRED_TIME_FORMAT_ERROR,
    error
  })
};

export const getPreferredTimeFormat = () => async(dispatch: Dispatch<GetPreferredTimeFormatActionType>): Promise<void> => {
  const {
    request,
    receive,
    failed
  } = getPreferredTimeFormatActions;

  dispatch(request());

  try {
    let preferredTimeFormat = await userStore.get('timeFormat');

    if (!preferredTimeFormat) {
      await userStore.set('timeFormat', TimeFormats.Utc);
      preferredTimeFormat = await userStore.get('timeFormat');
    }

    dispatch(receive({data: preferredTimeFormat}));
  } catch (e) {
    const {message} = transformToPortalError(e);

    dispatch(failed(message || 'An error occurred while getting the preferred time format'));
  }
};

const setPreferredTimeFormatActions: ISetPreferredTimeFormatActions = {
  request: () => ({type: SET_PREFERRED_TIME_FORMAT}),
  receive: payload => ({
    type: SET_PREFERRED_TIME_FORMAT_DONE,
    payload
  }),
  failed: error => ({
    type: SET_PREFERRED_TIME_FORMAT_ERROR,
    error
  })
};

export const setPreferredTimeFormat = (format: TimeFormats) => async(dispatch: Dispatch<SetPreferredTimeFormatActionType>): Promise<void> => {
  const {
    request,
    receive,
    failed
  } = setPreferredTimeFormatActions;

  dispatch(request());

  try {
    await userStore.set('timeFormat', format);

    dispatch(receive({data: format}));
  } catch (e) {
    const {message} = transformToPortalError(e);

    dispatch(failed(message || 'An error occurred while setting the preferred time format'));
  }
};