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`
  border-collapse: collapse;
  position: relative;
  width: 100%;
  background: var(--colorWhiteBase);
  overflow: hidden;
  border-radius: 3px;
  box-shadow: 0px 2px 16px rgba(0, 0, 0, 0.05);
`

const HtmlTHead = styled.thead`
  outline: 1px solid rgba(0, 0, 0, 0.1);
  background: var(--colorBlueBase);
`

const HtmlTableHeader = styled.th`
    font-size: 13px;
    font-weight: ${(props) => (props.isSorted ? 700 : 500)};
    letter-spacing: ${(props) => (props.isSorted ? '0.5px' : '0px')};
    text-transform: uppercase;
    background: ${(props) =>
    props.isSorted ? 'var(--colorBlueDark)' : 'none'};

    color: var(--colorWhiteBase);
    padding: 8px 0px 8px 8px
    text-align: left;
    padding-left: 8px;

    &:first-of-type {
      padding: 6px 0px 6px 16px;
    }
`

const TBody = styled.tbody``

const HtmlTableRow = styled.tr`
  border-bottom: 1px solid rgba(0, 0, 0, 0.015);

  &:nth-of-type(even) {
    background: var(--colorGrayUltraLight) !important;
  }
`

const HtmlTableCell = styled.td`
  padding: 4px 8px;
  font-size: 14px;

  &:first-of-type {
    /* padding: 4px 8px 4px 16px; */
    padding: 8px 8px 8px 16px;
  }
`

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 (
        <HtmlTableHeader
          key={column.dataKey}
          isSorted={this.state.activeSort === column.dataKey}
        >
          <Header />
          {sorter}
        </HtmlTableHeader>
      )
    })
  }

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

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

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

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

    return (
      <HtmlTableCell key={column.dataKey}>
        <Render />
      </HtmlTableCell>
    )
  }

  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 (
      <HtmlTable>
        <HtmlTHead>
          <tr>{tableData.headers}</tr>
        </HtmlTHead>
        <TBody>
          {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>}
      </HtmlTable>
    )
  }
}

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