import React from 'react';
import { Container, FlexColumn, FlexRow, Grid } from '../../utils/containers';
import Media from 'react-media';
import theme from '../../utils/theme';
import { ELEMENTS_PER_PAGE, IS_MOBILE } from '../../utils/globals';
import { Body, Medium } from '../../utils/fonts';
import styled from 'styled-components';
import ColumnFilterIcon from './ColumnFilterIcon';

const TableStyle = styled(FlexColumn)`
  overflow-x: ${({metrics}) => metrics > 10 ? 'scroll' : 'auto'};
`;

const Line = styled(FlexRow)`
  position: absolute;
  top: ${({ top }) => (top ? top : 'auto')};
  bottom: ${({ bottom }) => (bottom ? bottom : 'auto')};
  left: 0;
  width: 100%;
  background-color: ${({ theme }) => theme.colors.dark04};
  height: ${({ height }) => (height ? height : '1px')};
`;

const MobileTableStyle = styled(Container)`
  width: 100%;
  border-collapse: collapse;
  margin: 32px 0;

  tr:nth-of-type(odd) {
    background: ${({ theme }) => theme.colors.dark03};
  }

  th {
    background: ${({ theme }) => theme.colors.dark05};
    color: ${({ theme }) => theme.colors.white};
  }

  td,
  th {
    padding: 6px;
    border: 1px solid ${({ theme }) => theme.colors.white};
    text-align: left;
  }

  display: block;

  thead,
  tbody,
  th,
  td {
    display: block;
  }

  thead tr {
    position: absolute;
    top: -9999px;
    left: -9999px;
  }

  td {
    border: none;
    border-bottom: 1px solid ${({ theme }) => theme.colors.dark01};
    position: relative;
    padding-left: 50%;
  }

  .mobile-table-header {
    font-weight: 400;
    position: absolute;
    top: 6px;
    left: 6px;
    width: 45%;
    padding-right: 10px;
    white-space: nowrap;
  }
`;

const Table = (props) => {
  const [, updateState] = React.useState();
  const forceUpdate = React.useCallback(() => updateState({}), []);
  const [activeIcon, setActiveIcon] = React.useState(null);
  const [rotateActiveIcon, setRotateActiveIcon] = React.useState(false);

  const metricsRender = (elem) => {
    if (!props.iterableColumnElement) return <></>;
    if (Array.isArray(elem[props.iterableColumnElement.name]))
      elem = elem[props.iterableColumnElement.name];
    else {
      let newElem = [];
      for (let metric of props.possibleMetrics) {
        if (Object.hasOwn(elem, props.iterableColumnElement.name)) {
          if (elem[props.iterableColumnElement.name][metric] === '-1')
            newElem.push('N/A');
          else newElem.push(elem[props.iterableColumnElement.name][metric]);
        } else {
          newElem.push('N/A');
        }
      }
      elem = newElem;
    }
    let indexModificator = 2;
    if (props.tableType === 'leaderboard') indexModificator = 4;
    if (props.tableType === 'allEntries') indexModificator = 3;

    return elem.map((iterableElem, i) => {
      return (
        <Body
          key={`metric-result-${i}`}
          as="td"
          order={props.iterableColumnElement.order}
          textAlign={props.iterableColumnElement.align}
          minWidth="88px"
          margin="auto 0"
          overflowWrap="anywhere"
        >
          {IS_MOBILE() && (
            <Container className="mobile-table-header">
              {props.headerElements[indexModificator + i]}
            </Container>
          )}
          {props.iterableColumnElement.format
            ? props.iterableColumnElement.format(iterableElem)
            : iterableElem}
        </Body>
      );
    });
  };

  const rowRender = (elem) => {
    let RowStyle = Body;
    if (elem.submitter === props.user) RowStyle = Medium;
    return props.staticColumnElements.map((elemName, i) => {
      return (
        <RowStyle
          key={`leaderboard-static-elemName-${i}-${elem[elemName.name]}`}
          as="td"
          order={elemName.order}
          textAlign={elemName.align}
          margin="auto 0"
          minWidth="88px"
          overflowWrap="anywhere"
        >
          {IS_MOBILE() && (
            <Container className="mobile-table-header">
              {props.headerElements[i]}
            </Container>
          )}
          {elemName.format
            ? elemName.format(elem[elemName.name])
            : elem[elemName.name]}
        </RowStyle>
      );
    });
  };

  const desktopRender = () => {
    const n = (props.pageNr - 1) * (ELEMENTS_PER_PAGE * 2);
    let elementsToMap = props.elements.slice(n, n + ELEMENTS_PER_PAGE * 2);
    if (elementsToMap.length > 0) {
      return (
        <TableStyle as="table" margin="32px 0 72px 0" width="100%">
          <FlexColumn as="tbody" width="100%">
            <Grid
              as="tr"
              gridGap="20px"
              position="relative"
              width="100%"
              padding="0 6px"
              minHeight="44px"
              margin="0 0 6px 0"
              gridTemplateColumns={props.gridTemplateColumns}
            >
              {props.headerElements.map((elem, i) => {
                return (
                  <FlexRow
                    key={`table-header-${i}`}
                    alignmentX="flex-start"
                    as="td"
                    cursor="pointer"
                    onClick={() => {
                      if (activeIcon === i) {
                        let newRotateActiveIcon = !rotateActiveIcon;
                        setRotateActiveIcon(newRotateActiveIcon);
                      } else {
                        setRotateActiveIcon(false);
                      }
                      setActiveIcon(i);
                      props.sortByUpdate(elem, i);
                      forceUpdate();
                    }}
                  >
                    <Medium
                      cursor={elem !== '#' ? 'pointer' : ''}
                      textAlign={elem === 'when' ? 'right' : 'left'}
                      width={elem === 'when' ? '100%' : 'auto'}
                      padding="0 4px 0 0"
                      overflowWrap="anywhere"
                      minWidth="72px"

                      // minWidth={elem === 'result' ? '72px' : 'none'}
                    >
                      {elem.replace('.', ' ')}
                    </Medium>
                    {elem !== '#' && (
                      <ColumnFilterIcon
                        cursor="pointer"
                        index={i}
                        active={activeIcon}
                        rotateIcon={rotateActiveIcon}
                      />
                    )}
                  </FlexRow>
                );
              })}
              <Line
                height="2px"
                top="calc(100% + 2px)"
                as="td"
                shadow={theme.shadow}
              />
            </Grid>
            {elementsToMap.map((elem, index) => {
              return (
                <Grid
                  as="tr"
                  key={`leaderboard-row-${index}`}
                  backgroundColor={
                    index % 2 === 1 ? theme.colors.dark01 : 'transparent'
                  }
                  gridTemplateColumns={props.gridTemplateColumns}
                  gridGap="20px"
                  position="relative"
                  width="100%"
                  padding="4px"
                  minHeight="48px"
                >
                  {rowRender(elem)}
                  {props.headerElements ? metricsRender(elem) : ''}
                </Grid>
              );
            })}
          </FlexColumn>
        </TableStyle>
      );
    }
    return <Medium margin="72px 0">No results ;c</Medium>;
  };

  const mobileRender = () => {
    const n = (props.pageNr - 1) * ELEMENTS_PER_PAGE;
    let elementsToMap = props.elements.slice(n, n + ELEMENTS_PER_PAGE);
    if (elementsToMap.length > 0) {
      return (
        <MobileTableStyle
          as="table"
          staticColumnElements={props.staticColumnElements}
          headerElements={props.headerElements}
        >
          <Container as="tbody">
            {elementsToMap.map((elem, index) => {
              return (
                <Grid as="tr" key={`leaderboard-row-${index}`}>
                  {rowRender(elem)}
                  {props.headerElements ? metricsRender(elem) : ''}
                </Grid>
              );
            })}
          </Container>
        </MobileTableStyle>
      );
    }
    return <Medium margin="72px 0">No results ;c</Medium>;
  };

  return (
    <>
      <Media query={theme.mobile}>{mobileRender()}</Media>
      <Media query={theme.desktop}>{desktopRender()}</Media>
    </>
  );
};

export default Table;