import { IItem, ItemContainerType } from '@rpg-engine/shared';
import React, {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState,
} from 'react';
import { generateContextMenu, IContextMenuItem } from '../itemContainerHelper';

interface IPosition {
  x: number;
  y: number;
}

interface IItemSlotDetailsState {
  item: IItem | null;
  isTooltipVisible: boolean;
  isTooltipMobileVisible: boolean;
  isContextMenuVisible: boolean;
  contextMenuPosition: IPosition;
  contextActions: IContextMenuItem[];
  clearContextActions: () => void;
  clearDetailsState: () => void;
}

interface IItemSlotDetailsContext {
  detailsState: IItemSlotDetailsState;
  updateDetailsState: (newState: Partial<IItemSlotDetailsState>) => void;
  clearDetailsState: () => void;
  setContextActions: (
    item: IItem | null,
    containerType: string | null,
    isDepotSystem: boolean,
    isContextMenuDisabled: boolean
  ) => void;
  clearContextActions: () => void;
}

const initialDetailsState: IItemSlotDetailsState = {
  item: null,
  isTooltipVisible: false,
  isTooltipMobileVisible: false,
  isContextMenuVisible: false,
  contextMenuPosition: { x: 0, y: 0 },
  contextActions: [],
  clearContextActions: () => {},
  clearDetailsState: () => {},
};

const ItemSlotDetailsContext = createContext<IItemSlotDetailsContext>({
  detailsState: initialDetailsState,
  updateDetailsState: () => {},
  clearDetailsState: () => {},
  setContextActions: () => {},
  clearContextActions: () => {},
});

export const useItemSlotDetails = (): IItemSlotDetailsContext =>
  useContext(ItemSlotDetailsContext);

interface IProps {
  children: React.ReactNode;
}

export const ItemSlotDetailsProvider: React.FC<IProps> = ({ children }) => {
  const [detailsState, setDetailsState] = useState<IItemSlotDetailsState>(
    initialDetailsState
  );

  const updateDetailsState = useCallback(
    (newState: Partial<IItemSlotDetailsState>): void => {
      setDetailsState(prevState => ({
        ...prevState,
        ...newState,
      }));
    },
    []
  );

  const clearDetailsState = useCallback(() => {
    setDetailsState(initialDetailsState);
  }, [setDetailsState]);

  const setContextActions = useCallback(
    (
      item: IItem | null,
      containerType: string | null,
      isDepotSystem: boolean,
      isContextMenuDisabled: boolean
    ): void => {
      if (item && containerType && !isContextMenuDisabled) {
        const newContextActions = generateContextMenu(
          item,
          containerType as ItemContainerType,
          isDepotSystem
        );
        updateDetailsState({ contextActions: newContextActions });
      } else {
        updateDetailsState({ contextActions: [] });
      }
    },
    []
  );

  const clearContextActions = useCallback(() => {
    updateDetailsState({ contextActions: [] });
  }, [updateDetailsState]);

  const contextValue = useMemo(
    () => ({
      detailsState,
      updateDetailsState,
      clearDetailsState,
      setContextActions,
      clearContextActions,
    }),
    [
      detailsState,
      updateDetailsState,
      clearDetailsState,
      setContextActions,
      clearContextActions,
    ]
  );

  return (
    <ItemSlotDetailsContext.Provider value={contextValue}>
      {children}
    </ItemSlotDetailsContext.Provider>
  );
};
