import React from 'react';
import PropTypes from 'prop-types';
import loAt from 'lodash/at';

// Style
/* istanbul ignore next */
if (typeof window !== 'undefined') require('./style.scss');

const TableHead = (cell, ...rest) => {
  const [children, colspan = 0, align = 'left'] = Array.isArray(cell) ? [...cell, ...rest] : [cell, 0, ...rest];
  return colspan ? <th colSpan={colspan}>{children}</th> : <th align={align}>{children}</th>;
};

const TableCell = (cell, align = 'left') => <td align={align}>{cell}</td>;

export default class Table extends React.Component {
  static propTypes = {
    align: PropTypes.arrayOf(PropTypes.string),
    attr: PropTypes.object,
    body: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
    head: PropTypes.array,
    layout: PropTypes.oneOf(['fixed', 'auto', 'inherit']),
    pick: PropTypes.array,
    striped: PropTypes.bool,
  };

  static defaultProps = {
    align: [],
    attr: {},
    layout: 'fixed',
    pick: [],
    striped: true,
  };

  render() {
    const { head, body } = this.props;
    return (
      <table
        className={['Table', this.props.striped && 'Table_striped'].join(' ')}
        style={{ tableLayout: this.props.layout, ...this.props.style }}
      >
        {head && head.length && (
          <thead>
            {head.map((row, x) => (
              <tr key={`th-${x}`}>{row.map((d, i) => TableHead(d, this.props.align[i]))}</tr>
            ))}
          </thead>
        )}
        <tbody>
          {body.map((row, x) => (
            <tr key={`tr-${x}`}>
              {typeof row === 'object' && !Array.isArray(row)
                ? (this.props.pick.length ? loAt(row, this.props.pick) : Object.values(row)).map((d, i) =>
                    TableCell(d, this.props.align[i])
                  )
                : row.map((d, i) => TableCell(d, this.props.align[i]))}
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
}
