import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Modal from 'react-modal'
import Admin from './../admin'
import { fetchEntities } from '../actions/index'
import ObjectNew from './object-new'
import _ from 'lodash'

const maxColumns = 6;
const maxTextChars = 30;

interface ObjectsIndexProps {
  fetchEntities: any;
  fields: any[];
  objects: any[];
  templateEditable: boolean;
  templateName: string;
  templatePlural: string;
}

interface ObjectsIndexState extends ComponentState {
  fields: any[]
  modalOpen?: boolean
  modalStyles: any
  objects: any[]
  searchColumn: number
  templateEditable?: boolean
  templateName: string
  templatePlural: string
}

class ObjectsIndex extends React.Component<ObjectsIndexProps, ObjectsIndexState> {

  constructor(props) {
    super(props);
    this.state = {
      fetching: true,
      templateName: "",
      templatePlural: "",
      fields: [],
      objects: [],
      searchText: "",
      searchColumn: 0,
      modalStyles: {
        overlay: {
          background: 'rgba(0, 0, 0, 0.50)'
        },
        content: {
          background: '#F5F6F7',
          padding: 0,
          margin: 'auto',
          maxWidth: 1000,
          height: 123,
          maxHeight: '90%'
        }
      }
    };
  }

  componentDidMount() {
    let templateId = window.location.pathname.split("/")[3];
    this.props.fetchEntities({ url: `/admin/api/templates/${templateId}/all` }).then(() => {
      this.setState({
        fetching: false,
        templateName: this.props.templateName,
        templatePlural: this.props.templatePlural,
        templateEditable: this.props.templateEditable,
        objects: this.props.objects,
        fields: this.props.fields
      });
    });
  }

  redirect(id) {
    window.location.pathname = "admin/objects/" + id;
  }

  clickNew() {
    this.setState({ modalOpen: true });
  }

  closeModal() {
    let modalStyles = this.state.modalStyles;
    modalStyles.content.height = 123;
    this.setState({
      modalOpen: false,
      modalStyles: modalStyles
    });
  }

  updateModalHeight(fields) {
    let baseHeight = 74;
    let buttonHeight = 47;
    let height = baseHeight + buttonHeight;
    this.state.fields.forEach(function(field) {
      if (field.fieldType == "image") {
        height += 201;
      } else if (field.fieldType == "text") {
        var rows = Math.ceil(Admin.calculateFieldWidth(field) / 2000);
        if (rows === 1) {
          height += 119;
        } else if (rows === 2) {
          height += 141;
        } else {
          height += (141 + (17 * (rows - 2)));
        }
      } else {
        height += 119;
      }
    });
    let modalStyles = this.state.modalStyles;
    modalStyles.content.height = height;
    this.setState({
      modalStyles: modalStyles
    });
  }

  filterSearchText() {
    if (this.state.searchText !== '') {
      var re = new RegExp(this.state.searchText, 'i');
      return this.state.objects.filter((object) => {
        return re.test(object.fields[this.state.searchColumn]);
      });
    } else {
      return this.state.objects;
    }
  }

  objectSort(object) {
    var property = object.fields[this.state.searchColumn];
    return property.toLowerCase();
  }

  successCallback(objects) {
    this.setState({
      modalOpen: false,
      objects
    });
  }

  render() {
    var filteredObjects = this.filterSearchText.call(this);
    return(
      <div id="objects-index" className="component">
        <div className="clearfix">
          <h1 className="search-box-header">{ this.state.templatePlural }</h1>
          { this.renderAddButton() }
          <input className={ `search-box${this.state.templateEditable ? ' margin' : ''}` } onChange={ Admin.changeSearchText.bind(this) } value={ this.state.searchText } />
        </div>
        <div className="white-box">
          { Admin.renderSpinner(this.state.fetching) }
          { Admin.renderGrayedOut(this.state.fetching) }
          <table className="admin-table">
            <thead>
              <tr>
                { this.state.fields.map((field, index) => {
                  if (index < maxColumns) {
                    if (field.fieldType === 'text' || field.fieldType === 'number') {
                      return(
                        <th key={ index }><div className={ Admin.sortClass.bind(this)(index) } onClick={ Admin.clickHeader.bind(this, index) }>{ field.name }</div></th>
                      );
                    } else {
                      return(
                        <th key={ index }>{ field.name }</th>
                      );
                    }
                  } else {
                    return null;
                  }
                }) }
              </tr>
            </thead>
            <tbody>
              <tr>
                { this.state.fields.map((field, index) => {
                  if (index < maxColumns) {
                    return(
                      <td key={ index }></td>
                    );
                  } else {
                    return null;
                  }
                }) }
              </tr>
              { _.sortBy(filteredObjects, [this.objectSort.bind(this)]).map((object, index) => {
                return(
                  <tr key={ index } onClick={ this.redirect.bind(this, object.id) }>
                    { object.fields.map((value, index) => {
                      if (index < maxColumns) {
                        if (this.state.fields[index].fieldType == "image") {
                          if (value) {
                            return(
                              <td key={ index }>
                                <img src={ value } className="uploaded-image" />
                              </td>
                            );
                          } else {
                            return(
                              <td key={ index }>
                                <div className="empty-table-image"></div>
                              </td>
                            );
                          }
                        } else {
                          if (value.length > maxTextChars) {
                            value = value.slice(0, maxTextChars) + "...";
                          }
                          return(
                            <td key={ index }>
                              { value }
                            </td>
                          )
                        }
                      } else {
                        return null;
                      }
                    }) }
                  </tr>
                );
              }) }
            </tbody>
          </table>
        </div>
        <Modal isOpen={ this.state.modalOpen } onRequestClose={ this.closeModal.bind(this) } contentLabel="Modal" style={ this.state.modalStyles }>
          <ObjectNew templateId={ window.location.pathname.split("/")[3] } templateName={ this.state.templateName } updateModalHeight={ this.updateModalHeight.bind(this) } successCallback={ this.successCallback.bind(this) } />
        </Modal>
      </div>
    );
  }

  renderAddButton() {
    if (this.state.templateEditable) {
      return(
        <a className={ "orange-button float-button btn" + Admin.renderDisabledButtonClass(this.state.fetching) } onClick={ this.clickNew.bind(this) }>Add New</a>
      );
    } else {
      return null;
    }
  }

  componentDidUpdate() {
    $('.match-height-layout').matchHeight();
  }
}

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

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

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