import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Admin from './../admin'
import Tools from './../../app/assets/javascripts/teachable/tools'
import { rearrangeEntities } from '../actions/index'

interface Entity {
  id: number;
  name: string;
  order: number;
}

interface WebinarObjectProps {
  callback: any;
  clickXButton: any;
  entity: Entity;
  entities: Entity[];
  entityName: string;
  index: number;
  rearrangeEntities: any;
  renderHandle: boolean;
  selectedObjects: any[];
  webinarId: number;
  tableClassName: string;
}

class WebinarObject extends React.Component<WebinarObjectProps, {}> {

  constructor(props) {
    super(props);
  }

  componentDidMount() {
    var tableClassName = this.props.tableClassName;
    $(`.${tableClassName} td`).draggable({
      cursor: '-webkit-grabbing',
      handle: '.handle',
      helper: function() { return '<div></div>'; },
      stop: this.dragEndHandler
    });
    $(`.${tableClassName} .top-drop-zone, .${tableClassName} .drop-zone`).droppable({
      accept: Admin.canIDrop, // note that top-drop-zone and bottom-drop-zone within this component will automatically not be droppable (since they're within the draggable td element), this function is just for the bottom-drop-zone in the component directly above
      tolerance: 'pointer',
      over: this.dragOverHandler,
      out: this.dragOutHandler,
      drop: this.dropHandler.bind(this)
    });
  }

  mouseDownHandler(e) {
    $('.handle, a, input, textarea, .x-button, .nice-select, tr').addClass('grabbing');
    var entity = e.target.parentElement.parentElement;
    entity.classList.add('highlight');
  }

  mouseUpHandler(e) {
    $('.handle, a, input, textarea, .x-button, .nice-select, tr').removeClass('grabbing');
    e.target.parentElement.parentElement.classList.remove('highlight');
  }

  dragOverHandler(e) {
    e.target.classList.add('highlight');
  }

  dragOutHandler(e) {
    e.target.classList.remove('highlight');
  }

  dragEndHandler(e) {
    $('.handle, a, input, textarea, .x-button, .nice-select, tr').removeClass('grabbing');
    $('tr.highlight').removeClass('highlight');
  }

  dropHandler(e, ui) {
    var draggedIndex = ui.draggable.attr('id').split('-')[1];
    var dropZoneIndex = e.target.dataset.index;
    $('.highlight').removeClass('highlight');
    var currentOrder = {};
    this.props.entities.forEach((entity) => {
      currentOrder[entity.order] = entity.id;
    });
    var newOrder = Tools.rearrangeFields(currentOrder, draggedIndex, dropZoneIndex);
    this.props.rearrangeEntities({
      directory: 'webinar_objects',
      newOrder,
      additionalData: {
        webinarId: this.props.webinarId,
        objektName: this.props.entityName
      }
    }).then(() => {
      this.props.callback.call(this, this.props.selectedObjects, this.props.entityName);
    });
  }

  render() {
    return(
      <tr>
        <td id={ "index-" + this.props.entity.order } className="name-column" data-index={ this.props.entity.order }>
          { this.renderTopDropZone() }
          <div>
            { this.props.entity.name }
          </div>
          <img className="handle" src={ window.Images.handle } onMouseDown={ this.mouseDownHandler } onMouseUp={ this.mouseUpHandler } />
          <div className="x-button" onClick={ this.props.clickXButton.bind(this) } data-id={ this.props.entity.id }></div>
          { this.renderBottomDropZone() }
        </td>
      </tr>
    );
  }

  renderTopDropZone() {
    return(
      <div className={ "top-drop-zone" + (this.props.entity.order == 0 ? '' : ' hidden') } data-index={ "-1" }></div>
    );
  }

  renderBottomDropZone() {
    return(
      <div className="drop-zone" data-index={ this.props.entity.order }></div>
    );
  }
}

const mapStateToProps = (reducers, props) => {
  return reducers.standardReducer;
};

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ rearrangeEntities }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(WebinarObject);
