import { IItem } from '@rpg-engine/shared';
import React, {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState,
} from 'react';
import { IPosition } from '../../../../types/eventTypes';

interface IDraggingState {
  item: IItem | null;
  isDragging: boolean;
  position: IPosition;
  dropPosition: IPosition | null;
  isFocused: boolean;
  draggingDistance: number;
}

interface IDraggingContext {
  draggingState: IDraggingState;
  updateDraggingState: (newState: Partial<IDraggingState>) => void;
  clearDraggingState: () => void;
}

const initialDraggingState: IDraggingState = {
  item: null,
  isDragging: false,
  position: { x: 0, y: 0 },
  dropPosition: null,
  isFocused: false,
  draggingDistance: 0,
};

const ItemSlotDraggingContext = createContext<IDraggingContext>({
  draggingState: initialDraggingState,
  updateDraggingState: () => {},
  clearDraggingState: () => {},
});

export const useItemSlotDragging = (): IDraggingContext =>
  useContext(ItemSlotDraggingContext);

interface IProps {
  children: React.ReactNode;
}

export const ItemSlotDraggingProvider: React.FC<IProps> = ({ children }) => {
  const [draggingState, setDraggingState] = useState<IDraggingState>(
    initialDraggingState
  );

  const updateDraggingState = useCallback(
    (newState: Partial<IDraggingState>): void => {
      setDraggingState(prevState => ({
        ...prevState,
        ...newState,
      }));
    },
    []
  );

  const clearDraggingState = useCallback(() => {
    setDraggingState(initialDraggingState);
  }, []);

  const contextValue = useMemo(
    () => ({
      draggingState,
      updateDraggingState,
      clearDraggingState,
    }),
    [draggingState, updateDraggingState, clearDraggingState]
  );

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