/* eslint-disable sonarjs/no-small-switch */
import type { LdapUser } from '@/types/user';
import type { PropsWithChildren } from 'react';
import { createContext, useMemo, useReducer } from 'react';

type State = {
  error: string | undefined;
  step: 'login' | 'telegram' | 'telegram-login';
  tfa: boolean;
  user: LdapUser | undefined;
};

type Action = {
  payload: Partial<State>;
  type: 'set-step' | 'set-error' | 'reset-error';
};

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case 'set-step': {
      if (action.payload.step)
        return {
          ...state,
          error: undefined,
          step: action.payload.step,
          user: action.payload.user || state.user,
        };

      return state;
    }

    case 'set-error': {
      if (action.payload.error) {
        return {
          ...state,
          error: action.payload.error,
        };
      }

      return state;
    }

    case 'reset-error': {
      return {
        ...state,
        error: undefined,
      };
    }

    default:
      return state;
  }
};

type Context = {
  dispatch: React.Dispatch<Action>;
  state: State;
};

export const FormStateContext = createContext<Context>({} as Context);

type FormStateProviderProps = {
  readonly tfa: boolean;
  readonly user?: LdapUser;
} & PropsWithChildren;

export function FormStateProvider({ children, tfa, user = undefined }: FormStateProviderProps) {
  const [state, dispatch] = useReducer(reducer, {
    error: undefined,
    step: 'login',
    tfa,
    user,
  });

  const value = useMemo(() => ({ dispatch, state }), [state]);

  return <FormStateContext.Provider value={value}>{children}</FormStateContext.Provider>;
}
