import React from 'react'
import { SortableContainer, SortableElement } from 'react-sortable-hoc'
import { Grid, makeStyles } from '@material-ui/core'

const useStyles = makeStyles({
  // Fixing some spotty behavior with the cursor style changing when dragging an item
  // See this issue for more info: https://github.com/clauderic/react-sortable-hoc/issues/212
  pointerEventsFix: {
    pointerEvents: 'auto !important'
  },
  widgetsContainer: {
    zIndex: 10,
    width: '100%',
    margin: 0
  }
})

const DraggableWidgetContainer = SortableElement(
  ({ Component, payload, ...props }) => {
    // Merge props from general props and from payload
    // Add first the payload values, so them cannot overwrite the ones from props
    return (
      <Grid item xs={12} sm={6} md={4} lg={3}>
        <Component {...payload} {...props} />
      </Grid>
    )
  }
)

const DraggableWidgetsList = SortableContainer(
  ({ items: widgets, ...props }) => {
    const classes = useStyles()

    return (
      <Grid container spacing={3} className={classes.widgetsContainer}>
        {widgets.map(({ id, Component, payload }, index) => {
          // Use `id` for the key to optimize renders on reorder
          // The SortableElements will use the map method's index for sorting
          // Passthrough `id`, `Component` and `payload`
          return (
            <DraggableWidgetContainer
              key={id}
              index={index}
              {...props}
              {...{ id, Component, payload }}
            />
          )
        })}
      </Grid>
    )
  }
)

const SortableWidgetContainer = ({ widgets, onReorder, ...props }) => {
  const classes = useStyles()

  // Handle reordering of widgets after dragging and dropping
  const onSortEnd = ({ oldIndex, newIndex }) => {
    onReorder(oldIndex, newIndex)
  }

  return (
    <DraggableWidgetsList
      axis='xy'
      items={widgets}
      helperClass={classes.pointerEventsFix}
      onSortEnd={onSortEnd}
      useDragHandle
      {...props}
    />
  )
}

export default SortableWidgetContainer