import React, {
  useCallback, useRef, useState, useContext,
} from 'react';
import PropTypes from 'prop-types';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { useId } from '@reach/auto-id';

const propTypes = {
  children: PropTypes.node,
  /**
  * onDragEnd({ oldIndex, newIndex })
  */
  onDragEnd: PropTypes.func,
};
const defaultProps = {
  children: '',
  onDragEnd: () => {},
};

export const DragContainerContext = React.createContext({});

export const useDragContainerContext = () => useContext(DragContainerContext);

export const PipelineDragContainer = ({ children, onDragEnd }) => {
  const id = useId();
  const containerRef = useRef();
  const [isDragging, setIsDragging] = useState(false);
  const [placeholderStyle, setPlaceholderStyle] = useState({
    width: 0,
    height: 0,
  });

  const handleDragStart = useCallback(() => {
    setIsDragging(true);
  }, []);

  const handleDragEnd = useCallback(({ source, destination }) => {
    setIsDragging(false);

    if (!destination) {
      return;
    }

    onDragEnd({ oldIndex: source.index, newIndex: destination.index });
  }, []);

  return (
    <DragContainerContext.Provider
      value={{
        containerEl: containerRef.current,
        setPlaceholderStyle,
        isDragging,
      }}
    >
      <DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
        <Droppable
          droppableId={`droppable-${id}`}
          direction="horizontal"
        >
          {(provided) => (
            <div
              ref={(el) => {
                provided.innerRef(el);
                containerRef.current = el;
              }}
              className="sui-prj-pipeline-drag-list"
              {...provided.droppableProps}
            >
              {children}
              {isDragging && (
                <div
                  style={{
                    width: placeholderStyle.width || 0,
                    height: placeholderStyle.height || 0,
                  }}
                />
              )}
              <div style={{ display: 'none' }}>
                {provided.placeholder}
              </div>
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </DragContainerContext.Provider>
  );
};

PipelineDragContainer.propTypes = propTypes;
PipelineDragContainer.defaultProps = defaultProps;
