import { GRID_HEIGHT, GRID_WIDTH } from '@rpg-engine/shared';
import { useCallback, useEffect, useState } from 'react';
import { IPosition } from '../types/eventTypes';

interface ICursorPositionProps {
  scale?: number;
}

export const useCursorPosition = ({ scale = 1 }: ICursorPositionProps): IPosition => {
  const [position, setPosition] = useState<IPosition>({ x: 0, y: 0 });

  const scalePosition = useCallback((x: number, y: number): IPosition => {
    return {
      x: ((x - GRID_WIDTH / 2) / scale) + GRID_WIDTH / 2,
      y: ((y - GRID_HEIGHT / 2) / scale) + GRID_HEIGHT / 2,
    };
  }, [scale]);

  const setFromEvent = useCallback((e: MouseEvent | TouchEvent) => {
    let x, y;

    if ('touches' in e) {
      x = e.touches[0].clientX;
      y = e.touches[0].clientY;
    } else {
      x = e.clientX;
      y = e.clientY;
    }

    const scaledPosition = scalePosition(x, y);
    setPosition(scaledPosition);
  }, [scale, scalePosition]);

  const cleanup = useCallback(() => {
    setPosition({ x: 0, y: 0 });
  }, []);

  useEffect(() => {
    const handleEvent = (e: Event) => setFromEvent(e as MouseEvent | TouchEvent);

    window.addEventListener('mousemove', handleEvent);
    window.addEventListener('touchmove', handleEvent);
    window.addEventListener('mouseup', cleanup);
    window.addEventListener('touchend', cleanup);

    return () => {
      window.removeEventListener('mousemove', handleEvent);
      window.removeEventListener('touchmove', handleEvent);
      window.removeEventListener('mouseup', cleanup);
      window.removeEventListener('touchend', cleanup);
    };
  }, [setFromEvent, cleanup]);

  return position;
};
