import {useContext} from '@hooks';
import {Dispatch, useCallback, useReducer} from 'react';
import {createContext} from 'use-context-selector';

export type SearchContextState = {
  isSearching: boolean;
  refetch: () => void;
};

export type SearchContextAction =
  | {type: 'CHANGE_SEARCH_STATE'; payload: boolean}
  | {type: 'CHANGE_SEARCH_FUNCTION'; payload: () => void};

export function initSearchContextState(
  init?: Partial<SearchContextState>,
): SearchContextState {
  return {isSearching: init?.isSearching ?? false, refetch: () => null};
}

function reducer(
  state: SearchContextState,
  action: SearchContextAction,
): SearchContextState {
  switch (action.type) {
    case 'CHANGE_SEARCH_STATE':
      return {...state, isSearching: action.payload};
    case 'CHANGE_SEARCH_FUNCTION':
      return {...state, refetch: action.payload};
    default:
      return state;
  }
}

export function useSearchContextReducer() {
  return useReducer(reducer, initSearchContextState());
}

export const createSearchContext = () =>
  createContext<[SearchContextState, Dispatch<SearchContextAction>]>([
    initSearchContextState(),
    () => null,
  ]);

export function useTableSearchState(
  context: ReturnType<typeof createSearchContext>,
) {
  const [{isSearching}, dispatch] = useContext(context);

  const onSearchChange = useCallback(
    function (state: boolean) {
      dispatch({type: 'CHANGE_SEARCH_STATE', payload: state});
    },
    [dispatch],
  );

  return [isSearching, onSearchChange] as const;
}

export function useTableSearchDispatch(
  context: ReturnType<typeof createSearchContext>,
) {
  const [, dispatch] = useContext(context);

  return dispatch;
}
