import React from 'react'
import Modal from 'react-modal'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import isEqual from 'lodash/isEqual'
import cloneDeep from 'lodash/cloneDeep'
import ConfirmDelete from './confirm-delete'
import Template from './util/template'
import Admin from './../admin'
import { ConfirmDeleteModalStyles } from './helpers/modal-styles'
import { fetchEntity, createEntity, updateEntity, deleteEntity } from '../actions/index'
import { withExitPrompt } from './util/with-exit-prompt'

interface PartialDetailsProps {
  deleteEntity: any;
  errors: string[];
  fetchEntity: any;
  fields: string[];
  partial: any;
  partial_errors: string[];
  partialSaved: any;
  templates: any;
  updateEntity: any;
}

interface PartialDetailsState {
  changesToSave: boolean;
  deleteModalOpen: boolean;
  errors: {
    fields: any;
    partial_errors: string[];
  }
  fetching: boolean;
  fieldRefs: any;
  fields: any;
  fieldsSaved: any;
  partial: any;
  partialSaved: any;
  templates: any;
  saveButtonRef?: any;
}

class PartialDetails extends React.Component<PartialDetailsProps, PartialDetailsState> {

  constructor(props) {
    super(props);
    this.state = {
      changesToSave: false,
      deleteModalOpen: false,
      fetching: true,
      partial: {},
      partialSaved: {},
      fieldRefs: {},
      fields: [],
      fieldsSaved: [],
      errors: {
        partial_errors: [],
        fields: []
      },
      templates: []
    };
  }

  componentDidMount() {
    let pathDirectories = window.location.pathname.split('/');
    this.props.fetchEntity({
      id: pathDirectories[pathDirectories.length - 1],
      directory: "partials",
      entityName: "partial"
    }).then(() => {
      let errors = {
        fields: Array(this.props.fields.length).fill([]),
        partial_errors: []
      };
      this.setState({
        fetching: false,
        partial: this.props.partial,
        partialSaved: cloneDeep(this.props.partial),
        errors,
        fields: this.props.fields,
        fieldsSaved: cloneDeep(this.props.fields),
        templates: this.props.templates
      }, () => {
        Admin.setUpNiceSelect({ selector: 'select', func: Admin.changeField.bind(this, this.changeFieldArgs()) });
      });
    });
  }

  changeFieldArgs() {
    return {
      thing: "partial",
      errorsArray: this.state.errors["partial_errors"],
      changesFunction: this.checkForChanges.bind(this)
    };
  }

  checkForChanges() {
    return !isEqual(this.state.partial, this.state.partialSaved);
  }

  clickSave() {
    let fields = Template.getUpdatedFieldsArray.call(this);
    this.setState({
      fetching: true,
      fields: fields
    }, () => {
      let pathDirectories = window.location.pathname.split('/');
      this.props.updateEntity({
        id: pathDirectories[pathDirectories.length - 1],
        directory: "partials",
        entityName: "partial",
        entity: this.state.partial,
        additionalData: {
          fields: Template.convertFieldsToSnakeCase(fields)
        }
      }).then(() => {
        this.setState({
          fetching: false,
          partial: this.props.partial,
          partialSaved: cloneDeep(this.props.partial),
          fields: this.props.fields,
          fieldsSaved: cloneDeep(this.props.fields),
          changesToSave: false
        }, () => {
          this.state.saveButtonRef.resetChangesToSave();
        });
      }, () => {
        this.setState({
          fetching: false,
          errors: {
            partial_errors: this.props.partial_errors,
            fields: this.props.fields
          }
        });
      });
    });
  }

  render() {
    return(
      <div id='partial-details' className='component'>
        <h1>Partial Details</h1>
        <div className="white-box">
          { Admin.renderSpinner(this.state.fetching) }
          { Admin.renderGrayedOut(this.state.fetching) }
          <div className="row">
            { Admin.renderImageField.bind(this)({
              columnWidth: 3,
              entity: "partial",
              property: "imageId",
              imageUrlProperty: "imageUrl",
              columnHeader: "Image",
              createImageRecord: true })
            }
            { Admin.renderField.bind(this)({ columnWidth: 7, entity: "partial", property: "name", errorsArray: this.state.errors.partial_errors }) }
            { Admin.renderBooleanDropDown.bind(this)({ columnWidth: 2, entity: "partial", property: "devsOnly" }) }
          </div>
          { Template.renderFieldsZone.call(this, this.state.templates) }
          { Template.renderButtons.call(this) }
          <Modal isOpen={ this.state.deleteModalOpen } onRequestClose={ Admin.closeDeleteModal.bind(this) } contentLabel='Modal' style={ ConfirmDeleteModalStyles }>
            <ConfirmDelete entityId={ this.state.partial.id } entityName="partial" entityDirectory="partials" closeModal={ Admin.closeDeleteModal.bind(this) } closeAndFetch={ Admin.closeDeleteModalAndFetch.bind(this) } delete={ Admin.deleteEntity.bind(this) } />
          </Modal>
        </div>
      </div>
    );
  }

  componentDidUpdate() {
    $('.match-height-layout').matchHeight();
    Admin.resetNiceSelect({
      selector: '#active-dropdown',
      func: Admin.changeField.bind(this, this.changeFieldArgs())
    });
  }
}

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

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchEntity, createEntity, updateEntity, deleteEntity }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(withExitPrompt(PartialDetails));
