import React from 'react';
import PropTypes from 'prop-types';
import ReactTableComponent from './ReactTableComponent';
import { CheckBox } from '../formElements';

export default class CheckedPaginatedTable extends React.Component {
  constructor(props) {
    super(props)
    const initialPage = props.page || 1
    this.state = { selected: {}, selectAll: false, dataStore: { [initialPage]: props.data }, currentPage: initialPage }
    this.usePrimaryKey = !!props.primaryKey
    this.checked = !!props.checkBoxWidth
    this.controlledPagination = props.page && props.pageSize && props.pages && props.fetchData ? true : false
  }

  componentDidMount() {
    this.modifySelected({}, false, this.props.data, this.props.page || 1)
  }

  modifySelected = (selected, selectAll, data, page) => {
    const pageExists = Object.keys(this.state.dataStore).indexOf(String(page)) > -1
    for (var i = 0, l = data.length; i < l; i++) {
      if (!this.props.enabledKey || data[i][this.props.enabledKey] !== false) {
        var key = this.usePrimaryKey ? data[i][this.props.primaryKey] : (this.props.pageSize || 0) * (page - 1) + i
        selected[key] = selected[key] || selectAll
      }
    }
    this.setState({ selected: { ...selected }, selectAll }, () => {
      if (selectAll && !pageExists) this.getSelected()
    })
  }

  modifyData = (storeData, data, page) => {
    storeData[page] = data
    this.setState({ dataStore: { ...storeData } })
  }

  componentWillReceiveProps(np) {
    if (np.page != this.props.page) this.setState({ currentPage: np.page || 1 })
    var page = !np.noCache && np.page || 1
    this.modifyData(this.state.dataStore, np.data, page)

    if (this.props.refreshState && this.props.refreshState(this.props, np)) {
      this.modifySelected({}, false, np.data, page)
    }
    else {
      this.modifySelected(this.state.selected, this.state.selectAll, np.data, page)
    }
  }

  getSelected() {
    var sel = []
    if (this.props.getSelectedKeys) {
      Object.keys(this.state.selected).forEach(key => { this.state.selected[key] && sel.push(key) })
      this.props.getSelectedKeys(sel)
    }
    else if (this.props.getSelectedRows) {
      Object.keys(this.state.selected).forEach((key) => {
        if (this.state.selected[key]) {
          if (this.usePrimaryKey) {
            var flag = 0
            for (var page in this.state.dataStore) {
              var pageData = this.state.dataStore[page]
              for (var i = 0, l = pageData.length; i < l; i++) {
                if (pageData[i][this.props.primaryKey] == key) {
                  sel.push(pageData[i])
                  flag = 1
                  break
                }
              }
              if (flag == 1) break
            }
          }
          else {
            if (this.props.pageSize) {
              sel.push(this.state.dataStore[Math.floor(key / this.props.pageSize) + 1][key % this.props.pageSize])
            }
            else {
              sel.push(this.state.dataStore[1][key])
            }
          }
        }
      })
      this.props.getSelectedRows(sel)
    }
  }

  toggleRow(key) {
    var selected = this.state.selected
    selected[key] = !selected[key]
    this.setState({ selected }, this.getSelected)
  }

  toggleSelectAll = () => {
    var selected = this.state.selected
    for (var key in selected) {
      selected[key] = !this.state.selectAll
    }
    this.setState({ selected, selectAll: !this.state.selectAll }, this.getSelected)
  }

  render() {
    var self = this;
    var { checkBoxWidth, serialNoWidth, primaryKey, columns, enabledKey, enableAll, ...rest } = this.props
    var newColumns = [].concat(columns)
    var origin = self.controlledPagination ? (self.state.currentPage - 1) * self.props.pageSize : 0
    serialNoWidth && newColumns.unshift({
      Header: 'S.No',
      id: 'sNo',
      width: serialNoWidth,
      Cell: row => <div>{(origin + row.viewIndex + 1)}</div>
    })
    self.checked && newColumns.unshift({
      sortable: false,
      width: checkBoxWidth,
      id: "checkbox",
      Cell: ({ original, row }) => {
        var key = self.usePrimaryKey ? original[primaryKey] : self.props.noCache ? row._viewIndex : origin + row._viewIndex
        return (
          <CheckBox
            disabled={original[enabledKey] === false || enableAll === false}
            checked={self.state.selected[key] && !(original[enabledKey] === false || enableAll === false)}
            onChange={() => self.toggleRow(key)}
          />
        )
      },
      Header: x => (
        <CheckBox
          disabled={enableAll === false}
          checked={self.state.selectAll}
          onChange={self.toggleSelectAll.bind(self)}
        />
      )
    })
    return (
      !this.controlledPagination ?
        <ReactTableComponent
          {...rest}
          resizable={false}
          columns={newColumns}
        />
        :
        <ReactTableComponent
          {...rest}
          manual
          page={this.state.currentPage - 1}
          showPagination
          showPageJump={false}
          showPageSizeOptions={false}
          resizable={false}
          columns={newColumns}
          data={self.state.dataStore[!self.props.noCache && self.state.currentPage || 1]}
          onFetchData={(tableState, instance) => {
            if (Object.keys(self.state.dataStore).indexOf(String(instance.state.page + 1)) < 0) {
              //new page
              self.props.fetchData(instance.state.page + 1)
            }
            else if (instance.state.page + 1 != self.state.currentPage) {
              //old page
              if (self.props.noCache) {
                self.props.fetchData(instance.state.page + 1)
              }
              else {
                self.setState({ currentPage: instance.state.page + 1 })
              }
            }
          }}
        />
    )
  }
}

CheckedPaginatedTable.propTypes = {
  data: PropTypes.array,
  columns: PropTypes.array,
  page: PropTypes.number,
  pages: PropTypes.number,
  pageSize: PropTypes.number,
  primaryKey: PropTypes.string,
  checkBoxWidth: PropTypes.number,
  serialNoWidth: PropTypes.number,
  fetchData: PropTypes.func,
  getSelectedKeys: PropTypes.func,
  getSelectedRows: PropTypes.func,
  enabledKey: PropTypes.string,
  enableAll: PropTypes.bool,
  noCache: PropTypes.bool,
}