import { FC, createContext, useState, useContext, useCallback } from 'react';

const BULK_LIMIT = 100;

type Item = {
  formId: number;
  stepId: number;
  chatId: number;
};

export type MassiveAssignContextValue = {
  setIsSelecting: (bool: boolean) => void;
  isSelecting: boolean;
  isChecked: (formId: number) => boolean;
  addItem: (item: Item) => void;
  removeItem: (item: number) => void;
  resetSelection: () => void;
  reachedLimit: boolean;
  canExecuteBulkAction: boolean;
  selectedItems: Item[];
};

const MassiveAssignContext = createContext<MassiveAssignContextValue>({
  setIsSelecting: () => null,
  isSelecting: false,
  addItem: () => null,
  removeItem: () => null,
  resetSelection: () => null,
  reachedLimit: false,
  canExecuteBulkAction: false,
  isChecked: () => false,
  selectedItems: [],
});

export const MassiveAssignProvider: FC<
  React.PropsWithChildren<unknown>
> = props => {
  const { children } = props;

  const [isSelecting, setIsSelecting] = useState(false);
  const [selectedItems, setSelectedItems] = useState([]);
  const [checkedBoxes, setCheckedBoxes] = useState({});

  const resetSelection = useCallback(() => {
    setIsSelecting(false);
    setSelectedItems([]);
    setCheckedBoxes({});
  }, []);

  const addItem = useCallback(
    item => {
      if (selectedItems.some(e => e.formId === item.formId)) return;
      setSelectedItems([...selectedItems, item]);
      setCheckedBoxes({ ...checkedBoxes, [item.formId]: true });
    },
    [selectedItems, checkedBoxes],
  );

  const removeItem = useCallback(
    formId => {
      const filteredItems = selectedItems.filter(
        item => item.formId !== formId,
      );
      setSelectedItems(filteredItems);
      setCheckedBoxes({ ...checkedBoxes, [formId]: false });
    },
    [selectedItems, checkedBoxes],
  );

  const isChecked = useCallback(formId => checkedBoxes[formId], [checkedBoxes]);

  const reachedLimit = selectedItems.length >= BULK_LIMIT;

  const canExecuteBulkAction = selectedItems.length > 0;

  return (
    <MassiveAssignContext.Provider
      value={{
        canExecuteBulkAction,
        reachedLimit,
        resetSelection,
        isChecked,
        addItem,
        removeItem,
        isSelecting,
        setIsSelecting,
        selectedItems,
      }}
    >
      {children}
    </MassiveAssignContext.Provider>
  );
};

export const useMassiveAssign = () => useContext(MassiveAssignContext);

export const MassiveAssignConsumer = MassiveAssignContext.Consumer;

export default MassiveAssignContext;
