import PropTypes from 'prop-types';
import { Box, Divider, IconButton, Typography } from '@mui/material';
import { useRef, useState } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { Icon } from '@iconify/react';
import DragIndicatorIcon from '@iconify-icons/material-symbols/drag-indicator';
import KeyboardArrowDownRoundedIcon from '@iconify-icons/material-symbols/keyboard-arrow-down-rounded';
import { useMemoizedFn } from 'ahooks';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
export default function DragItem({
  // eslint-disable-next-line no-unused-vars
  id,
  title,
  children,
  index,
  onMove,
  defaultExpand = false,
  onEnd,
  icon = null
}) {
  const [expand, setExpand] = useState(defaultExpand);
  const dropRef = useRef(null);
  const dragRef = useRef(null);
  const [{
    handlerId
  }, drop] = useDrop({
    accept: 'dragItem',
    collect(monitor) {
      return {
        handlerId: monitor.getHandlerId()
      };
    },
    hover(item, monitor) {
      if (!dropRef.current) {
        return;
      }
      const dragIndex = item.index;
      const hoverIndex = index;
      // Don't replace items with themselves
      if (dragIndex === hoverIndex) {
        return;
      }
      // Determine rectangle on screen
      const hoverBoundingRect = dropRef.current?.getBoundingClientRect();
      const dragBoundingRect = dragRef.current?.getBoundingClientRect();
      // 需要拖动多少距离才能触发位置变更
      const dragY = (dragBoundingRect.bottom - dragBoundingRect.top) / 2;
      // Determine mouse position
      const clientOffset = monitor.getClientOffset();
      // Get pixels to the top
      const hoverClientY = clientOffset.y - hoverBoundingRect.top;
      // Only perform the move when the mouse has crossed half of the items height
      // When dragging downwards, only move when the cursor is below 50%
      // When dragging upwards, only move when the cursor is above 50%
      // Dragging downwards
      if (dragIndex < hoverIndex && hoverClientY < dragY) {
        return;
      }
      // Dragging upwards
      if (dragIndex > hoverIndex && hoverClientY > dragY) {
        return;
      }
      // Time to actually perform the action
      onMove(dragIndex, hoverIndex);
      // Note: we're mutating the monitor item here!
      // Generally it's better to avoid mutations,
      // but it's good here for the sake of performance
      // to avoid expensive index searches.
      item.index = hoverIndex;
    }
  });
  const [{
    isDragging
  }, drag] = useDrag({
    item: {
      index,
      type: 'dragItem'
    },
    collect: monitor => ({
      isDragging: monitor.isDragging()
    }),
    end: onEnd
  });
  drag(dragRef);
  drop(dropRef);
  const opacity = isDragging ? 0.5 : 1;
  const toggleExpand = useMemoizedFn(e => {
    e.preventDefault();
    e.stopPropagation();
    setExpand(!expand);
  });
  return /*#__PURE__*/_jsxs(Box, {
    ref: dropRef,
    children: [/*#__PURE__*/_jsxs(Box, {
      sx: {
        cursor: 'pointer',
        '&:hover': {
          backgroundColor: 'grey.100'
        }
      },
      ref: dragRef,
      "data-handler-id": handlerId,
      children: [/*#__PURE__*/_jsxs(Box, {
        sx: {
          py: 2,
          px: 1,
          opacity,
          display: 'flex',
          alignItems: 'center',
          gap: 0.5
        },
        draggable: false,
        onClick: toggleExpand,
        children: [/*#__PURE__*/_jsx(Box, {
          sx: {
            pointerEvents: 'auto',
            cursor: 'grab',
            '&:active': {
              cursor: 'grabbing'
            },
            fontSize: 0,
            color: 'text.hint',
            '&:hover': {
              color: 'text.secondary'
            }
          },
          children: /*#__PURE__*/_jsx(Icon, {
            fontSize: 20,
            icon: DragIndicatorIcon
          })
        }), /*#__PURE__*/_jsx(Box, {
          sx: {
            display: 'flex',
            alignItems: 'center',
            flexShrink: 0,
            mr: 0.5,
            // HACK: 图标与文字在视觉上是不居中的，通过偏移来调整，优化视觉体验
            transform: 'translateY(-1px)'
          },
          children: icon
        }), /*#__PURE__*/_jsx(Typography, {
          sx: {
            flex: 1
          },
          children: title
        }), /*#__PURE__*/_jsx(IconButton, {
          size: "small",
          sx: {
            pointerEvents: 'auto',
            transform: expand ? '' : 'rotate(180deg)',
            transition: 'transform 0.3s ease'
          },
          children: /*#__PURE__*/_jsx(Icon, {
            icon: KeyboardArrowDownRoundedIcon,
            style: {
              transform: 'scale(1.5)'
            }
          })
        })]
      }), /*#__PURE__*/_jsx(Divider, {})]
    }), /*#__PURE__*/_jsx(Box, {
      sx: {
        pl: 4,
        py: 2.5,
        display: expand ? 'block' : 'none'
      },
      children: children
    })]
  });
}
DragItem.propTypes = {
  title: PropTypes.string.isRequired,
  id: PropTypes.string.isRequired,
  children: PropTypes.node.isRequired,
  index: PropTypes.number.isRequired,
  onMove: PropTypes.func.isRequired,
  onEnd: PropTypes.func.isRequired,
  defaultExpand: PropTypes.bool,
  icon: PropTypes.any
};