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 { withResponsiveContainer } from '../ResponsiveContainer/withResponsiveContainer';
var ResponsiveDonutChart = withResponsiveContainer(DonutChart);
var ResponsiveVerticalStackedBarChart = withResponsiveContainer(VerticalStackedBarChart);
var ResponsiveLineChart = withResponsiveContainer(LineChart);
var ResponsiveHorizontalBarChartWithAxis = withResponsiveContainer(HorizontalBarChartWithAxis);
var ResponsiveAreaChart = withResponsiveContainer(AreaChart);
var ResponsiveHeatMapChart = withResponsiveContainer(HeatMapChart);
var ResponsiveSankeyChart = withResponsiveContainer(SankeyChart);
var ResponsiveGaugeChart = withResponsiveContainer(GaugeChart);
var ResponsiveGroupedVerticalBarChart = withResponsiveContainer(GroupedVerticalBarChart);
var ResponsiveVerticalBarChart = withResponsiveContainer(VerticalBarChart);
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, _l, _m, _o, _p, _q, _r, _s;
    var plotlySchema = sanitizeJson(props.chartSchema).plotlySchema;
    var plotlyInput = (function () {
        try {
            return plotlySchema;
        }
        catch (error) {
            throw new Error("Invalid plotly schema: ".concat(error));
        }
    })();
    if (!plotlyInput) {
        throw new Error('Plotly input is null or undefined');
    }
    if (!plotlyInput.data) {
        throw new Error('Plotly input data is null or undefined');
    }
    if (plotlyInput.data.length === 0) {
        throw new Error('Plotly input data is empty');
    }
    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 _t = React.useState(selectedLegends), activeLegends = _t[0], setActiveLegends = _t[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(ResponsiveVerticalStackedBarChart, __assign({}, transformPlotlyJsonToVSBCProps(plotlySchema, colorMap, isDarkTheme, fallbackVSBC), commonProps)));
    };
    var exportAsImage = React.useCallback(function (opts) {
        return new Promise(function (resolve, reject) {
            if (!chartRef.current || typeof chartRef.current.toImage !== 'function') {
                return reject(Error('Chart cannot be exported as image'));
            }
            chartRef.current
                .toImage(__assign({ background: theme.semanticColors.bodyBackground, scale: 5 }, opts))
                .then(resolve)
                .catch(reject);
        });
    }, [theme]);
    React.useImperativeHandle(props.componentRef, function () { return ({
        exportAsImage: exportAsImage,
    }); }, [exportAsImage]);
    switch (plotlyInput.data[0].type) {
        case 'pie':
            return (React.createElement(ResponsiveDonutChart, __assign({}, transformPlotlyJsonToDonutProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
        case 'bar':
            var orientation_1 = plotlyInput.data[0].orientation;
            var containsBase = plotlyInput.data.some(function (series) { return series.base !== undefined; });
            if (orientation_1 === 'h' && containsBase) {
                throw new Error('Unsupported chart type: Gantt');
            }
            else if (orientation_1 === 'h' && isNumberArray(plotlyInput.data[0].x)) {
                return (React.createElement(ResponsiveHorizontalBarChartWithAxis, __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(ResponsiveGroupedVerticalBarChart, __assign({}, transformPlotlyJsonToGVBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
                }
                return (React.createElement(ResponsiveVerticalStackedBarChart, __assign({}, transformPlotlyJsonToVSBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
            }
        case 'scatter':
            if (((_d = (_c = plotlyInput.data[0]) === null || _c === void 0 ? void 0 : _c.mode) === null || _d === void 0 ? void 0 : _d.includes('markers')) && !isNumberArray(plotlyInput.data[0].y)) {
                throw new Error("Unsupported chart - type :".concat((_e = plotlyInput.data[0]) === null || _e === void 0 ? void 0 : _e.type, ", mode: ").concat((_f = plotlyInput.data[0]) === null || _f === void 0 ? void 0 : _f.mode, "\n          , xAxisType: String or Date"));
            }
            var isAreaChart_1 = plotlyInput.data.some(function (series) { return series.fill === 'tonexty' || series.fill === 'tozeroy'; });
            var isScatterMarkers_1 = (_h = (_g = plotlyInput.data[0]) === null || _g === void 0 ? void 0 : _g.mode) === null || _h === void 0 ? void 0 : _h.includes('markers');
            var renderChartJsx = function (chartProps) {
                if (isAreaChart_1) {
                    return React.createElement(ResponsiveAreaChart, __assign({}, chartProps));
                }
                return React.createElement(ResponsiveLineChart, __assign({}, chartProps, { lineMode: isScatterMarkers_1 ? 'scatter' : 'default' }));
            };
            return checkAndRenderChart(renderChartJsx, isAreaChart_1);
        case 'heatmap':
            return (React.createElement(ResponsiveHeatMapChart, __assign({}, transformPlotlyJsonToHeatmapProps(plotlySchema), commonProps, { legendProps: {} })));
        case 'sankey':
            return (React.createElement(ResponsiveSankeyChart, __assign({}, transformPlotlyJsonToSankeyProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
        case 'indicator':
        case 'gauge':
            if (((_l = (_k = (_j = plotlyInput.data) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.mode) === null || _l === void 0 ? void 0 : _l.includes('gauge')) || ((_o = (_m = plotlyInput.data) === null || _m === void 0 ? void 0 : _m[0]) === null || _o === void 0 ? void 0 : _o.type) === 'gauge') {
                return (React.createElement(ResponsiveGaugeChart, __assign({}, transformPlotlyJsonToGaugeProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
            }
            throw new Error("Unsupported chart - type: ".concat((_p = plotlyInput.data[0]) === null || _p === void 0 ? void 0 : _p.type, ", mode: ").concat((_q = plotlyInput.data[0]) === null || _q === void 0 ? void 0 : _q.mode));
        case 'histogram':
            return (React.createElement(ResponsiveVerticalBarChart, __assign({}, transformPlotlyJsonToVBCProps(plotlySchema, colorMap, isDarkTheme), commonProps)));
        case 'contour':
            throw new Error("Unsupported chart - type: ".concat((_r = plotlyInput.data[0]) === null || _r === void 0 ? void 0 : _r.type));
        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(ResponsiveLineChart, __assign({}, chartProps));
                };
                return checkAndRenderChart(renderLineChartJsx);
            }
            throw new Error("Unsupported chart type :".concat((_s = plotlyInput.data[0]) === null || _s === void 0 ? void 0 : _s.type));
    }
});
DeclarativeChart.displayName = 'DeclarativeChart';
//# sourceMappingURL=DeclarativeChart.js.map