import react, { useState } from 'react';
import './Map.css';

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

interface MouseHandlerProperties {
  boardSize: number;
  shift: Point;
  addShift: (shift: Point) => void;
  zoom: number;
  addZoom: (zoomFactor: number, center: Point, deltaShift?: Point) => void;
  children?: any;
}

const MouseHandler: react.FC<MouseHandlerProperties> = (
  props: MouseHandlerProperties
) => {
  const initialMouseState = {
    down: false,
    starting: { x: -1, y: -1 },
    timestamp: 0,
  };

  const [mouseState, setMouseState] = useState(initialMouseState);

  // console.log('MouseHandler, mouseState: ' + JSON.stringify(mouseState));
  // console.log(
  //   'MouseHandler, shift: ' +
  //     JSON.stringify(props.shift) +
  //     ', zoom:' +
  //     props.zoom
  // );

  const genericHandler = (event: any) => {
    // console.log(`Log - Event:  ${event.type}`);
    // if (event.pageX !== undefined) {
    //   console.log(
    //     `Mouse : ${event.pageX}, ${event.pageY}, target: ${event.target}`
    //   );
    //   console.log(
    //     `mouseState: ' ${JSON.stringify(mouseState)} (+${
    //       Date.now() - mouseState.timestamp
    //     }ms) `
    //   );
    //   return;
    //}
  };

  const mouseLeaveHandler = (event: any) => {
    genericHandler(event);
    setMouseState(initialMouseState);
  };

  const mouseDownHandler = (event: any) => {
    genericHandler(event);
    setMouseState({
      down: true,
      starting: { x: event.pageX, y: event.pageY },
      timestamp: Date.now(),
    });
  };

  const mouseUpHandler = (event: any) => {
    genericHandler(event);
    setMouseState(initialMouseState);
  };

  const mouseMoveHandler = (event: any) => {
    if (mouseState.down && Date.now() - mouseState.timestamp > 5) {
      genericHandler(event);
      //console.log(
      //   `dispatch ${JSON.stringify({
      //     x: event.pageX - mouseState.starting.x,
      //     y: event.pageY - mouseState.starting.y,
      //   })}`
      // );
      props.addShift({
        x: event.pageX - mouseState.starting.x,
        y: event.pageY - mouseState.starting.y,
      });
      setMouseState({
        down: true,
        starting: {
          x: event.pageX,
          y: event.pageY,
        },
        timestamp: Date.now(),
      });
    }
  };

  const doubleClickHandler = (event: any) => {
    genericHandler(event);
    props.addZoom(Math.SQRT2, { x: event.pageX, y: event.pageY });
  };

  const initialWheelState = {
    timestamp: 0,
  };

  const [wheelState, setWheelState] = useState(initialWheelState);

  const wheelEventHandler = (event: any) => {
    genericHandler(event);
    if (
      event.deltaMode === WheelEvent.DOM_DELTA_PIXEL &&
      Date.now() - wheelState.timestamp > 100
    ) {
      props.addZoom(event.deltaY < 0 ? Math.SQRT2 : Math.SQRT1_2, {
        x: event.pageX,
        y: event.pageY,
      });

      setWheelState({
        timestamp: Date.now(),
      });
    }
  };

  return (
    <div
      className='handler'
      onMouseDown={mouseDownHandler}
      onMouseMove={mouseMoveHandler}
      onMouseUp={mouseUpHandler}
      onMouseLeave={mouseLeaveHandler}
      onDoubleClick={doubleClickHandler}
      onWheel={wheelEventHandler}
    >
      {' '}
      {props.children === undefined ? <></> : props.children}
    </div>
  );
};

export default MouseHandler;
