/* eslint-disable no-nested-ternary */
import _ from 'lodash';
import i18next from 'i18next';
import moment from 'moment-timezone';
import PropTypes from 'prop-types';
import React, { Fragment } from 'react';
import ReactTooltip from 'react-tooltip';

import { GraphDisplayProps } from './interfaces';

import { getValueGraphPosition } from './utils/transform';
import {
  GraphDisplayContent,
  GraphLabels,
  GraphLabelDay,
  GraphDisplayContentRow,
  GraphNoDataToDisplay,
  GraphBarsContainer,
  OverlappedGraphBarsContainer,
} from './styledComponents';

import GraphBarsComponent from './GraphBarsComponent';

const OverlappedGraphBars = ({
  overlappedStocks,
  index,
  stock,
  maxHeight,
  unit,
  hideUnit,
}) => {
  const hasPositiveValue = overlappedStocks.some(
    ({ value: graphValue }) => graphValue !== null && graphValue >= 0
  );

  if (index === 1 && !hasPositiveValue) {
    return <></>;
  }

  return overlappedStocks.map(({ value, color }, barIndex) => {
    const roundedValue = Math.round(value * 100) / 100;

    const zIndex = overlappedStocks.length - barIndex + 1; // +1 because we want the value to be at least equal at one

    return (
      <GraphBarsContainer zIndex={zIndex}>
        <GraphBarsComponent
          color={color}
          height={
            maxHeight !== 0 ? (roundedValue / maxHeight) * 100 : roundedValue
          }
          key={value}
          nbColumn={stock.length}
          value={roundedValue}
          valuePosition={getValueGraphPosition(index, stock)}
          unit={unit}
          hideUnit={hideUnit}
          hideValue={barIndex + 1 !== overlappedStocks.length} // +1 because index can be equal to 0 and not the length of array if there's data inside
        />
      </GraphBarsContainer>
    );
  });
};

const GraphDisplayComponent = (props: GraphDisplayProps): JSX.Element => {
  const {
    graph,
    nbColumn,
    maxHeight,
    unit,
    columnHeight,
    isSelectedDay,
    singleBarGraph,
    hideUnit,
    timezone,
  } = props;

  const hasValueSet = singleBarGraph
    ? typeof graph.y.stock[0].value === 'number'
    : typeof graph.y.stock[0].value === 'number' ||
      typeof graph.y.stock[1].value === 'number';

  const tooltipId = `tooltip-graph-${graph.x}`;

  const isDateToday = timezone
    ? moment.tz(graph.x, timezone).isSame(moment(), 'day')
    : moment(graph.x).isSame(moment(), 'day');

  const isDateYesterday = timezone
    ? moment.tz(graph.x, timezone).isSame(moment().subtract(1, 'day'), 'day')
    : moment(graph.x).isSame(moment().subtract(1, 'day'), 'day');

  const currentDate = moment().format('YYYY-MM-DD');
  const currentDateMinusThirteenDays = moment(currentDate).add(2, 'days');
  const tooltipPos = moment(graph.x).isBefore(currentDateMinusThirteenDays)
    ? 'right'
    : 'left';

  return (
    <GraphDisplayContent>
      <GraphDisplayContentRow
        columnHeight={Math.min(columnHeight, 100)}
        data-for={tooltipId}
        data-html
        data-tip={graph.tooltip}
      >
        {!!hasValueSet &&
          // eslint-disable-next-line consistent-return
          _.map(graph.y.stock, ({ value, overlappedStocks, color }, index) => {
            if (!!overlappedStocks && overlappedStocks.length) {
              return (
                <Fragment key={`${index}`}>
                  <OverlappedGraphBarsContainer>
                    <OverlappedGraphBars
                      overlappedStocks={overlappedStocks}
                      index={index}
                      stock={graph.y.stock}
                      maxHeight={maxHeight}
                      unit={unit}
                      hideUnit={hideUnit}
                    />
                  </OverlappedGraphBarsContainer>
                </Fragment>
              );
            }

            if (index !== 1 || (index === 1 && value !== null && value >= 0)) {
              const roundedValue = Math.round(value * 100) / 100;

              return (
                <Fragment key={index}>
                  <GraphBarsComponent
                    color={color}
                    height={
                      maxHeight !== 0
                        ? (roundedValue / maxHeight) * 100
                        : roundedValue
                    }
                    key={value}
                    nbColumn={graph.y.stock.length}
                    value={roundedValue}
                    valuePosition={getValueGraphPosition(index, graph.y.stock)}
                    unit={unit}
                    hideUnit={hideUnit}
                  />
                </Fragment>
              );
            }
          })}
        {!hasValueSet && (
          <GraphNoDataToDisplay>
            {i18next.t('COMPONENT_GRAPH_STOCK_LABEL_NO_DATA')}
          </GraphNoDataToDisplay>
        )}
        <ReactTooltip
          backgroundColor="white"
          className="custom-tooltip-event"
          effect="solid"
          id={tooltipId}
          place={tooltipPos}
          arrowColor="transparent"
        />
      </GraphDisplayContentRow>
      <GraphLabels nbColumn={nbColumn}>
        <GraphLabelDay bold={isSelectedDay} key={graph.x}>
          {isDateToday
            ? i18next.t('GENERAL_TODAY_ABBREV')
            : isDateYesterday
            ? i18next.t('GENERAL_YESTERDAY')
            : moment(graph.x).format('DD/MM')}
        </GraphLabelDay>
      </GraphLabels>
    </GraphDisplayContent>
  );
};
GraphDisplayComponent.propTypes = {
  nbColumn: PropTypes.number.isRequired,
  maxHeight: PropTypes.number.isRequired,
  columnHeight: PropTypes.number.isRequired,
  unit: PropTypes.string.isRequired,
  graph: PropTypes.shape({
    x: PropTypes.string,
    y: PropTypes.shape({
      stock: PropTypes.arrayOf(
        PropTypes.shape({
          // eslint-disable-next-line react/forbid-prop-types
          value: PropTypes.any,
          color: PropTypes.string,
        })
      ),
    }),
    tooltip: PropTypes.string,
  }),
  isSelectedDay: PropTypes.bool,
  hideUnit: PropTypes.bool,
};

GraphDisplayComponent.defaultProps = {
  graph: {},
  isSelectedDay: false,
  hideUnit: false,
};

OverlappedGraphBars.propTypes = {
  overlappedStocks: PropTypes.arrayOf(
    PropTypes.shape({
      // eslint-disable-next-line react/forbid-prop-types
      value: PropTypes.any,
      color: PropTypes.string,
    })
  ).isRequired,
  index: PropTypes.number.isRequired,
  stock: PropTypes.arrayOf(
    PropTypes.shape({
      // eslint-disable-next-line react/forbid-prop-types
      value: PropTypes.any,
      color: PropTypes.string,
    })
  ),
  maxHeight: PropTypes.number.isRequired,
  unit: PropTypes.string.isRequired,
  hideUnit: PropTypes.bool,
};

OverlappedGraphBars.defaultProps = {
  stock: [],
  hideUnit: false,
};

export default GraphDisplayComponent;
