import { __assign } from "tslib";
/* eslint-disable @typescript-eslint/naming-convention */
import * as React from 'react';
import { useTheme } from '@fluentui/react';
import { DonutChart } from '../DonutChart/index';
import { VerticalStackedBarChart } from '../VerticalStackedBarChart/index';
import { isArrayOrTypedArray, isDateArray, isNumberArray, isMonthArray, sanitizeJson, updateXValues, transformPlotlyJsonToDonutProps, transformPlotlyJsonToVSBCProps, transformPlotlyJsonToScatterChartProps, transformPlotlyJsonToHorizontalBarWithAxisProps, transformPlotlyJsonToHeatmapProps, transformPlotlyJsonToSankeyProps, transformPlotlyJsonToGaugeProps, transformPlotlyJsonToGVBCProps, transformPlotlyJsonToVBCProps, isLineData, } from './PlotlySchemaAdapter';
import { LineChart } from '../LineChart/index';
import { HorizontalBarChartWithAxis } from '../HorizontalBarChartWithAxis/index';
import { AreaChart } from '../AreaChart/index';
import { HeatMapChart } from '../HeatMapChart/index';
import { SankeyChart } from '../SankeyChart/SankeyChart';
import { GaugeChart } from '../GaugeChart/index';
import { GroupedVerticalBarChart } from '../GroupedVerticalBarChart/index';
import { VerticalBarChart } from '../VerticalBarChart/index';
import { toImage } from './imageExporter';
var useColorMapping = function () {
    var colorMap = React.useRef(new Map());
    return colorMap;
};
/**
 * DeclarativeChart component.
 * {@docCategory DeclarativeChart}
 */
export var DeclarativeChart = React.forwardRef(function (props, forwardedRef) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
    var plotlySchema = sanitizeJson(props.chartSchema).plotlySchema;
    var plotlyInput = plotlySchema;
    var selectedLegends = plotlySchema.selectedLegends;
    var colorMap = useColorMapping();
    var theme = useTheme();
    var isDarkTheme = (_a = theme === null || theme === void 0 ? void 0 : theme.isInverted) !== null && _a !== void 0 ? _a : false;
    var chartRef = React.useRef(null);
    if (!isArrayOrTypedArray(selectedLegends)) {
        selectedLegends = [];
    }
    var _l = React.useState(selectedLegends), activeLegends = _l[0], setActiveLegends = _l[1];
    var onActiveLegendsChange = function (keys) {
        setActiveLegends(keys);
        if (props.onSchemaChange) {
            props.onSchemaChange({ plotlySchema: { plotlyInput: plotlyInput, selectedLegends: keys } });
        }
    };
    React.useEffect(function () {
        // eslint-disable-next-line @typescript-eslint/no-shadow
        var plotlySchema = sanitizeJson(props.chartSchema).plotlySchema;
        // eslint-disable-next-line @typescript-eslint/no-shadow
        var selectedLegends = plotlySchema.selectedLegends;
        setActiveLegends(selectedLegends !== null && selectedLegends !== void 0 ? selectedLegends : []);
    }, [props.chartSchema]);
    var multiSelectLegendProps = {
        canSelectMultipleLegends: true,
        onChange: onActiveLegendsChange,
        selectedLegends: activeLegends,
    };
    var commonProps = {
        legendProps: multiSelectLegendProps,
        componentRef: chartRef,
        calloutProps: { layerProps: { eventBubblingEnabled: true } },
    };
    var checkAndRenderChart = function (renderChartJsx, isAreaChart) {
        if (isAreaChart === void 0) { isAreaChart = false; }
        var fallbackVSBC = false;
        var xValues = plotlyInput.data[0].x;
        var isXDate = isDateArray(xValues);
        var isXNumber = isNumberArray(xValues);
        var isXMonth = isMonthArray(xValues);
        if (isXDate || isXNumber) {
            var chartProps = __assign(__assign({}, transformPlotlyJsonToScatterChartProps({ data: plotlyInput.data, layout: plotlyInput.layout }, isAreaChart, colorMap, isDarkTheme)), commonProps);
            return renderChartJsx(chartProps);
        }
        else if (isXMonth) {
            var updatedData = plotlyInput.data.map(function (dataPoint) { return (__assign(__assign({}, dataPoint), { x: updateXValues(dataPoint.x) })); });
            var chartProps = __assign(__assign({}, transformPlotlyJsonToScatterChartProps({ data: updatedData, layout: plotlyInput.layout }, isAreaChart, colorMap, isDarkTheme)), commonProps);
            return renderChartJsx(chartProps);
        }
        // Unsupported schema, render as VerticalStackedBarChart
        fallbackVSBC = true;
        return (React.createElement(VerticalStackedBarChart, __assign({}, transformPlotlyJsonToVSBCProps(plotlySchema, colorMap, isDarkTheme, fallbackVSBC), commonProps)));
    };
    var exportAsImage = React.useCallback(function (opts) {
        var _a;
        return toImage((_a = chartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer, __assign({ background: theme.semanticColors.bodyBackground, scale: 5 }, opts));
    }, [theme]);
    React.useImperativeHandle(props.componentRef, function () { return ({
        exportAsImage: exportAsImage,
    }); }, [exportAsImage]);
    switch (plotlyInput.data[0].type) {
        case 'pie':
            return React.createElement(DonutChart, __assign({}, transformPlotlyJsonToDonutProps(plotlySchema, colorMap, isDarkTheme), commonProps));
        case 'bar':
            var orientation_1 = plotlyInput.data[0].orientation;
            if (orientation_1 === 'h') {
                return (React.createElement(HorizontalBarChartWithAxis, __assign({}, transformPlotlyJsonToHorizontalBarWithAxisProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
            }
            else {
                var containsLines = plotlyInput.data.some(function (series) { return series.type === 'scatter' || isLineData(series); });
                if (['group', 'overlay'].includes((_b = plotlySchema === null || plotlySchema === void 0 ? void 0 : plotlySchema.layout) === null || _b === void 0 ? void 0 : _b.barmode) && !containsLines) {
                    return (React.createElement(GroupedVerticalBarChart, __assign({}, transformPlotlyJsonToGVBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
                }
                return (React.createElement(VerticalStackedBarChart, __assign({}, transformPlotlyJsonToVSBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
            }
        case 'scatter':
            if (plotlyInput.data[0].mode === 'markers') {
                throw new Error("Unsupported chart - type :".concat((_c = plotlyInput.data[0]) === null || _c === void 0 ? void 0 : _c.type, ", mode: ").concat((_d = plotlyInput.data[0]) === null || _d === void 0 ? void 0 : _d.mode));
            }
            var isAreaChart_1 = plotlyInput.data.some(function (series) { return series.fill === 'tonexty' || series.fill === 'tozeroy'; });
            var renderChartJsx = function (chartProps) {
                if (isAreaChart_1) {
                    return React.createElement(AreaChart, __assign({}, chartProps));
                }
                return React.createElement(LineChart, __assign({}, chartProps));
            };
            return checkAndRenderChart(renderChartJsx, isAreaChart_1);
        case 'heatmap':
            return React.createElement(HeatMapChart, __assign({}, transformPlotlyJsonToHeatmapProps(plotlySchema), commonProps, { legendProps: {} }));
        case 'sankey':
            return (React.createElement(SankeyChart, __assign({}, transformPlotlyJsonToSankeyProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
        case 'indicator':
            if ((_g = (_f = (_e = plotlyInput.data) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.mode) === null || _g === void 0 ? void 0 : _g.includes('gauge')) {
                return (React.createElement(GaugeChart, __assign({}, transformPlotlyJsonToGaugeProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
            }
            throw new Error("Unsupported chart - type: ".concat((_h = plotlyInput.data[0]) === null || _h === void 0 ? void 0 : _h.type, ", mode: ").concat((_j = plotlyInput.data[0]) === null || _j === void 0 ? void 0 : _j.mode));
        case 'histogram':
            return (React.createElement(VerticalBarChart, __assign({}, transformPlotlyJsonToVBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
        default:
            var xValues = plotlyInput.data[0].x;
            var yValues = plotlyInput.data[0].y;
            if (xValues && yValues && xValues.length > 0 && yValues.length > 0) {
                var renderLineChartJsx = function (chartProps) {
                    return React.createElement(LineChart, __assign({}, chartProps));
                };
                return checkAndRenderChart(renderLineChartJsx);
            }
            throw new Error("Unsupported chart type :".concat((_k = plotlyInput.data[0]) === null || _k === void 0 ? void 0 : _k.type));
    }
});
DeclarativeChart.displayName = 'DeclarativeChart';
//# sourceMappingURL=DeclarativeChart.js.map