import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { createContainer, Chart, ChartAxis, ChartLegendTooltip, ChartArea, ChartScatter, ChartBoxPlot, getInteractiveLegendEvents, ChartLegend } from '@patternfly/react-charts';
import { useIntl } from 'react-intl';
import messages from '../../../locales/messages.esm.js';
import { getDateRangeString } from '../utils/chart-datum.esm.js';
import { getResizeObserver, getDomain, getLegendData, isDataAvailable, isSeriesHidden, initHiddenSeries } from '../utils/chart-utils.esm.js';
import ChartTheme from '../theme/index.esm.js';
import { unitsLookupKey } from '../utils/format.esm.js';
import { chartStyles } from './optimizationsBreakdownChart.styles.esm.js';
import { useOptimizationsBreakdownChartStyles } from './OptimizationsBreakdownChartStyles.esm.js';

const OptimizationsBreakdownChart = ({ baseHeight, name, limitData, padding, requestData, usageData }) => {
  const [containerRef] = useState(React.createRef());
  const [cursorVoronoiContainer, setCursorVoronoiContainer] = useState();
  const [extraHeight, setExtraHeight] = useState(0);
  const [hiddenSeries, setHiddenSeries] = useState(/* @__PURE__ */ new Set());
  const [series, setSeries] = useState();
  const [width, setWidth] = useState(0);
  const intl = useIntl();
  const classes = useOptimizationsBreakdownChartStyles();
  const cloneContainer = () => {
    const legendData = getLegendData(series, hiddenSeries, true);
    legendData?.push(
      {
        childName: "usage",
        name: "",
        symbol: {
          fill: "none"
        }
      },
      {
        childName: "usage",
        name: "",
        symbol: {
          fill: "none"
        }
      }
    );
    return cursorVoronoiContainer ? React.cloneElement(cursorVoronoiContainer, {
      disable: !isDataAvailable(series, hiddenSeries),
      labelComponent: /* @__PURE__ */ React.createElement(
        ChartLegendTooltip,
        {
          legendData,
          title: (datum) => `${datum.x}`
        }
      )
    }) : void 0;
  };
  const getLimitChart = () => {
    return series?.map((serie, index) => {
      if (serie.childName === "limit") {
        return /* @__PURE__ */ React.createElement(
          ChartArea,
          {
            data: !hiddenSeries.has(index) ? serie.data : [{ y: null }],
            interpolation: "monotoneX",
            key: serie.childName,
            name: serie.childName,
            style: serie.style
          }
        );
      }
      return null;
    });
  };
  const getRequestChart = () => {
    return series?.map((serie, index) => {
      if (serie.childName === "request") {
        return /* @__PURE__ */ React.createElement(
          ChartArea,
          {
            data: !hiddenSeries.has(index) ? serie.data : [{ y: null }],
            interpolation: "monotoneX",
            key: serie.childName,
            name: serie.childName,
            style: serie.style
          }
        );
      }
      return null;
    });
  };
  const getScatterChart = () => {
    return series?.map((serie, index) => {
      if (serie.childName === "scatter") {
        return /* @__PURE__ */ React.createElement(
          ChartScatter,
          {
            data: !hiddenSeries.has(index - 1) ? serie.data : [{ y: null }],
            key: serie.childName,
            name: serie.childName,
            style: serie.style
          }
        );
      }
      return null;
    });
  };
  const getUsageChart = () => {
    return series?.map((serie, index) => {
      if (serie.childName === "usage") {
        return /* @__PURE__ */ React.createElement(
          ChartBoxPlot,
          {
            boxWidth: width < 475 ? 15 : void 0,
            data: !hiddenSeries.has(index) ? serie.data : [{ y: [null] }],
            key: serie.childName,
            name: serie.childName,
            style: serie.style
          }
        );
      }
      return null;
    });
  };
  const getChartNames = () => {
    const result = [];
    if (series) {
      series.map((serie) => {
        if (serie.childName === "usage") {
          result.push([serie.childName, "scatter"]);
        } else if (serie.childName !== "scatter") {
          result.push(serie.childName);
        }
      });
    }
    return result;
  };
  const getPadding = useCallback(() => {
    return padding ? padding : {
      bottom: 75 + extraHeight,
      // Maintain chart aspect ratio
      left: 50,
      right: 50,
      top: 10
    };
  }, [extraHeight, padding]);
  const handleOnLegendClick = (index) => {
    const newHiddenSeries = initHiddenSeries(hiddenSeries, index);
    setHiddenSeries(newHiddenSeries);
  };
  const getCursorVoronoiContainer = useCallback(() => {
    const CursorVoronoiContainer = createContainer("voronoi", "cursor");
    const labelFormatter = (datum) => {
      const formatValue = (val) => val !== void 0 ? val : "";
      if (datum.childName === "scatter") {
        return null;
      } else if (datum.childName === "usage" && (datum._min !== void 0 || datum._max !== void 0 || datum._median !== void 0 || datum._q1 !== void 0 || datum._q3 !== void 0 || datum.yVal !== null)) {
        return intl.formatMessage(messages.chartUsageTooltip, {
          br: "\n",
          min: formatValue(datum._min !== void 0 ? datum._min : datum.yVal),
          max: formatValue(datum._max !== void 0 ? datum._max : datum.yVal),
          median: formatValue(
            datum._median !== void 0 ? datum._median : datum.yVal
          ),
          q1: formatValue(datum._q1 !== void 0 ? datum._q1 : datum.yVal),
          q3: formatValue(datum._q3 !== void 0 ? datum._q3 : datum.yVal),
          units: intl.formatMessage(messages.units, {
            units: unitsLookupKey(datum.units)
          })
        });
      }
      const yVal = Array.isArray(datum.y) ? datum.y[0] : datum.y;
      let units = datum.units;
      if ((datum.childName === "limit" || datum.childName === "request") && datum.units === "") {
        units = unitsLookupKey("cores");
      }
      return yVal !== null ? intl.formatMessage(messages.valueUnits, {
        value: yVal,
        units: intl.formatMessage(messages.units, {
          units: unitsLookupKey(units)
        })
      }) : intl.formatMessage(messages.chartNoData);
    };
    return /* @__PURE__ */ React.createElement(
      CursorVoronoiContainer,
      {
        cursorDimension: "x",
        labels: ({ datum }) => labelFormatter(datum),
        mouseFollowTooltips: true,
        voronoiDimension: "x",
        voronoiPadding: getPadding()
      }
    );
  }, [getPadding, intl]);
  const getEvents = () => {
    const result = getInteractiveLegendEvents({
      chartNames: getChartNames(),
      isHidden: (index) => isSeriesHidden(hiddenSeries, index),
      legendName: `${name}-legend`,
      onLegendClick: (props) => handleOnLegendClick(props.index)
    });
    return result;
  };
  const getHeight = () => {
    return baseHeight + extraHeight;
  };
  const getLegend = () => {
    return /* @__PURE__ */ React.createElement(
      ChartLegend,
      {
        data: getLegendData(series, hiddenSeries),
        height: 25,
        gutter: 20,
        name: `${name}-legend`,
        responsive: false
      }
    );
  };
  const handleLegendAllowWrap = (value) => {
    if (value !== extraHeight) {
      setExtraHeight(value);
    }
  };
  const handleOnResize = useCallback(() => {
    const { clientWidth = 0 } = containerRef.current || {};
    if (clientWidth !== width) {
      setWidth(clientWidth);
    }
  }, [containerRef, width]);
  const initDatum = useCallback(() => {
    const newSeries = [];
    if (requestData && requestData.length) {
      newSeries.push({
        childName: "request",
        data: requestData,
        legendItem: {
          name: getDateRangeString(
            requestData,
            messages.recommendedRequest,
            true
          ),
          symbol: {
            fill: chartStyles.requestColorScale[0],
            type: "square"
          },
          tooltip: intl.formatMessage(messages.request)
        },
        style: {
          data: {
            ...chartStyles.request,
            stroke: chartStyles.requestColorScale[0]
          }
        }
      });
    }
    if (limitData && limitData.length) {
      newSeries.push({
        childName: "limit",
        data: limitData,
        legendItem: {
          name: getDateRangeString(limitData, messages.recommendedLimit, true),
          symbol: {
            fill: chartStyles.limitColorScale[0],
            type: "square"
          },
          tooltip: intl.formatMessage(messages.limit)
        },
        style: {
          data: {
            ...chartStyles.limit,
            stroke: chartStyles.limitColorScale[0]
          }
        }
      });
    }
    if (usageData && usageData.length) {
      const boxPlotData = [];
      usageData.map((datum) => {
        if (datum.y.every((val, _i, arr) => val === arr[0])) {
          boxPlotData.push({
            ...datum,
            yVal: datum.y[0],
            y: [null]
          });
        } else {
          boxPlotData.push(datum);
        }
      });
      newSeries.push({
        childName: "usage",
        data: boxPlotData,
        legendItem: {
          name: getDateRangeString(usageData, messages.actualUsage),
          symbol: {
            fill: chartStyles.usageColorScale[1],
            type: "square"
          },
          tooltip: intl.formatMessage(messages.usage)
        },
        style: {
          median: {
            stroke: chartStyles.usageColorScale[0]
          },
          q1: {
            fill: chartStyles.usageColorScale[1]
          },
          q3: {
            fill: chartStyles.usageColorScale[1]
          }
        }
      });
      const scatterData = [];
      usageData.map((datum) => {
        if (datum.y.every((val, _i, arr) => val === arr[0])) {
          scatterData.push({
            ...datum,
            y: datum.y[0]
          });
        } else {
          scatterData.push({
            ...datum,
            y: null
          });
        }
      });
      newSeries.push({
        childName: "scatter",
        data: scatterData,
        style: {
          data: { fill: chartStyles.usageColorScale[1] }
        }
      });
    }
    setSeries(newSeries);
    setCursorVoronoiContainer(getCursorVoronoiContainer());
    setHiddenSeries(/* @__PURE__ */ new Set());
  }, [getCursorVoronoiContainer, intl, limitData, requestData, usageData]);
  useMemo(() => {
    initDatum();
  }, [initDatum]);
  useEffect(() => {
    const unobserve = getResizeObserver(containerRef.current, handleOnResize);
    return () => {
      if (unobserve) {
        unobserve();
      }
    };
  }, [containerRef, handleOnResize]);
  const chartHeight = getHeight();
  return /* @__PURE__ */ React.createElement("div", { className: classes.chartOverride, ref: containerRef }, /* @__PURE__ */ React.createElement("div", { style: { height: chartHeight } }, /* @__PURE__ */ React.createElement(
    Chart,
    {
      containerComponent: cloneContainer(),
      domain: getDomain(series, hiddenSeries, 1),
      domainPadding: { x: [30, 30] },
      events: getEvents(),
      height: chartHeight,
      legendAllowWrap: handleLegendAllowWrap,
      legendComponent: getLegend(),
      legendPosition: "bottom",
      name,
      padding: getPadding(),
      theme: ChartTheme,
      width
    },
    /* @__PURE__ */ React.createElement(ChartAxis, { fixLabelOverlap: true }),
    /* @__PURE__ */ React.createElement(ChartAxis, { dependentAxis: true, showGrid: true }),
    getRequestChart(),
    getLimitChart(),
    getScatterChart(),
    getUsageChart()
  )));
};

export { OptimizationsBreakdownChart };
//# sourceMappingURL=OptimizationsBreakdownChart.esm.js.map
