import React, { useEffect, useState } from 'react';

import theme from '../../helpers/theme';
import useCursorPosition from '../../hooks/useCursorPosition';
import { getAbsoluteCoordinate } from '../../helpers/position';

import { SVG, Circle } from './styled';

type Props = LinePositionType & {
  top: number;
  left: number;
  width: number;
  height: number;
  onMove: (position: LinePositionType) => void;
  onClick?: (event: React.MouseEvent) => void;
  completeStart: PointType;
  completeEnd: PointType;
};

const MARGIN_DISTANCE = 18;

const initState = {
  start: { x: 0, y: 0 },
  end: { x: 0, y: 0 },
  operator: '',
  clickX: 0,
  clickY: 0,
};

const OuterRect: React.FC<Props> = ({
  top,
  left,
  width,
  height,
  start,
  end,
  onMove,
  onClick,
  completeStart,
  completeEnd,
}: Props) => {
  const [state, setState] = useState(initState);
  const [cursorPosition, setRef] = useCursorPosition(20);

  const handleMouseDown = (e: React.MouseEvent): void => {
    const operatorId = (e.target as HTMLElement).getAttribute(
      'data-id',
    ) as string;
    const coord = getAbsoluteCoordinate(document.body, e);

    setRef(document.body);
    setState({
      start,
      end,
      operator: operatorId,
      clickX: coord.x,
      clickY: coord.y,
    });
  };

  const handleMouseUp = (): void => {
    setRef(null);
    setState(initState);
  };

  useEffect(() => {
    if (cursorPosition.x && cursorPosition.y) {
      if (state.operator === 'start') {
        const x1 = cursorPosition.x - (state.clickX - state.start.x);
        const y1 = cursorPosition.y - (state.clickY - state.start.y);

        onMove({
          start: { x: x1, y: y1 },
          end,
        });
      } else if (state.operator === 'end') {
        const x2 = cursorPosition.x - (state.clickX - state.end.x);
        const y2 = cursorPosition.y - (state.clickY - state.end.y);

        onMove({
          start,
          end: { x: x2, y: y2 },
        });
      } else if (state.operator === 'move') {
        const x1 = cursorPosition.x - (state.clickX - state.start.x);
        const y1 = cursorPosition.y - (state.clickY - state.start.y);
        const x2 = cursorPosition.x - (state.clickX - state.end.x);
        const y2 = cursorPosition.y - (state.clickY - state.end.y);

        onMove({
          start: { x: x1, y: y1 },
          end: { x: x2, y: y2 },
        });
      }
    }
  }, [cursorPosition, state]);

  useEffect(() => {
    window.addEventListener('mouseup', handleMouseUp);

    return (): void => {
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);

  return (
    <SVG
      data-id="move"
      viewBox={`${left} ${top} ${width + 10} ${height + 10}`}
      style={{
        left: `${left - MARGIN_DISTANCE}px`,
        top: `${top - MARGIN_DISTANCE}px`,
        width: `${width + 10}px`,
        height: `${height + 10}px`,
      }}
      onClick={onClick}
      onMouseDown={handleMouseDown}
    >
      <Circle
        data-id="start"
        onMouseDown={handleMouseDown}
        fill={theme.colors.primary}
        cx={completeStart.x + MARGIN_DISTANCE}
        cy={completeStart.y + MARGIN_DISTANCE}
        r={6}
      />
      <Circle
        data-id="end"
        onMouseDown={handleMouseDown}
        fill={theme.colors.primary}
        cx={completeEnd.x + MARGIN_DISTANCE}
        cy={completeEnd.y + MARGIN_DISTANCE}
        r={6}
      />
    </SVG>
  );
};

export default OuterRect;
