import _ from 'lodash';
import React, { useState, useEffect, Fragment } from 'react';

import PropTypes from 'prop-types';
import { PropsRow } from '../../interface';
import { numberToFixed } from '../../../utils/format';
import {
  ItemRowContainer,
  ItemRow,
  ItemDisplayWithCustomModal,
  ModalContainer,
  ArrowIconContainer,
  NestedContentContainer,
  NestedStockGraphContainer,
} from './styledComponents';

import ActionButton from '../ActionButton';
import ItemDisplay from '../ItemDisplay/ItemDisplay';
import CustomModalButtonDisplay from '../CustomModalButton/CustomModalButtonDisplay';
import ArrowIcon from '../../../ArrowIcon';
import StockGraph from '../../../StockGraph';
import {
  ConfigurationProps,
  ItemGraph,
  StockGraphProps,
} from '../../../StockGraph/interfaces';
import NestedData from '../NestedData/NestedData';

const Row = (props: PropsRow): JSX.Element => {
  const {
    theme,
    headers,
    item,
    openRow,
    customModalIcon,
    openModal,
    modalTitle,
    modalHeaders,
    isExpandable,
    isHighlighted,
    labelModalEmptyState,
    graphEmptyStateLabel,
    customNestedContentPadding,
    isBold,
    hasNestedData,
  } = props;

  const [isLoading, setIsLoading] = useState(true);
  const [graphContent, setStockGraphContent] = useState<StockGraphProps>();

  useEffect(() => {
    (async function loadData() {
      if (item.opened && item.graphContent) {
        const result = await item.graphContent();

        setStockGraphContent(result);
        setIsLoading(false);
      }
    })();
  }, [item, item.opened]);

  return (
    <>
      <ItemRowContainer isExpandable={isExpandable}>
        {item.isHighlighted && (
          <ArrowIconContainer>
            <ArrowIcon />
          </ArrowIconContainer>
        )}

        <ItemRow isExpandable={isExpandable} onClick={() => openRow()}>
          {headers.map((header, index) => {
            let value: string | number = '';

            const isAction = header.propertyKey === 'action';

            const isRowHidden = header.hideRow;

            if (_.get(item, header.propertyKey)) {
              value = header.isNumber
                ? numberToFixed(
                    _.get(item, header.propertyKey),
                    2,
                    '-',
                    header.unit
                  )
                : _.get(item, header.propertyKey);
            }

            if (isRowHidden) {
              return <Fragment key={`parent-row-${index}`} />;
            }

            return (
              <Fragment key={`parent-row-${index}`}>
                {!isAction && !header.customModalRender && (
                  <ItemDisplay
                    value={
                      header.render
                        ? header.render(_.get(item, header.propertyKey), item)
                        : value
                    }
                    large={header.large}
                    narrow={header.narrow}
                    isHighlighted={isHighlighted}
                    minWidth={header.minWidth}
                    nbColumn={headers.length}
                    hasNestedData={hasNestedData}
                    isBold={isBold}
                    displayBigger={header.displayBigger}
                  />
                )}
                {!isAction && header.customModalRender && (
                  <ItemDisplayWithCustomModal
                    nbColumn={headers.length}
                    minWidth={header.minWidth}
                  >
                    <ModalContainer>
                      <CustomModalButtonDisplay
                        theme={theme}
                        icon={customModalIcon}
                        openModal={openModal}
                        openedModal={_.get(item, `modalOpened`)}
                        modalContent={_.get(item, `modalContent`, () => [])}
                        modalTitle={modalTitle}
                        modalHeaders={modalHeaders}
                        labelModalEmptyState={labelModalEmptyState}
                      />
                    </ModalContainer>
                  </ItemDisplayWithCustomModal>
                )}
                {isAction && isExpandable && (
                  <div style={{ flex: 4 }}>
                    <ActionButton
                      visibility
                      open={item.opened}
                      isDisabled={
                        !item.nestedContent &&
                        !item.graphContent &&
                        !item.nestedData
                      }
                    />
                  </div>
                )}
              </Fragment>
            );
          })}
        </ItemRow>

        <>
          {item.opened && item.nestedContent && (
            <NestedContentContainer
              customNestedContentPadding={customNestedContentPadding}
            >
              {item.nestedContent()}
            </NestedContentContainer>
          )}

          {item.opened && item.graphContent && (
            <NestedStockGraphContainer>
              <StockGraph
                theme={theme}
                data={_.get(graphContent, `data`, []) as Array<ItemGraph>}
                configuration={
                  _.get(graphContent, `configuration`, {}) as ConfigurationProps
                }
                isLoading={isLoading}
                unit={_.get(graphContent, `unit`, '')}
                hasNoInventoryStockOfEntity={_.get(
                  graphContent,
                  `hasNoInventoryStockOfEntity`
                )}
                currentDate={_.get(graphContent, `currentDate`)}
                singleBarGraph={_.get(graphContent, `singleBarGraph`)}
                graphEmptyStateLabel={graphEmptyStateLabel}
                hideUnit={_.get(graphContent, `hideUnit`)}
                timezone={_.get(graphContent, `timezone`)}
              />
            </NestedStockGraphContainer>
          )}

          {item.opened && item.nestedData && (
            <NestedData
              theme={theme}
              headers={headers}
              data={item.nestedData}
            />
          )}
        </>
      </ItemRowContainer>
    </>
  );
};

Row.propTypes = {
  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,
      render: PropTypes.func,
    })
  ).isRequired,
  item: PropTypes.objectOf(
    PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.string,
      PropTypes.bool,
      PropTypes.func,
      PropTypes.object,
    ])
  ).isRequired,
  isExpandable: PropTypes.bool,
  isHighlighted: PropTypes.bool,
  openRow: PropTypes.func.isRequired,
  openModal: PropTypes.func.isRequired,
  // eslint-disable-next-line react/forbid-prop-types
  theme: PropTypes.objectOf(PropTypes.any),
  modalTitle: PropTypes.string,
  graphEmptyStateLabel: PropTypes.string.isRequired,
  customNestedContentPadding: PropTypes.string,
  isBold: PropTypes.bool,
  hasNestedData: PropTypes.bool,
};

Row.defaultProps = {
  theme: null,
  modalTitle: null,
  isExpandable: true,
  isHighlighted: false,
  customNestedContentPadding: '',
  isBold: false,
  hasNestedData: false,
};

export default Row;
