import React, { useState, useCallback } from 'react';
import { useRef, useMemo } from 'react';

function DragItem({ children, dragData, dragId }) {
  const DragId = useMemo(() => dragId || `dragId-${Math.random()}`, [dragId]);
  const [status, setStatus] = useState('noDrag');
  const [offset, setOffset] = useState([0, 0]);
  const domRef = useRef(null);
  const dragDomTemp = useRef(null);

  const onDragStart = useCallback(
    (event) => {
      const { pageX, pageY } = event;
      const { x, y } = domRef.current.getBoundingClientRect();
      const offsetX = pageX - x;
      const offsetY = pageY - y;

      dragDomTemp.current = domRef.current.cloneNode(true);
      domRef.current.after(dragDomTemp.current);

      //初始化缓存dom位置
      dragDomTemp.current.style.position = 'fixed';
      dragDomTemp.current.style.left = `${event.pageX - offsetX}px`;
      dragDomTemp.current.style.top = `${event.pageY - offsetY}px`;
      dragDomTemp.current.style.draggable = false;
      dragDomTemp.current.style.pointerEvents = 'none';

      setOffset([offsetX, offsetY]);
      setStatus('draging');

      event.dataTransfer.setDragImage(new Image(), 0, 0);
      event.dataTransfer.setData('DATA', JSON.stringify({ ...dragData, DragId }));
    },
    [DragId, dragData]
  );

  const onDragEnd = useCallback(() => {
    dragDomTemp.current.remove();
    setStatus('dragEnd');
  }, []);

  const onDrag = useCallback(
    (e) => {
      if (e.pageX === 0 && e.pageY === 0) {
        return;
      }
      if (e.pageX < offset[2] || e.pageY < offset[3]) {
        return;
      }
      dragDomTemp.current.style.position = 'fixed';
      dragDomTemp.current.style.left = `${e.pageX - offset[0]}px`;
      dragDomTemp.current.style.top = `${e.pageY - offset[1]}px`;
      // console.log(e.pageX, e.pageY, offset);
    },
    [offset]
  );

  return (
    <div
      ref={domRef}
      onDragStart={onDragStart}
      onDrag={onDrag}
      id={DragId}
      draggable={true}
      onDragEnd={onDragEnd}
      style={{
        width: 'max-content',
        opacity: status === 'draging' ? 0.5 : 1,
      }}
    >
      {children}
    </div>
  );
}

export default DragItem;
