'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "VegaDeclarativeChart", {
    enumerable: true,
    get: function() {
        return VegaDeclarativeChart;
    }
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _VegaLiteSchemaAdapter = require("./VegaLiteSchemaAdapter");
const _index = require("../Legends/index");
const _withResponsiveContainer = require("../ResponsiveContainer/withResponsiveContainer");
const _index1 = require("../LineChart/index");
const _index2 = require("../VerticalBarChart/index");
const _index3 = require("../VerticalStackedBarChart/index");
const _index4 = require("../GroupedVerticalBarChart/index");
const _index5 = require("../HorizontalBarChartWithAxis/index");
const _index6 = require("../AreaChart/index");
const _index7 = require("../ScatterChart/index");
const _index8 = require("../DonutChart/index");
const _index9 = require("../HeatMapChart/index");
const _index10 = require("../PolarChart/index");
const _VegaDeclarativeChartHooks = require("./VegaDeclarativeChartHooks");
/**
 * Maximum allowed nesting depth for incoming JSON specs.
 * Matches the Plotly adapter's MAX_DEPTH to prevent stack overflow / memory exhaustion.
 */ const MAX_DEPTH = 15;
/**
 * Validates that a JSON value does not exceed the maximum nesting depth.
 * Throws if the depth limit is exceeded (same behavior as Plotly's sanitizeJson).
 */ function validateJsonDepth(value, depth = 0) {
    if (depth > MAX_DEPTH) {
        throw new Error('VegaDeclarativeChart: Maximum JSON depth exceeded');
    }
    if (value !== null && typeof value === 'object') {
        for (const key of Object.keys(value)){
            validateJsonDepth(value[key], depth + 1);
        }
    }
}
/**
 * Check if spec is a horizontal concatenation
 */ function isHConcatSpec(spec) {
    return !!spec.hconcat && Array.isArray(spec.hconcat) && spec.hconcat.length > 0;
}
/**
 * Check if spec is a vertical concatenation
 */ function isVConcatSpec(spec) {
    return !!spec.vconcat && Array.isArray(spec.vconcat) && spec.vconcat.length > 0;
}
/**
 * Get grid properties for concat specs
 */ function getVegaConcatGridProperties(spec) {
    if (isHConcatSpec(spec)) {
        return {
            templateRows: 'auto',
            templateColumns: `repeat(${spec.hconcat.length}, 1fr)`,
            isHorizontal: true,
            specs: spec.hconcat
        };
    }
    if (isVConcatSpec(spec)) {
        return {
            templateRows: `repeat(${spec.vconcat.length}, auto)`,
            templateColumns: '1fr',
            isHorizontal: false,
            specs: spec.vconcat
        };
    }
    return {
        templateRows: '1fr',
        templateColumns: '1fr',
        isHorizontal: false,
        specs: [
            spec
        ]
    };
}
const ResponsiveLineChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index1.LineChart);
const ResponsiveVerticalBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index2.VerticalBarChart);
const ResponsiveVerticalStackedBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index3.VerticalStackedBarChart);
const ResponsiveGroupedVerticalBarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index4.GroupedVerticalBarChart);
const ResponsiveHorizontalBarChartWithAxis = (0, _withResponsiveContainer.withResponsiveContainer)(_index5.HorizontalBarChartWithAxis);
const ResponsiveAreaChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index6.AreaChart);
const ResponsiveScatterChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index7.ScatterChart);
const ResponsiveDonutChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index8.DonutChart);
const ResponsiveHeatMapChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index9.HeatMapChart);
const ResponsivePolarChart = (0, _withResponsiveContainer.withResponsiveContainer)(_index10.PolarChart);
const vegaChartMap = {
    line: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToLineChartProps,
        renderer: ResponsiveLineChart
    },
    bar: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToVerticalBarChartProps,
        renderer: ResponsiveVerticalBarChart
    },
    'stacked-bar': {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToVerticalStackedBarChartProps,
        renderer: ResponsiveVerticalStackedBarChart
    },
    'grouped-bar': {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToGroupedVerticalBarChartProps,
        renderer: ResponsiveGroupedVerticalBarChart
    },
    'horizontal-bar': {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToHorizontalBarChartProps,
        renderer: ResponsiveHorizontalBarChartWithAxis
    },
    area: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToAreaChartProps,
        renderer: ResponsiveAreaChart
    },
    scatter: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToScatterChartProps,
        renderer: ResponsiveScatterChart
    },
    donut: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToDonutChartProps,
        renderer: ResponsiveDonutChart
    },
    heatmap: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToHeatMapChartProps,
        renderer: ResponsiveHeatMapChart
    },
    histogram: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToHistogramProps,
        renderer: ResponsiveVerticalBarChart
    },
    polar: {
        transformer: _VegaLiteSchemaAdapter.transformVegaLiteToPolarChartProps,
        renderer: ResponsivePolarChart
    }
};
/**
 * Renders a single Vega-Lite chart spec
 */ function renderSingleChart(spec, colorMap, isDarkTheme, interactiveCommonProps) {
    const chartType = (0, _VegaLiteSchemaAdapter.getChartType)(spec);
    const chartConfig = vegaChartMap[chartType.type];
    if (!chartConfig) {
        throw new Error(`VegaDeclarativeChart: Unsupported chart type '${chartType.type}'`);
    }
    const { transformer, renderer: ChartRenderer } = chartConfig;
    const chartProps = transformer(spec, colorMap, isDarkTheme);
    // For hconcat/vconcat sub-charts, hide per-chart legends (shared legend rendered separately)
    if (spec._hideLegend) {
        chartProps.hideLegend = true;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return /*#__PURE__*/ _react.createElement(ChartRenderer, {
        ...chartProps,
        ...interactiveCommonProps
    });
}
const VegaDeclarativeChart = /*#__PURE__*/ _react.forwardRef((props, forwardedRef)=>{
    const { vegaLiteSpec, selectedLegends = [] } = props.chartSchema;
    if (!vegaLiteSpec) {
        throw new Error('VegaDeclarativeChart: vegaLiteSpec is required in chartSchema');
    }
    // Guard against excessively deep JSON specs that could cause stack overflow / memory exhaustion
    validateJsonDepth(vegaLiteSpec);
    const colorMap = (0, _VegaDeclarativeChartHooks.useColorMapping)();
    const isDarkTheme = (0, _VegaDeclarativeChartHooks.useIsDarkTheme)();
    const chartRef = _react.useRef(null);
    const [activeLegends, setActiveLegends] = _react.useState(selectedLegends);
    const onActiveLegendsChange = (keys)=>{
        setActiveLegends(keys);
        if (props.onSchemaChange) {
            props.onSchemaChange({
                vegaLiteSpec,
                selectedLegends: keys
            });
        }
    };
    _react.useEffect(()=>{
        var _props_chartSchema_selectedLegends;
        setActiveLegends((_props_chartSchema_selectedLegends = props.chartSchema.selectedLegends) !== null && _props_chartSchema_selectedLegends !== void 0 ? _props_chartSchema_selectedLegends : []);
    }, [
        props.chartSchema.selectedLegends
    ]);
    const multiSelectLegendProps = {
        canSelectMultipleLegends: true,
        onChange: onActiveLegendsChange,
        selectedLegends: activeLegends
    };
    const interactiveCommonProps = {
        componentRef: chartRef,
        legendProps: multiSelectLegendProps
    };
    try {
        // Check if this is a concat spec (multiple charts side-by-side or stacked)
        if (isHConcatSpec(vegaLiteSpec) || isVConcatSpec(vegaLiteSpec)) {
            const gridProps = getVegaConcatGridProperties(vegaLiteSpec);
            // Build shared legend from the first sub-chart's color encoding
            const firstSubSpec = {
                ...gridProps.specs[0],
                data: gridProps.specs[0].data || vegaLiteSpec.data,
                encoding: {
                    ...vegaLiteSpec.encoding || {},
                    ...gridProps.specs[0].encoding || {}
                }
            };
            const sharedLegendProps = (0, _VegaLiteSchemaAdapter.getVegaLiteLegendsProps)(firstSubSpec, colorMap, isDarkTheme);
            return /*#__PURE__*/ _react.createElement("div", {
                ref: forwardedRef,
                className: props.className,
                style: props.style
            }, /*#__PURE__*/ _react.createElement("div", {
                style: {
                    display: 'grid',
                    gridTemplateRows: gridProps.templateRows,
                    gridTemplateColumns: gridProps.templateColumns,
                    gap: '16px'
                }
            }, gridProps.specs.map((subSpec, index)=>{
                // Compute default height for sub-charts
                const defaultSubHeight = typeof vegaLiteSpec.height === 'number' ? vegaLiteSpec.height : typeof subSpec.height === 'number' ? subSpec.height : 300;
                const mergedSpec = {
                    ...subSpec,
                    data: subSpec.data || vegaLiteSpec.data,
                    encoding: {
                        ...vegaLiteSpec.encoding || {},
                        ...subSpec.encoding || {}
                    },
                    height: typeof subSpec.height === 'number' ? subSpec.height : defaultSubHeight,
                    // Hide legends on ALL sub-charts — shared legend is rendered below
                    _hideLegend: true
                };
                const cellRow = gridProps.isHorizontal ? 1 : index + 1;
                const cellColumn = gridProps.isHorizontal ? index + 1 : 1;
                return /*#__PURE__*/ _react.createElement("div", {
                    key: `chart_${index}`,
                    style: {
                        gridRowStart: cellRow,
                        gridRowEnd: cellRow + 1,
                        gridColumnStart: cellColumn,
                        gridColumnEnd: cellColumn + 1,
                        minWidth: 0
                    }
                }, renderSingleChart(mergedSpec, colorMap, isDarkTheme, interactiveCommonProps));
            })), sharedLegendProps.legends.length > 0 && /*#__PURE__*/ _react.createElement(_index.Legends, {
                ...sharedLegendProps,
                ...multiSelectLegendProps
            }));
        }
        // Check if this is a layered spec (composite chart)
        if (vegaLiteSpec.layer && vegaLiteSpec.layer.length > 1) {
            // Check if it's a supported bar+line combo
            const marks = vegaLiteSpec.layer.map((layer)=>(0, _VegaLiteSchemaAdapter.getMarkType)(layer.mark));
            const hasBar = marks.includes('bar');
            const hasLine = marks.includes('line') || marks.includes('point');
            const isBarLineCombo = hasBar && hasLine;
            // Only warn for unsupported layered specs
            if (!isBarLineCombo) {
            // Layered specifications with multiple chart types are not fully supported.
            // Only the first layer will be rendered.
            }
        }
        // Render single chart
        const chartComponent = renderSingleChart(vegaLiteSpec, colorMap, isDarkTheme, interactiveCommonProps);
        return /*#__PURE__*/ _react.createElement("div", {
            ref: forwardedRef,
            className: props.className,
            style: props.style
        }, chartComponent);
    } catch (error) {
        throw new Error(`Failed to transform Vega-Lite spec: ${error}`);
    }
});
VegaDeclarativeChart.displayName = 'VegaDeclarativeChart';
