/* eslint-disable react-hooks/rules-of-hooks */
import React, { useEffect, useState } from 'react';
import { boolean, object } from '@storybook/addon-knobs';

import Box from '../Layout/Box';
import Button from '../Button';
import Pagination from '../Pagination';
import { PaginationProvider } from '../Pagination/PaginationContainer';
import Stack from '../Layout/Stack';
import Table from '.';
import TableSort from './TableSort';
import { Text } from '../Text';
import TextLink from '../TextLink';
import usePagination from '../Pagination/usePagination';
import { useReducer } from 'react';

export default {
  title: 'Components|Table',
  component: Table,
};

function sort(data, orderedColumn, ordering) {
  if (ordering === 'NONE') return data;

  return data.sort((o1, o2) => {
    let comparison, o1Val, o2Val;
    if (orderedColumn === 1) {
      o1Val = o1.name || '';
      o2Val = o2.name || '';
    } else {
      o1Val = o1.email || '';
      o2Val = o2.email || '';
    }
    comparison = o1Val.localeCompare(o2Val);

    const i = ordering === 'ASC' ? 1 : -1;
    if (comparison > 0) {
      return i;
    }
    if (comparison < 0) {
      return -i;
    }
    return 0;
  });
}

const TableWrapper = ({ loading, ...rest }) => {
  const [selected, setSelected] = useState({});
  const [{ sortProp, ordering, page }, dispatch] = useReducer(
    function reducer(state, action) {
      switch (action.type) {
        case 'TOGGLE_ORDERING':
          return {
            ...state,
            sortProp: action.payload,
            ordering:
              state.ordering !== 'ASC' || action.payload !== state.sortProp ? 'ASC' : 'DESC',
            page: 1,
          };
        case 'SET_PAGE':
          return {
            ...state,
            page: action.payload,
          };
        default:
          return state;
      }
    },
    {
      sortProp: 1,
      ordering: 'NONE',
      page: 1,
    },
  );

  const data = [
    { name: 'a', email: 'a@chaserhq.com' },
    { name: 'b', email: 'b@chaserhq.com' },
    { name: 'c', email: 'c@chaserhq.com' },
    { name: 'd', email: 'd@chaserhq.com' },
    { name: 'e', email: 'e@chaserhq.com' },
    { name: 'f', email: 'f@chaserhq.com' },
    { name: 'g', email: 'g@chaserhq.com' },
    { name: 'h', email: 'h@chaserhq.com' },
    { name: 'i', email: 'i@chaserhq.com' },
    { name: 'j', email: 'j@chaserhq.com' },
    { name: 'k', email: 'k@chaserhq.com' },
    { name: 'l', email: 'l@chaserhq.com' },
    { name: 'm', email: 'm@chaserhq.com' },
    { name: 'n', email: 'n@chaserhq.com' },
    { name: 'o', email: 'o@chaserhq.com' },
    { name: 'p', email: 'p@chaserhq.com' },
    { name: 'q', email: 'q@chaserhq.com' },
    { name: 'r', email: 'r@chaserhq.com' },
    { name: 's', email: 's@chaserhq.com' },
    { name: 't', email: 't@chaserhq.com' },
    { name: 'u', email: 'u@chaserhq.com' },
    { name: 'v', email: 'v@chaserhq.com' },
    { name: 'w', email: 'w@chaserhq.com' },
    { name: 'x', email: 'x@chaserhq.com' },
    { name: 'y', email: 'y@chaserhq.com' },
    { name: 'z', email: 'z@chaserhq.com' },
    { name: '0', email: '0@chaserhq.com' },
    { name: '1', email: '1@chaserhq.com' },
    { name: '2', email: '2@chaserhq.com' },
    { name: '3', email: '3@chaserhq.com' },
    { name: '4', email: '4@chaserhq.com' },
    { name: '5', email: '5@chaserhq.com' },
    { name: '6', email: '6@chaserhq.com' },
    { name: '7', email: '7@chaserhq.com' },
    { name: '8', email: '8@chaserhq.com' },
    { name: '9', email: '9@chaserhq.com' },
    { name: 'aa', email: 'aa@chaserhq.com' },
    { name: 'ab', email: 'ab@chaserhq.com' },
    { name: 'ac', email: 'ac@chaserhq.com' },
    { name: 'ad', email: 'ad@chaserhq.com' },
    { name: 'ae', email: 'ae@chaserhq.com' },
    { name: 'af', email: 'af@chaserhq.com' },
    { name: 'ag', email: 'ag@chaserhq.com' },
    { name: 'ah', email: 'ah@chaserhq.com' },
    { name: 'ai', email: 'ai@chaserhq.com' },
    { name: 'aj', email: 'aj@chaserhq.com' },
    { name: 'ak', email: 'ak@chaserhq.com' },
    { name: 'al', email: 'al@chaserhq.com' },
    { name: 'am', email: 'am@chaserhq.com' },
    { name: 'an', email: 'an@chaserhq.com' },
    { name: 'ao', email: 'ao@chaserhq.com' },
    { name: 'ap', email: 'ap@chaserhq.com' },
    { name: 'aq', email: 'aq@chaserhq.com' },
    { name: 'ar', email: 'ar@chaserhq.com' },
    { name: 'as', email: 'as@chaserhq.com' },
    { name: 'at', email: 'at@chaserhq.com' },
    { name: 'au', email: 'au@chaserhq.com' },
    { name: 'av', email: 'av@chaserhq.com' },
    { name: 'aw', email: 'aw@chaserhq.com' },
    { name: 'ax', email: 'ax@chaserhq.com' },
    { name: 'ay', email: 'ay@chaserhq.com' },
    { name: 'az', email: 'az@chaserhq.com' },
    { name: 'a0', email: 'a0@chaserhq.com' },
    { name: 'a1', email: 'a1@chaserhq.com' },
    { name: 'a2', email: 'a2@chaserhq.com' },
    { name: 'a3', email: 'a3@chaserhq.com' },
    { name: 'a4', email: 'a4@chaserhq.com' },
    { name: 'a5', email: 'a5@chaserhq.com' },
    { name: 'a6', email: 'a6@chaserhq.com' },
    { name: 'a7', email: 'a7@chaserhq.com' },
    { name: 'a8', email: 'a8@chaserhq.com' },
    { name: 'a9', email: 'a9@chaserhq.com' },
  ];

  const sorted = sort(data, sortProp, ordering);

  const currentSort = ordering !== 'NONE' ? `${ordering === 'DESC' ? '-' : ''}${sortProp}` : '';

  function onSort(prop) {
    dispatch({ type: 'TOGGLE_ORDERING', payload: prop });
  }

  const [cellLoading, setCellLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setCellLoading(false);
    }, 2000);

    return () => clearTimeout(timer);
  }, []);

  const pagination = usePagination({
    data: sorted,
    pageSize: 10,
    page,
    onPageChange: (p) => dispatch({ type: 'SET_PAGE', payload: p }),
  });

  const columns = [
    {
      id: 'name',
      header: () => (
        <TableSort sortProp={1} currentSort={currentSort} onSort={onSort} headerTitle="Name" />
      ),
      headerStyle: { width: '150px' },
      accessor: 'name',
      dataField: 'name',
    },
    {
      id: 'email',

      header: () => 'Email Address',
      accessor: 'email',
      dataField: 'email',
    },
    {
      id: 'key',
      accessor: 'key',
      headerStyle: { width: '150px' },
      dataField: 'key',
      align: 'right',
      cell: (...args) => <TextLink as="button">Text link</TextLink>,
      formatter: (...args) => <TextLink as="button">Text link</TextLink>,
    },
    {
      id: 'loading',
      header: () => 'Loading',
      accessor: 'loading',
      dataField: 'loading',
      loading: cellLoading,
    },
  ];

  const [hiddenColumns, setHiddenColumns] = useState(['name']);

  return (
    <PaginationProvider pagination={pagination}>
      <Stack>
        <button onClick={() => setHiddenColumns(['name', 'email'])}>Toggle Column 1</button>
        <Table
          loading={loading}
          keyField="email"
          data={data}
          columns={columns}
          selected={selected}
          disabled={object('disabled', {
            'b@chaserhq.com': true,
            'c@chaserhq.com': true,
            'd@chaserhq.com': true,
          })}
          setSelected={setSelected}
          setHiddenColumns={setHiddenColumns}
          hiddenColumns={hiddenColumns}
          renderExpanded={(row) => (
            <Box>
              <Text>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum maxime incidunt
                numquam? Saepe dolores impedit at, praesentium, non illum quos magni, voluptatibus
                rerum laudantium atque esse dicta hic quae rem.
              </Text>
            </Box>
          )}
          {...rest}
        />
        <Pagination />
      </Stack>
    </PaginationProvider>
  );
};

export const index = () => {
  return <TableWrapper loading={boolean('loading', false)} />;
};

export const renderSelect = () => {
  return (
    <TableWrapper
      renderSelectAll={({ checked, onChange }) => (
        <Button
          appearance={checked ? 'primary' : 'secondary'}
          onClick={() => onChange({ target: { checked: !checked } })}
        >
          {checked ? 'deselect all' : 'select all'}
        </Button>
      )}
      renderSelect={(row, { checked, onChange }) => (
        <Button
          appearance={checked ? 'primary' : 'secondary'}
          onClick={() => onChange({ target: { checked: !checked } })}
        >
          {checked ? 'deselect' : 'select'}
        </Button>
      )}
      renderExpanded={null}
    />
  );
};

export const empty = () => {
  const data = [];
  const columns = [
    {
      id: 'name',
      header: 'Name',
      accessor: 'name',
    },
    {
      id: 'email',
      header: 'Email address',
      accessor: 'email',
    },
  ];
  return <Table noDataIndication="No data" keyField="email" data={data} columns={columns} />;
};
