import React from 'react'
import styled from 'styled-components'
// import posed from 'react-pose'

// import { TableRows } from './TableRows'

const PRIMITIVES = ['string', 'number', 'boolean']

// const PosedHtmlTableRow = posed.tr({
//   notSorting: {
//     opacity: 1,
//     background: '#ffffff',
//     color: '#000',
//     transition: ({ index }) => ({ delay: index * 25 }),
//   },
//   sorting: {
//     opacity: 0,
//     background: '#ececec0a',
//     color: '#ececec0a',
//     transition: ({ index }) => ({ delay: (index + 1) * 25 }),
//   },
// })

const HtmlTable = styled.table`

`

const HtmlTHead = styled.thead`

`

const HtmlTableHeader = styled.th`

`

const TBody = styled.tbody``

const HtmlTableRow = styled.tr`

`

const HtmlTableCell = styled.td`

`

const getColumnProps = (children) => {
  return children.map((target) => {
    return target.props
  })
}

const handlePrimitive = (target) => {
  return PRIMITIVES.includes(typeof target)
    ? () => String(target)
    : target || null
}

// If Table.Column has sort property but no provided function.
const defaultSort = (data) => {
  return data.tableProps.data.sort((a, b) => {
    return data.newSortDirection === 'ascending'
      ? (a[data.column.dataKey] > b[data.column.dataKey] && 1) || -1
      : (a[data.column.dataKey] < b[data.column.dataKey] && 1) || -1
  })
}

const SMALL_STYLES = {
  padding: '2px 8px',
  cursor: 'pointer',
  lineHeight: 0,
  position: 'relative',
  bottom: '1px',
}

const setSorting = (self) => (status) => {
  return self.setState({
    sorting: status,
  })
}

export class Table extends React.Component {
  state = {
    sorting: false,
    activeSort: null,
    sortDirection: 'ascending',
    sortedRows: this.props.data || [],
    showOptions: false,
    sortedColumn: null,
  }

  setSorting = setSorting(this)

  UNSAFE_componentWillReceiveProps(newProps) {
    if (!this.state.activeSort) this.setState({ sortedRows: newProps.data })
    else this.sortRows(this.state.sortedColumn, newProps)({})
  }

  generate = () => {
    const columns = getColumnProps(this.props.children)
    const rows = this.generateRows(columns)
    const headers = this.generateHeaders(columns)
    return { headers, rows }
  }

  generateHeaders = (columns) => {
    return columns.map((column) => {
      const Header = handlePrimitive(column.header)

      const sorter = column.sort ? (
        <small
          key={column.dataKey}
          style={SMALL_STYLES}
          onClick={this.sortRows(column)}
        >
          ↕️
        </small>
      ) : null

      return (
        <th
          className="ETableHead"
          key={column.dataKey}
          isSorted={this.state.activeSort === column.dataKey}
        >
          <Header />
          {sorter}
        </th>
      )
    })
  }

  generateRows = (columns) => {
    const createColumns = (row) => {
      return columns.map((column) => {
        return this.generateCell(column, row)
      })
    }

    return this.state.sortedRows.map((row, index) => {
      return (props) => (
        <tr
          className="ETableRow"
          style={props.style}
          index={props.index}
          pose={props.sorting ? 'sorting' : 'notSorting'}
        >
          {createColumns(row)}
        </tr>
      )
    })
  }

  generateCell = (column, row) => {
    const value = row[column.dataKey]

    const Render = column.render
      ? () => <column.render column={column} row={row} value={value} />
      : () => value

    return (
      <td className="ETableCell" key={column.dataKey}>
        <Render />
      </td>
    )
  }

  sortRows = (column, props = this.props) => (event) => {
    this.setSorting(true)

    const { activeSort, sortDirection } = this.state
    const isPreviouslyActive = activeSort === column.dataKey

    const newSortDirection = isPreviouslyActive
      ? sortDirection === 'ascending'
        ? 'descending'
        : 'ascending'
      : 'ascending'

    const sorter = typeof column.sort === 'function' ? column.sort : defaultSort

    const sortedRows = sorter({
      tableState: { ...this.state },
      tableProps: { ...props },
      newSortDirection,
      isPreviouslyActive,
      column,
      event,
    })

    this.setSorting(false)

    this.setState({
      activeSort: column.dataKey,
      sortedColumn: column,
      sortDirection: newSortDirection,
      sortedRows,
    })
  }

  render() {
    const tableData = this.generate()

    return (
      <table className="ETable">
        <thead className="ETableHeader">
          <tr className="ETableRow">{tableData.headers}</tr>
        </thead>
        <tbody className="ETableBody">
          {tableData.rows.map((Row, index) => (
            // NOTE: No other value to use than index for key.
            <Row index={index} key={index} />
          ))}
        </tbody>
        {this.props.footer && <tfoot>{this.props.footer()}</tfoot>}
      </table>
    )
  }
}

const Column = () => { }
Table.Column = Column
