import {PAGE_SIZE_LIST} from '@utils';
import {Dispatch, useCallback, useReducer} from 'react';
import {createContext} from 'use-context-selector';
import {useContext} from '..';
import {produce} from 'immer';

export type PageContextState = {
  page: number,
  pageSize: number,
};

export type PageContextAction = {
  type: 'EDIT_PAGE',
  payload: Partial<PageContextState>,
} | {
  type: 'RESET'
};

export function pageContextInit(options?: {page: number; pageSize: number}): PageContextState {
  const {page, pageSize} = options ?? {};
  return {page: page ?? 1, pageSize: pageSize ?? Number(PAGE_SIZE_LIST[0])};
}

function pageReduce(state: PageContextState, action: PageContextAction): PageContextState {
  const {type} = action;

  switch (type) {
    case 'EDIT_PAGE': {
      const next = produce(state, function(draft) {
        draft.page = action.payload?.page ?? state.page;
        draft.pageSize = action.payload?.pageSize ?? state.pageSize;
      });

      return next;
    }
    case 'RESET':
      return pageContextInit();
    default:
      return state;
  }
}

export function usePageContextReducer(options?: {page: number; pageSize: number}) {
  return useReducer(pageReduce, pageContextInit(options));
}

export function createPageContext() {
  return createContext<[PageContextState, Dispatch<PageContextAction>]>(
    [pageContextInit(), () => null],
  );
}

export function usePage(context: ReturnType<typeof createPageContext>) {
  const [{page, pageSize}, dispatch] = useContext(context);

  const onPageChange = useCallback(function(page: number, pageSize: number) {
    dispatch({type: 'EDIT_PAGE', payload: {page, pageSize}});
  }, [dispatch]);

  const onCurrentPageChange = useCallback(function(page: number) {
    dispatch({type: 'EDIT_PAGE', payload: {page}});
  }, [dispatch]);

  return [{page, pageSize}, {onPageChange, onCurrentPageChange}] as const;
}

