import _ from 'lodash';
import i18next from 'i18next';
import { ThemeProvider } from 'styled-components';
import moment from 'moment';
import PropTypes from 'prop-types';
import React from 'react';

import { getMaxValue } from './utils/transform';

import iconEmptyState from '../images/icon-inpulse-no-data.svg';

import { StockGraphProps } from './interfaces';

import Tooltip from '../Tooltip';
import YAxis from './components/YAxis';
import ComponentLoader from './components/ComponentLoader';

import {
  GraphContainer,
  TitleCloseRow,
  TitleContainer,
  Title,
  Subtitle,
  GraphContent,
  LegendTitle,
  LegendContainer,
  LegendContent,
  LegendBox,
  EmptyGraph,
  DisplayIconNoData,
  NoDataInfo,
} from './styledComponents';

import GraphDisplayComponent from './GraphDisplayComponent';

/*
  The purpose of this function is to format the overlappedStocks to add them up. We do that so the associated graph bars are on top of each other
  vertically and not all at the same place over each other. For example if we have this:

  overlappedStocks = [
    {
      value: 20,
      color: red,
    },
    {
      value: 30,
      color: blue,
    },
    {
      value: 10,
      color: yellow,
    },
  ]

  In this case we want the blue to be displayed with a height of 20px, the red with a height of 30px on top of the blue and the yellow
  with a height of 10px on top of the red. We need to take the previous bars height into consideration if we don't want them to overlap
  so the red will be 20px, the blue 50px (20 + 30) and le yellow 60px (20 + 30 + 10)
*/
const formatData = (data) => {
  return data.map((item) => {
    const formattedStock = item.y.stock.map((currentStock) => {
      if (
        !currentStock.overlappedStocks ||
        !currentStock.overlappedStocks.length
      ) {
        return currentStock;
      }

      const { overlappedStocks } = currentStock.overlappedStocks.reduce(
        (acc, { value, color }) => {
          acc.total += value;
          acc.overlappedStocks.push({ value: acc.total, color });

          return acc;
        },
        { overlappedStocks: [], total: 0 }
      );

      return { overlappedStocks, value: currentStock.value };
    });

    return { ...item, y: { ...item.y, stock: formattedStock } };
  });
};

const StockGraph = (props: StockGraphProps): JSX.Element => {
  const {
    data,
    configuration,
    isLoading,
    unit,
    currentDate,
    hasNoInventoryStockOfEntity,
    singleBarGraph,
    theme,
    graphEmptyStateLabel,
    hideUnit,
    timezone,
  } = props;

  let maxHeight = 0;
  let heightYAxis = 0;

  const formattedData = formatData(data);

  if (formattedData && formattedData.length) {
    maxHeight = Math.ceil(getMaxValue(formattedData) / 10) * 10 + 10; // to take the text value into account
    heightYAxis = maxHeight === 0 ? 4 : Math.round(maxHeight / 4) * 4;
  }

  return (
    <>
      <ThemeProvider theme={theme}>
        <GraphContainer onClick={(e) => e.stopPropagation()}>
          {/* Title */}
          {!isLoading &&
            formattedData &&
            formattedData.length > 0 &&
            !!configuration && (
              <TitleCloseRow>
                <TitleContainer>
                  <Title>{configuration.title}</Title>
                  {configuration.tooltiptext && (
                    <div style={{ cursor: 'pointer' }}>
                      <Tooltip text={configuration.tooltiptext} />
                    </div>
                  )}
                </TitleContainer>
                {configuration.subtitle && (
                  <Subtitle>{configuration.subtitle}</Subtitle>
                )}
              </TitleCloseRow>
            )}

          {/* StockGraph Container */}
          <GraphContent>
            {/* show component loader */}
            {isLoading && <ComponentLoader height={30} width={30} />}
            {/* show empty state "node data" */}
            {!isLoading && formattedData && formattedData.length === 0 && (
              <EmptyGraph>
                <DisplayIconNoData alt="icon-no-data" src={iconEmptyState} />
                <NoDataInfo>
                  {graphEmptyStateLabel ||
                    i18next.t(
                      !hasNoInventoryStockOfEntity
                        ? 'COMPONENT_GRAPH_STOCK_LABEL_NO_DATA'
                        : 'COMPONENT_GRAPH_STOCK_HAS_NO_INVENTORY_STOCK_FOR_ENTITY'
                    )}
                </NoDataInfo>
              </EmptyGraph>
            )}
            {/* show graphs component */}
            {!isLoading && formattedData && formattedData.length > 0 && (
              <>
                <div style={{ padding: '0 30px 0 0' }} />
                <YAxis height={heightYAxis} />
                {_.map(formattedData, (item, index) => {
                  const itemValue = item.y.stock.map((stock) => {
                    if (
                      !!stock.overlappedStocks &&
                      stock.overlappedStocks.length
                    ) {
                      return Math.max(
                        ...stock.overlappedStocks.map(({ value }) => value)
                      );
                    }

                    return stock.value;
                  });

                  const isSelectedDay =
                    moment(item.x).format('MM-DD') ===
                    moment(currentDate).format('MM-DD');
                  const maxTooltipHeight = Math.max(...itemValue);
                  const roundedMaxTooltipHeight =
                    Math.round(maxTooltipHeight * 100) / 100;
                  const columnHeight = maxTooltipHeight
                    ? (roundedMaxTooltipHeight / maxHeight) * 100
                    : 0;

                  return (
                    <GraphDisplayComponent
                      columnHeight={columnHeight}
                      graph={item}
                      isSelectedDay={isSelectedDay}
                      key={index}
                      maxHeight={maxHeight}
                      nbColumn={formattedData.length}
                      unit={unit}
                      singleBarGraph={singleBarGraph}
                      hideUnit={hideUnit}
                      timezone={timezone}
                    />
                  );
                })}
                <div style={{ padding: '0 0 0 30px' }} />
              </>
            )}
          </GraphContent>

          {/* Legend Container */}
          {!isLoading &&
            configuration &&
            configuration.legends &&
            formattedData &&
            formattedData.length > 0 && (
              <LegendContainer>
                {_.map(configuration.legends, (legend, index) => (
                  <LegendContent key={index}>
                    <LegendBox color={legend.color} />
                    <LegendTitle>{legend.name}</LegendTitle>
                  </LegendContent>
                ))}
              </LegendContainer>
            )}
        </GraphContainer>
      </ThemeProvider>
    </>
  );
};

StockGraph.propTypes = {
  hasNoInventoryStockOfEntity: PropTypes.bool,
  singleBarGraph: PropTypes.bool,
  graphEmptyStateLabel: PropTypes.string.isRequired,
  hideUnit: PropTypes.bool,
};

StockGraph.defaultProps = {
  hasNoInventoryStockOfEntity: false,
  singleBarGraph: false,
  hideUnit: false,
};

export default StockGraph;
