import React, { Component } from 'react'
import { string, func, arrayOf, object, oneOf } from 'prop-types'
import classnames from 'classnames'
import { Table, Header, HeadCell, Body, Row, Cell } from '@swrve/core'
import { Icon } from '@swrve/icons'
import { sortByFunc, ASC, DES } from './helpers'

class SortableTable extends Component {
  constructor(props) {
    super(props)
    this.state = {
      sortBy: '',
      order: ASC
    }
    this.toggleSortReducer = this.toggleSortReducer.bind(this)
  }

  // Add onChange here - so that you can wire this into a redux state.
  toggleSortReducer(sortBy) {
    return this.setState({
      sortBy,
      order: this.state.order === DES ? ASC : DES
    })
  }

  render() {
    const { renderHeader, renderCell, className, cols, rows, sortByFunc, schema } = this.props

    const sortBy = this.props.sortBy || this.state.sortBy
    const order = this.props.order || this.state.order

    return (
      <div className={classnames('sw-sortable-table', className)}>
        <Table type="light">
          <Header>
            {cols.map(p => (
              <HeadCell className="p-4 text-left group cursor-pointer" key={p}>
                <div
                  className={classnames(
                    'flex justify-between items-center group-hover:text-pickledBlack',
                    p === sortBy
                      ? 'text-gauloiseBlue-100 group-hover:text-gauloiseBlue-120'
                      : 'text-bombayGrey'
                  )}
                  onClick={() => {
                    this.toggleSortReducer(p)
                  }}
                >
                  {renderHeader(schema[p].label || p, { sortBy, order })}
                  <Icon
                    className={classnames(
                      order === ASC ? 'arrow-rotate-asc' : 'arrow-rotate-des',
                      p === sortBy
                        ? 'text-gauloiseBlue-100'
                        : 'text-cloudWhite group-hover:text-pickledBlack'
                    )}
                    name="arrow"
                    size="small"
                  />
                </div>
              </HeadCell>
            ))}
          </Header>
          <Body>
            {rows.sort(sortByFunc(sortBy, order, schema)).map(row => (
              <Row key={row.id} className="bg-cloudWhite row-transition">
                {cols.map(key => {
                  return (
                    <Cell key={key}>
                      {schema[key].render
                        ? renderCell(schema[key].render(row[key], { id: row.id, key }), {
                            id: row.id,
                            key,
                            sortBy,
                            order
                          })
                        : renderCell(row[key])}
                    </Cell>
                  )
                })}
              </Row>
            ))}
          </Body>
        </Table>
      </div>
    )
  }
}

SortableTable.defaultProps = {
  renderHeader(value) {
    return <span>{value}</span>
  },
  renderCell(value) {
    return <span>{value}</span>
  },
  sortByFunc
}

SortableTable.propTypes = {
  /**
   * Provide a custom className
   */
  className: string,
  /**
   * The visible object keys within the sortable table.
   */
  cols: arrayOf(string).isRequired,
  /**
   * The data to display.
   */
  rows: arrayOf(object).isRequired,
  /**
   * schema object prop provides custom metadata for each data key, such as labels, sortType and
   * a custom render prop.
   */
  schema: object.isRequired,
  /**
   * A sort function, can be overridden.
   */
  sortByFunc: func,
  /**
   * A render prop, if you wish to change the default renderer for a header you can do it here.
   */
  renderHeader: func,
  /**
   * A render prop, use this to globally override the default cell renderer
   */
  renderCell: func,
  /**
   * if sortBy is passed in as a prop - sortBy becomes controlled from the external setStat
   */
  sortBy: string,
  /**
   * If order is passed as a prop - ordering becomes controlled from the external setState
   */
  order: oneOf([ASC, DES])
}

export default SortableTable
