import PropTypes from 'prop-types';
import { ThemeProvider } from 'styled-components';
import React, { useState, Fragment } from 'react';

import { getTheme } from '../utils/theme';

import { Props } from './interface';
import { ExpandableListContainer, RowContainer } from './styledComponents';
import useInteractDataRowAndGraph from './customHook/useInteractDataRowAndGraph';
import HeaderRow from './components/HeaderRow/HeaderRow';
import LoadingState from './components/LoadingState/LoadingStateDisplay';
import { ORDER_TYPE } from './constants';
import ItemRowDisplay from './components/ItemRowDisplay/ItemRowDisplay';

const ExpandableEmbeddedList = (props: Props): JSX.Element => {
  const {
    theme,
    headers,
    data,
    isLoading,
    defaultOrderBy,
    defaultOrderType,
    minWidth,
    height,
    customModalIcon,
  } = props;

  const [orderBy, setOrderBy] = useState(defaultOrderBy);
  const [orderType, setOrderType] = useState<'asc' | 'desc'>(defaultOrderType);

  const setOrderColumn = (id) => {
    if (orderBy === id) {
      setOrderType(
        orderType === ORDER_TYPE.ASCENDING
          ? ORDER_TYPE.DESCENDING
          : ORDER_TYPE.ASCENDING
      );

      return;
    }
    setOrderBy(id);
    setOrderType(ORDER_TYPE.ASCENDING);
  };

  const interactData = useInteractDataRowAndGraph({
    data,
    headers,
    orderBy,
    orderType,
  });

  return (
    <ThemeProvider theme={getTheme(theme, 'expandableEmbeddedList')}>
      <ExpandableListContainer minWidth={minWidth}>
        <HeaderRow
          theme={theme}
          headers={headers}
          orderBy={orderBy}
          orderType={orderType}
          setOrderColumn={setOrderColumn}
        />

        {isLoading && <LoadingState headers={headers} />}

        {!isLoading && (
          <RowContainer height={height}>
            {interactData.dataState.map((item, index) => {
              const uniqId = `row-${index}`;
              return (
                <Fragment key={uniqId}>
                  <ItemRowDisplay
                    theme={getTheme(theme)}
                    headers={headers}
                    items={item}
                    openRow={() => interactData.openRow(index)}
                    openGraph={() =>
                      interactData.openParentModal(index, 'graphOpened')
                    }
                    openChildGraph={interactData.openChildModal}
                    openParentModal={() =>
                      interactData.openParentModal(index, 'modalOpened')
                    }
                    openChildModal={interactData.openChildModal}
                    parentIndex={index}
                    customModalIcon={customModalIcon}
                  />
                </Fragment>
              );
            })}
          </RowContainer>
        )}
      </ExpandableListContainer>
    </ThemeProvider>
  );
};

ExpandableEmbeddedList.propTypes = {
  // eslint-disable-next-line react/forbid-prop-types
  theme: PropTypes.objectOf(PropTypes.any),
  minWidth: PropTypes.number,
  headers: PropTypes.arrayOf(
    PropTypes.shape({
      name: PropTypes.string.isRequired,
      propertyKey: PropTypes.string.isRequired,
      isNumber: PropTypes.bool,
      unit: PropTypes.string,
      tooltipDisplay: PropTypes.string,
      large: PropTypes.bool,
      bold: PropTypes.bool,
      textTransform: PropTypes.string,
      textDecorationChild: PropTypes.string,
      withRender: PropTypes.bool,
      hrefPrefix: PropTypes.string,
      hrefSuffix: PropTypes.string,
      customModalRender: PropTypes.bool,
      customModalTooltip: PropTypes.string,
      graphConfiguration: PropTypes.shape({
        title: PropTypes.string,
        subtitle: PropTypes.string,
      }),
    })
  ).isRequired,
  data: PropTypes.arrayOf(
    PropTypes.shape({
      parentItem: PropTypes.shape({
        items: PropTypes.objectOf(
          PropTypes.oneOfType([
            PropTypes.number,
            PropTypes.string,
            PropTypes.bool,
            PropTypes.func,
          ])
        ),
        chart: PropTypes.arrayOf(
          PropTypes.shape({
            x: PropTypes.string,
            y: PropTypes.number,
          })
        ),
      }),
      childItems: PropTypes.arrayOf(
        PropTypes.shape({
          items: PropTypes.objectOf(
            PropTypes.oneOfType([
              PropTypes.number,
              PropTypes.string,
              PropTypes.bool,
              PropTypes.func,
            ])
          ),
          chart: PropTypes.arrayOf(
            PropTypes.shape({
              x: PropTypes.string.isRequired,
              y: PropTypes.number.isRequired,
            })
          ),
        })
      ),
    })
  ).isRequired,
  isLoading: PropTypes.bool.isRequired,
  defaultOrderBy: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  defaultOrderType: PropTypes.string,
  customModalIcon: PropTypes.string,
  height: PropTypes.string,
};

ExpandableEmbeddedList.defaultProps = {
  minWidth: 1200,
  height: '100%',
  defaultOrderBy: null,
  defaultOrderType: ORDER_TYPE.ASCENDING,
  customModalIcon: null,
  theme: null,
};

export default ExpandableEmbeddedList;
