'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "DeclarativeChart", {
    enumerable: true,
    get: function() {
        return DeclarativeChart;
    }
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _chartutilities = require("@fluentui/chart-utilities");
const _reacttheme = require("@fluentui/react-theme");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _tokens = require("@fluentui/tokens");
const _d3color = /*#__PURE__*/ _interop_require_wildcard._(require("d3-color"));
const _PlotlySchemaAdapter = require("./PlotlySchemaAdapter");
const _index = require("../../utilities/index");
const _AnnotationOnlyChart = require("../AnnotationOnlyChart/AnnotationOnlyChart");
const _index1 = require("../DonutChart/index");
const _index2 = require("../VerticalStackedBarChart/index");
const _index3 = require("../LineChart/index");
const _index4 = require("../HorizontalBarChartWithAxis/index");
const _index5 = require("../AreaChart/index");
const _index6 = require("../HeatMapChart/index");
const _SankeyChart = require("../SankeyChart/SankeyChart");
const _index7 = require("../GaugeChart/index");
const _index8 = require("../GroupedVerticalBarChart/index");
const _index9 = require("../VerticalBarChart/index");
const _index10 = require("../ScatterChart/index");
const _FunnelChart = require("../FunnelChart/FunnelChart");
const _index11 = require("../GanttChart/index");
const _index12 = require("../PolarChart/index");
const _withResponsiveContainer = require("../ResponsiveContainer/withResponsiveContainer");
const _index13 = require("../ChartTable/index");
const _index14 = require("../Legends/index");
const _imageexportutils = require("../../utilities/image-export-utils");
const ResponsiveDonutChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index1.DonutChart);
const ResponsiveVerticalStackedBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index2.VerticalStackedBarChart);
const ResponsiveLineChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index3.LineChart);
const ResponsiveHorizontalBarChartWithAxis = (0, _withResponsiveContainer.withResponsiveContainer)(_index4.HorizontalBarChartWithAxis);
const ResponsiveAreaChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index5.AreaChart);
const ResponsiveHeatMapChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index6.HeatMapChart);
const ResponsiveSankeyChart = (0, _withResponsiveContainer.withResponsiveContainer)(_SankeyChart.SankeyChart);
const ResponsiveGaugeChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index7.GaugeChart);
const ResponsiveGroupedVerticalBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index8.GroupedVerticalBarChart);
const ResponsiveVerticalBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index9.VerticalBarChart);
const ResponsiveScatterChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index10.ScatterChart);
const ResponsiveChartTable = (0, _withResponsiveContainer.withResponsiveContainer)(_index13.ChartTable);
const ResponsiveGanttChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index11.GanttChart);
// Removing responsive wrapper for FunnelChart as responsive container is not working with FunnelChart
//const ResponsiveFunnelChart = withResponsiveContainer(FunnelChart);
const ResponsivePolarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index12.PolarChart);
// Default x-axis key for grouping traces. Also applicable for PieData and SankeyData where x-axis is not defined.
const DEFAULT_XAXIS = 'x';
const useColorMapping = ()=>{
    const colorMap = _react.useRef(new Map());
    return colorMap;
};
function renderChart(Renderer, transformer, transformerArgs, commonProps, cellRow, cellColumn) {
    const chartProps = transformer(...transformerArgs);
    return /*#__PURE__*/ _react.createElement("div", {
        key: `${cellRow}_${cellColumn}`,
        style: {
            gridRowStart: cellRow,
            gridRowEnd: cellRow + 1,
            gridColumnStart: cellColumn,
            gridColumnEnd: cellColumn + 1
        }
    }, /*#__PURE__*/ _react.createElement(Renderer, {
        ...chartProps,
        ...commonProps
    }));
}
const LineAreaPreTransformOp = (plotlyInput)=>{
    const xValues = plotlyInput.data[0].x;
    const isXMonth = (0, _chartutilities.isMonthArray)(xValues);
    let renderData = plotlyInput.data;
    if (isXMonth) {
        renderData = plotlyInput.data.map((dataPoint)=>({
                ...dataPoint,
                x: (0, _PlotlySchemaAdapter.correctYearMonth)(dataPoint.x)
            }));
    }
    return {
        data: renderData,
        layout: plotlyInput.layout
    };
};
const chartMap = {
    annotation: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToAnnotationChartProps,
        renderer: _AnnotationOnlyChart.AnnotationOnlyChart
    },
    // PieData category charts
    donut: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToDonutProps,
        renderer: ResponsiveDonutChart
    },
    // SankeyData category charts
    sankey: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToSankeyProps,
        renderer: ResponsiveSankeyChart
    },
    // TableData category charts
    table: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToChartTableProps,
        renderer: ResponsiveChartTable
    },
    // PlotData category charts
    horizontalbar: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToHorizontalBarWithAxisProps,
        renderer: ResponsiveHorizontalBarChartWithAxis
    },
    groupedverticalbar: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToGVBCProps,
        renderer: ResponsiveGroupedVerticalBarChart
    },
    verticalstackedbar: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToVSBCProps,
        renderer: ResponsiveVerticalStackedBarChart
    },
    heatmap: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToHeatmapProps,
        renderer: ResponsiveHeatMapChart
    },
    gauge: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToGaugeProps,
        renderer: ResponsiveGaugeChart
    },
    verticalbar: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToVBCProps,
        renderer: ResponsiveVerticalBarChart
    },
    area: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToAreaChartProps,
        renderer: ResponsiveAreaChart,
        preTransformOperation: LineAreaPreTransformOp
    },
    line: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToLineChartProps,
        renderer: ResponsiveLineChart,
        preTransformOperation: LineAreaPreTransformOp
    },
    scatter: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToScatterChartProps,
        renderer: ResponsiveScatterChart,
        preTransformOperation: LineAreaPreTransformOp
    },
    gantt: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToGanttChartProps,
        renderer: ResponsiveGanttChart
    },
    funnel: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToFunnelChartProps,
        renderer: _FunnelChart.FunnelChart
    },
    scatterpolar: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToPolarChartProps,
        renderer: ResponsivePolarChart
    },
    fallback: {
        transformer: _PlotlySchemaAdapter.transformPlotlyJsonToVSBCProps,
        renderer: ResponsiveVerticalStackedBarChart
    }
};
const useIsDarkTheme = ()=>{
    const parentV9Theme = _react.useContext(_reactsharedcontexts.ThemeContext_unstable);
    const v9Theme = parentV9Theme ? parentV9Theme : _tokens.webLightTheme;
    // Get background and foreground colors
    const backgroundColor = _d3color.hsl(v9Theme.colorNeutralBackground1);
    const foregroundColor = _d3color.hsl(v9Theme.colorNeutralForeground1);
    const isDarkTheme = backgroundColor.l < foregroundColor.l;
    return isDarkTheme;
};
const DeclarativeChart = /*#__PURE__*/ _react.forwardRef(({ colorwayType = 'default', ...props }, forwardedRef)=>{
    var _plotlyInputWithValidData_layout;
    const { plotlySchema } = (0, _chartutilities.sanitizeJson)(props.chartSchema);
    const chart = (0, _chartutilities.mapFluentChart)(plotlySchema);
    if (!chart.isValid) {
        throw new Error(`Invalid chart schema: ${chart.errorMessage}`);
    }
    let plotlyInput = plotlySchema;
    try {
        plotlyInput = (0, _chartutilities.decodeBase64Fields)(plotlyInput);
    } catch (error) {
        throw new Error(`Failed to decode plotly schema: ${error}`);
    }
    const plotlyInputWithValidData = {
        ...plotlyInput,
        data: chart.validTracesInfo.map((trace)=>plotlyInput.data[trace.index])
    };
    const validTracesFilteredIndex = chart.validTracesInfo.map((trace, index)=>({
            index,
            type: trace.type
        }));
    let { selectedLegends } = plotlySchema;
    const colorMap = useColorMapping();
    const isDarkTheme = useIsDarkTheme();
    const chartRefs = _react.useRef([]);
    const isMultiPlot = _react.useRef(false);
    const legendsRef = _react.useRef(null);
    const containerRef = _react.useRef(null);
    const isRTL = (0, _index.useRtl)();
    if (!(0, _chartutilities.isArrayOrTypedArray)(selectedLegends)) {
        selectedLegends = [];
    }
    const [activeLegends, setActiveLegends] = _react.useState(selectedLegends);
    const onActiveLegendsChange = (keys)=>{
        setActiveLegends(keys);
        if (props.onSchemaChange) {
            props.onSchemaChange({
                plotlySchema: {
                    plotlyInput,
                    selectedLegends: keys
                }
            });
        }
    };
    _react.useEffect(()=>{
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const { plotlySchema } = (0, _chartutilities.sanitizeJson)(props.chartSchema);
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const { selectedLegends } = plotlySchema;
        setActiveLegends(selectedLegends !== null && selectedLegends !== void 0 ? selectedLegends : []);
    }, [
        props.chartSchema
    ]);
    const multiSelectLegendProps = {
        canSelectMultipleLegends: true,
        onChange: onActiveLegendsChange,
        selectedLegends: activeLegends
    };
    const interactiveCommonProps = {
        legendProps: multiSelectLegendProps
    };
    function createLegends(legendProps) {
        // eslint-disable-next-line react/jsx-no-bind
        return /*#__PURE__*/ _react.createElement(_index14.Legends, {
            ...legendProps,
            selectedLegends: activeLegends,
            onChange: onActiveLegendsChange,
            legendRef: legendsRef
        });
    }
    const exportAsImage = _react.useCallback(async (opts)=>{
        var _legendsRef_current;
        if (!containerRef.current) {
            throw new Error('Container reference is null');
        }
        const imgExpOpts = {
            background: (0, _index.resolveCSSVariables)(containerRef.current, _reacttheme.tokens.colorNeutralBackground1),
            scale: 5,
            ...opts
        };
        if (!isMultiPlot.current) {
            var _chartRefs_current__compRef, _chartRefs_current_;
            if (!((_chartRefs_current_ = chartRefs.current[0]) === null || _chartRefs_current_ === void 0 ? void 0 : (_chartRefs_current__compRef = _chartRefs_current_.compRef) === null || _chartRefs_current__compRef === void 0 ? void 0 : _chartRefs_current__compRef.toImage)) {
                throw new Error('Chart cannot be exported as image');
            }
            return chartRefs.current[0].compRef.toImage(imgExpOpts);
        }
        return (0, _imageexportutils.exportChartsAsImage)(chartRefs.current.map((item)=>{
            var _item_compRef;
            return {
                container: (_item_compRef = item.compRef) === null || _item_compRef === void 0 ? void 0 : _item_compRef.chartContainer,
                row: item.row,
                col: item.col
            };
        }), (_legendsRef_current = legendsRef.current) === null || _legendsRef_current === void 0 ? void 0 : _legendsRef_current.toSVG, isRTL, imgExpOpts);
    }, [
        isRTL
    ]);
    _react.useImperativeHandle(props.componentRef, ()=>({
            exportAsImage
        }), [
        exportAsImage
    ]);
    const groupedTraces = {};
    let nonCartesianTraceCount = 0;
    // For annotation-only charts, create a single group entry
    if (chart.type === 'annotation') {
        groupedTraces[DEFAULT_XAXIS] = [];
    } else {
        plotlyInputWithValidData.data.forEach((trace, index)=>{
            let traceKey = '';
            if ((0, _PlotlySchemaAdapter.isNonPlotType)(chart.validTracesInfo[index].type)) {
                traceKey = `${_PlotlySchemaAdapter.NON_PLOT_KEY_PREFIX}${nonCartesianTraceCount + 1}`;
                nonCartesianTraceCount++;
            } else {
                var _trace_subplot, _trace_xaxis;
                traceKey = chart.validTracesInfo[index].type === 'scatterpolar' ? (_trace_subplot = trace.subplot) !== null && _trace_subplot !== void 0 ? _trace_subplot : _PlotlySchemaAdapter.DEFAULT_POLAR_SUBPLOT : (_trace_xaxis = trace.xaxis) !== null && _trace_xaxis !== void 0 ? _trace_xaxis : DEFAULT_XAXIS;
            }
            if (!groupedTraces[traceKey]) {
                groupedTraces[traceKey] = [];
            }
            groupedTraces[traceKey].push(index);
        });
    }
    isMultiPlot.current = Object.keys(groupedTraces).length > 1;
    const gridProperties = (0, _PlotlySchemaAdapter.getGridProperties)(plotlyInputWithValidData, isMultiPlot.current, chart.validTracesInfo);
    // Render only one plot if the grid properties cannot determine positioning of multiple plots.
    if (isMultiPlot.current && gridProperties.templateRows === _PlotlySchemaAdapter.SINGLE_REPEAT && gridProperties.templateColumns === _PlotlySchemaAdapter.SINGLE_REPEAT) {
        if (chart.type === 'donut') {
            // If there are multiple data traces for donut/pie, picking the last one similar to plotly
            const keys = Object.keys(groupedTraces);
            keys.forEach((key, index)=>{
                if (index < keys.length - 1) {
                    delete groupedTraces[key];
                }
            });
        } else {
            Object.keys(groupedTraces).forEach((key, index)=>{
                if (index > 0) {
                    delete groupedTraces[key];
                }
            });
        }
        isMultiPlot.current = false;
    }
    const allupLegendsProps = (0, _PlotlySchemaAdapter.getAllupLegendsProps)(plotlyInputWithValidData, colorMap, colorwayType, chart.validTracesInfo, isDarkTheme);
    const titleObj = (_plotlyInputWithValidData_layout = plotlyInputWithValidData.layout) === null || _plotlyInputWithValidData_layout === void 0 ? void 0 : _plotlyInputWithValidData_layout.title;
    var _titleObj_text;
    const chartTitle = typeof titleObj === 'string' ? titleObj : (_titleObj_text = titleObj === null || titleObj === void 0 ? void 0 : titleObj.text) !== null && _titleObj_text !== void 0 ? _titleObj_text : '';
    const titleFont = typeof titleObj === 'object' ? titleObj === null || titleObj === void 0 ? void 0 : titleObj.font : undefined;
    const titleStyle = {
        ..._reacttheme.typographyStyles.caption1,
        color: _reacttheme.tokens.colorNeutralForeground1,
        textAlign: 'center',
        marginBottom: _reacttheme.tokens.spacingVerticalS,
        ...(0, _index.getChartTitleInlineStyles)(titleFont)
    };
    // map through the grouped traces and render the appropriate chart
    return /*#__PURE__*/ _react.createElement(_react.Fragment, null, isMultiPlot.current && chartTitle && /*#__PURE__*/ _react.createElement("div", {
        style: titleStyle
    }, chartTitle), /*#__PURE__*/ _react.createElement("div", {
        style: {
            display: 'grid',
            gridTemplateRows: gridProperties.templateRows,
            gridTemplateColumns: gridProperties.templateColumns
        },
        ref: containerRef
    }, Object.entries(groupedTraces).map(([xAxisKey, index], chartIdx)=>{
        var _filteredTracesInfo_;
        const plotlyInputForGroup = {
            ...plotlyInputWithValidData,
            data: index.map((idx)=>plotlyInputWithValidData.data[idx])
        };
        const filteredTracesInfo = validTracesFilteredIndex.filter((trace)=>index.includes(trace.index));
        var _filteredTracesInfo__type;
        let chartType = chart.type === 'fallback' || chart.type === 'groupedverticalbar' ? chart.type : (_filteredTracesInfo__type = (_filteredTracesInfo_ = filteredTracesInfo[0]) === null || _filteredTracesInfo_ === void 0 ? void 0 : _filteredTracesInfo_.type) !== null && _filteredTracesInfo__type !== void 0 ? _filteredTracesInfo__type : chart.type;
        if (validTracesFilteredIndex.some((trace)=>trace.type === 'line') && validTracesFilteredIndex.some((trace)=>trace.type === 'scatter')) {
            chartType = 'line';
        }
        const chartEntry = chartMap[chartType];
        if (chartEntry) {
            const { transformer, renderer, preTransformCondition, preTransformOperation } = chartEntry;
            if (preTransformCondition === undefined || preTransformCondition(plotlyInputForGroup)) {
                const transformedInput = preTransformOperation ? preTransformOperation(plotlyInputForGroup) : plotlyInputForGroup;
                const cellProperties = gridProperties.layout[xAxisKey];
                const resolvedCommonProps = chartType === 'annotation' ? {} : {
                    ...interactiveCommonProps
                };
                var _cellProperties_row, _cellProperties_column;
                return renderChart(renderer, transformer, [
                    transformedInput,
                    isMultiPlot.current,
                    colorMap,
                    colorwayType,
                    isDarkTheme
                ], {
                    ...resolvedCommonProps,
                    ...(cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.xAnnotation) && {
                        xAxisAnnotation: cellProperties.xAnnotation
                    },
                    ...(cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.yAnnotation) && {
                        yAxisAnnotation: cellProperties.yAnnotation
                    },
                    componentRef: (ref)=>{
                        var _cellProperties_row, _cellProperties_column;
                        chartRefs.current[chartIdx] = {
                            compRef: ref,
                            row: (_cellProperties_row = cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.row) !== null && _cellProperties_row !== void 0 ? _cellProperties_row : 1,
                            col: (_cellProperties_column = cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.column) !== null && _cellProperties_column !== void 0 ? _cellProperties_column : 1
                        };
                    }
                }, (_cellProperties_row = cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.row) !== null && _cellProperties_row !== void 0 ? _cellProperties_row : 1, (_cellProperties_column = cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties.column) !== null && _cellProperties_column !== void 0 ? _cellProperties_column : 1);
            }
            return /*#__PURE__*/ _react.createElement(_react.Fragment, null);
        } else {
            var _plotlyInputForGroup_data_;
            throw new Error(`Unsupported chart type :${(_plotlyInputForGroup_data_ = plotlyInputForGroup.data[0]) === null || _plotlyInputForGroup_data_ === void 0 ? void 0 : _plotlyInputForGroup_data_.type}`);
        }
    })), isMultiPlot.current && createLegends(allupLegendsProps));
});
DeclarativeChart.displayName = 'DeclarativeChart';
