import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'react/lib/update';

import SortableItem from './SortableItem';

import './sortable.scss';

/*
 * Based on
 * https://github.com/react-dnd/react-dnd/tree/master/examples/04%20Sortable/Simple
 */
const propTypes = {
  /** @ignore */
  className: PropTypes.string,
  list: PropTypes.array,
  keyProp: PropTypes.string,
  children: PropTypes.func,
  onChange: PropTypes.func.isRequired,
  listName: PropTypes.string.isRequired
};

const defaultProps = {
  list: [],
  keyProp: null,
  className: undefined,
  children: null
};

class SortableList extends Component {
  state = {
    list: this.props.list
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ list: nextProps.list });
  }

  moveItem = (dragIndex, hoverIndex) => {
    const { list } = this.state;
    const dragItem = list[dragIndex];

    const newList = update(list, {
      $splice: [
        [dragIndex, 1],
        [hoverIndex, 0, dragItem]
      ]
    });
    this.setState({ list: newList });
  }

  endDrag = () => {
    const { list } = this.state;
    const { onChange } = this.props;
    onChange(list);
  }

  render() {
    const { list } = this.state;
    const { children, keyProp, className, listName } = this.props;

    return (
      <div className={className}>
        {
          list.map((item, i) => (
            <SortableItem
              styleName="sortable--item"
              key={item[keyProp]}
              listName={listName}
              index={i}
              moveItem={this.moveItem}
              endDrag={this.endDrag}
            >
              {children(item, i)}
            </SortableItem>
          ))
        }
      </div>
    );
  }
}


SortableList.propTypes = propTypes;
SortableList.defaultProps = defaultProps;

export default DragDropContext(HTML5Backend)(SortableList);
