import React, {
  cloneElement,
  HTMLAttributes,
  isValidElement,
  MutableRefObject,
  ReactElement,
  ReactNode,
} from 'react';
import { NestedTableDragAndDropState } from './NestedTableDragAndDropState';
import { NestedTableDragAndDropOverlayPopover } from './NestedTableDragAndDropOverlayPopover';
import { MultipleDragOverlayEffect } from './MultipleDragOverlayEffect';
import { observer } from 'mobx-react-lite';

export interface NestedTableDragAndDropOverlayProps<C extends string>
  extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
  state: NestedTableDragAndDropState<C>;
  innerRef?:
    | ((instance: HTMLDivElement | null) => void)
    | MutableRefObject<HTMLDivElement | null>
    | null;
}

function _NestedTableDragAndDropOverlay<C extends string>(
  props: NestedTableDragAndDropOverlayProps<C>,
) {
  const { state, children, innerRef, style, ...rest } = props;
  const { activeNode } = state;
  return (
    <div
      data-hook="nested-table-dnd-overlay-wrapper"
      ref={innerRef}
      {...rest}
      style={{
        ...style,
        opacity: undefined,
      }}
    >
      {activeNode && !activeNode.collection.result.isEmpty && (
        <MultipleDragOverlayEffect style={style} {...rest} />
      )}
      <NestedTableDragAndDropOverlayPopover state={state}>
        {isValidElement(children)
          ? cloneElement(
              children as ReactElement<HTMLAttributes<HTMLElement>>,
              {
                style: {
                  ...children.props.style,
                  opacity: style?.opacity,
                },
              },
            )
          : children}
      </NestedTableDragAndDropOverlayPopover>
    </div>
  );
}

export const NestedTableDragAndDropOverlay = observer(
  _NestedTableDragAndDropOverlay,
);
