function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_with_holes(arr) {
    if (Array.isArray(arr)) return arr;
}
function _array_without_holes(arr) {
    if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _iterable_to_array(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterable_to_array_limit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
        for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
            _arr.push(_s.value);
            if (i && _arr.length === i) break;
        }
    } catch (err) {
        _d = true;
        _e = err;
    } finally{
        try {
            if (!_n && _i["return"] != null) _i["return"]();
        } finally{
            if (_d) throw _e;
        }
    }
    return _arr;
}
function _non_iterable_rest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _non_iterable_spread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _object_spread(target) {
    for(var i = 1; i < arguments.length; i++){
        var source = arguments[i] != null ? arguments[i] : {};
        var ownKeys = Object.keys(source);
        if (typeof Object.getOwnPropertySymbols === "function") {
            ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
                return Object.getOwnPropertyDescriptor(source, sym).enumerable;
            }));
        }
        ownKeys.forEach(function(key) {
            _define_property(target, key, source[key]);
        });
    }
    return target;
}
function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);
    if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) {
            symbols = symbols.filter(function(sym) {
                return Object.getOwnPropertyDescriptor(object, sym).enumerable;
            });
        }
        keys.push.apply(keys, symbols);
    }
    return keys;
}
function _object_spread_props(target, source) {
    source = source != null ? source : {};
    if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
    } else {
        ownKeys(Object(source)).forEach(function(key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
    }
    return target;
}
function _object_without_properties(source, excluded) {
    if (source == null) return {};
    var target = {}, sourceKeys, key, i;
    if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
        sourceKeys = Reflect.ownKeys(source);
        for(i = 0; i < sourceKeys.length; i++){
            key = sourceKeys[i];
            if (excluded.indexOf(key) >= 0) continue;
            if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
            target[key] = source[key];
        }
        return target;
    }
    target = _object_without_properties_loose(source, excluded);
    if (Object.getOwnPropertySymbols) {
        sourceKeys = Object.getOwnPropertySymbols(source);
        for(i = 0; i < sourceKeys.length; i++){
            key = sourceKeys[i];
            if (excluded.indexOf(key) >= 0) continue;
            if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
            target[key] = source[key];
        }
    }
    return target;
}
function _object_without_properties_loose(source, excluded) {
    if (source == null) return {};
    var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
    for(i = 0; i < sourceKeys.length; i++){
        key = sourceKeys[i];
        if (excluded.indexOf(key) >= 0) continue;
        if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
        target[key] = source[key];
    }
    return target;
}
function _sliced_to_array(arr, i) {
    return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _to_consumable_array(arr) {
    return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
import { ConfigProvider } from "antd";
import { BarElement, CategoryScale, Chart as ChartJS, Legend, LinearScale, Tooltip } from "chart.js";
import classNames from "clsx";
import React, { useContext, useEffect, useMemo, useRef, useState } from "react";
import { Bar } from "react-chartjs-2";
import ChartStatistic from "../ChartStatistic";
import { ChartContainer, ChartFilter, ChartToolBar, downloadChart } from "../components";
import { defaultColorList } from "../const";
import { findDataPointByXValue, isXValueEqual, resolveCssVariable, toNumber } from "../utils";
import { useStyle } from "./style";
var funnelChartComponentsRegistered = false;
var FunnelChart = function FunnelChart(_0) {
    var title = _0.title, data = _0.data, color = _0.color, _0_width = _0.width, width = _0_width === void 0 ? 600 : _0_width, _0_height = _0.height, height = _0_height === void 0 ? 400 : _0_height, className = _0.className, classNamesProp = _0.classNames, dataTime = _0.dataTime, _0_theme = _0.theme, theme = _0_theme === void 0 ? 'light' : _0_theme, _0_showLegend = _0.showLegend, showLegend = _0_showLegend === void 0 ? true : _0_showLegend, _0_legendPosition = _0.legendPosition, legendPosition = _0_legendPosition === void 0 ? 'bottom' : _0_legendPosition, _0_legendAlign = _0.legendAlign, legendAlign = _0_legendAlign === void 0 ? 'start' : _0_legendAlign, _0_showPercent = _0.showPercent, showPercent = _0_showPercent === void 0 ? true : _0_showPercent, toolbarExtra = _0.toolbarExtra, _0_renderFilterInToolbar = _0.renderFilterInToolbar, renderFilterInToolbar = _0_renderFilterInToolbar === void 0 ? false : _0_renderFilterInToolbar, _0_bottomLayerMinWidth = _0.bottomLayerMinWidth, bottomLayerMinWidth = _0_bottomLayerMinWidth === void 0 ? 0 : _0_bottomLayerMinWidth, typeNames = _0.typeNames, statisticConfig = _0.statistic, _0_loading = _0.loading, loading = _0_loading === void 0 ? false : _0_loading, props = _object_without_properties(_0, [
        "title",
        "data",
        "color",
        "width",
        "height",
        "className",
        "classNames",
        "dataTime",
        "theme",
        "showLegend",
        "legendPosition",
        "legendAlign",
        "showPercent",
        "toolbarExtra",
        "renderFilterInToolbar",
        "bottomLayerMinWidth",
        "typeNames",
        "statistic",
        "loading"
    ]);
    var _props_styles, _props_styles1, _props_styles2, _props_styles3;
    useMemo(function() {
        if (funnelChartComponentsRegistered) {
            return undefined;
        }
        if (typeof window === 'undefined') {
            return undefined;
        }
        ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend);
        funnelChartComponentsRegistered = true;
        return undefined;
    }, []);
    var safeData = Array.isArray(data) ? data : [];
    // 处理 ChartStatistic 组件配置
    var statistics = useMemo(function() {
        if (!statisticConfig) return null;
        return Array.isArray(statisticConfig) ? statisticConfig : [
            statisticConfig
        ];
    }, [
        statisticConfig
    ]);
    // 响应式尺寸
    var _useState = _sliced_to_array(useState(typeof window !== 'undefined' ? window.innerWidth : 768), 2), windowWidth = _useState[0], setWindowWidth = _useState[1];
    var isMobile = windowWidth <= 768;
    useEffect(function() {
        var handleResize = function handleResize() {
            return setWindowWidth(window.innerWidth);
        };
        if (typeof window !== 'undefined') {
            window.addEventListener('resize', handleResize);
            return function() {
                return window.removeEventListener('resize', handleResize);
            };
        }
    }, []);
    // 样式注册
    var context = useContext(ConfigProvider.ConfigContext);
    var baseClassName = context === null || context === void 0 ? void 0 : context.getPrefixCls('funnel-chart-container');
    var wrapSSR = useStyle(baseClassName).wrapSSR;
    var chartRef = useRef(null);
    var _useState1 = _sliced_to_array(useState(true), 2), showTrapezoid = _useState1[0], setShowTrapezoid = _useState1[1];
    var _useState2 = _sliced_to_array(useState(0), 2), pluginToggleKey = _useState2[0], setPluginToggleKey = _useState2[1];
    // 类别筛选（外层）
    var categories = useMemo(function() {
        return _to_consumable_array(new Set(safeData.map(function(d) {
            return d.category;
        })));
    }, [
        safeData
    ]);
    // 状态
    var _useState3 = _sliced_to_array(useState(categories.find(Boolean) || ''), 2), selectedFilter = _useState3[0], setSelectedFilter = _useState3[1];
    var _useState4 = _sliced_to_array(useState(undefined), 2), selectedFilterLabel = _useState4[0], setSelectedFilterLabel = _useState4[1];
    // 二级筛选（可选）- 仅基于当前选中 category 的可用标签
    var filterLabels = useMemo(function() {
        var labels = safeData.filter(function(d) {
            return !selectedFilter || d.category === selectedFilter;
        }).map(function(d) {
            return d.filterLabel;
        }).filter(function(v) {
            return v !== undefined;
        });
        return labels.length > 0 ? _to_consumable_array(new Set(labels)) : undefined;
    }, [
        safeData,
        selectedFilter
    ]);
    // 当切换 category 时，如当前二级筛选不在可选列表中，则重置为该类目第一项或清空
    useEffect(function() {
        var first = filterLabels && filterLabels.length > 0 ? filterLabels[0] : undefined;
        if (!filterLabels || filterLabels.length === 0) {
            if (selectedFilterLabel !== undefined) setSelectedFilterLabel(undefined);
            return;
        }
        if (!selectedFilterLabel || !filterLabels.includes(selectedFilterLabel)) {
            setSelectedFilterLabel(first);
        }
    }, [
        filterLabels
    ]);
    // 数据筛选
    var filteredData = useMemo(function() {
        var base = selectedFilter ? safeData.filter(function(d) {
            return d.category === selectedFilter;
        }) : safeData;
        var withFilterLabel = !filterLabels || !selectedFilterLabel ? base : base.filter(function(d) {
            return d.filterLabel === selectedFilterLabel;
        });
        // 统一过滤掉 x 为空（null/undefined）的数据，避免后续 toString 报错
        return withFilterLabel.filter(function(d) {
            return d.x !== null && d.x !== undefined;
        });
    }, [
        safeData,
        selectedFilter,
        filterLabels,
        selectedFilterLabel
    ]);
    // 阶段（使用 x 值作为阶段名称），按 y 从大到小排序以符合漏斗习惯
    var stages = useMemo(function() {
        var unique = _to_consumable_array(new Set(filteredData.map(function(d) {
            return d.x;
        }).filter(function(x) {
            return x !== null && x !== undefined;
        })));
        // 映射阶段 -> 数值
        var values = unique.map(function(x) {
            var dp = findDataPointByXValue(filteredData, x);
            var n = toNumber(dp === null || dp === void 0 ? void 0 : dp.y, 0);
            return {
                x: x,
                n: n
            };
        });
        // 降序
        values.sort(function(a, b) {
            return b.n - a.n;
        });
        return values.map(function(v) {
            return v.x;
        });
    }, [
        filteredData
    ]);
    var BAR_THICKNESS = 30;
    var ROW_GAP = 24;
    var PADDING_Y = isMobile ? 48 : 64;
    // 计算图表高度
    var chartHeight = useMemo(function() {
        var rows = Math.max(1, stages.length);
        return rows * (BAR_THICKNESS + ROW_GAP) + PADDING_Y;
    }, [
        stages.length,
        PADDING_Y
    ]);
    // 最终高度计算逻辑
    var finalHeight = useMemo(function() {
        if (typeof height === 'number') {
            return height;
        } else if (typeof height === 'string' && height.includes('px')) {
            return parseInt(height, 10) || chartHeight;
        }
        return chartHeight;
    }, [
        height,
        chartHeight
    ]);
    // 原始值
    var originalValues = useMemo(function() {
        return stages.map(function(x) {
            var dp = findDataPointByXValue(filteredData, x);
            return toNumber(dp === null || dp === void 0 ? void 0 : dp.y, 0);
        });
    }, [
        filteredData,
        stages
    ]);
    // 计算数据：使用浮动条 [-w/2, w/2] 居中呈现，形成对称“漏斗条”
    var processedData = useMemo(function() {
        var baseColor = color || defaultColorList[0];
        // 解析 CSS 变量为实际颜色值（Canvas 需要实际颜色值）
        var resolvedBaseColor = resolveCssVariable(baseColor);
        var labels = stages.map(function(x) {
            return x.toString();
        });
        var values = stages.map(function(x) {
            var dp = findDataPointByXValue(filteredData, x);
            var n = toNumber(dp === null || dp === void 0 ? void 0 : dp.y, 0);
            return n;
        });
        // 取当前数据的类型名作为数据集 label
        var typeName = (typeNames === null || typeNames === void 0 ? void 0 : typeNames.name) || '转化';
        // 应用最小宽度约束
        var adjustedValues = function() {
            var _Math, _Math1;
            // 非法值（≤0 或 >1）都视为不限制
            if (bottomLayerMinWidth <= 0 || bottomLayerMinWidth > 1 || values.length === 0) {
                return values;
            }
            var maxValue = (_Math = Math).max.apply(_Math, _to_consumable_array(values));
            var minValue = (_Math1 = Math).min.apply(_Math1, _to_consumable_array(values));
            // 如果最小值已经满足最小宽度要求，无需调整
            if (minValue >= maxValue * bottomLayerMinWidth) {
                return values;
            }
            // 线性映射到 [minWidth, maxValue] 区间
            var minWidth = bottomLayerMinWidth * maxValue;
            var range = maxValue - minValue;
            return values.map(function(v) {
                if (range === 0) return maxValue;
                var normalized = (v - minValue) / range;
                return minWidth + normalized * (maxValue - minWidth);
            });
        }();
        // 中心对称的浮动条：[-v/2, v/2]
        var datasetData = adjustedValues.map(function(v) {
            return [
                -v / 2,
                v / 2
            ];
        });
        // 生成从上到下由深到浅的颜色
        var hexToRgb = function hexToRgb(hex) {
            var s = hex.replace('#', '');
            var bigint = parseInt(s, 16);
            return {
                r: bigint >> 16 & 255,
                g: bigint >> 8 & 255,
                b: bigint & 255
            };
        };
        var rgbToHex = function rgbToHex(r, g, b) {
            return "#".concat([
                r,
                g,
                b
            ].map(function(v) {
                return Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0');
            }).join(''));
        };
        var lighten = function lighten(hex, t) {
            var _hexToRgb = hexToRgb(hex), r = _hexToRgb.r, g = _hexToRgb.g, b = _hexToRgb.b;
            var lr = r + (255 - r) * t;
            var lg = g + (255 - g) * t;
            var lb = b + (255 - b) * t;
            return rgbToHex(lr, lg, lb);
        };
        var count = Math.max(1, stages.length - 1);
        var colorList = stages.map(function(_, i) {
            var t = i / count * 0.6; // 限制变浅上限，避免变白
            return lighten(resolvedBaseColor, t);
        });
        return {
            labels: labels,
            datasets: [
                {
                    label: typeName,
                    data: datasetData,
                    backgroundColor: colorList,
                    borderColor: colorList,
                    borderWidth: 0,
                    borderRadius: 0,
                    borderSkipped: false,
                    barThickness: BAR_THICKNESS,
                    categoryPercentage: 1,
                    barPercentage: 1
                }
            ]
        };
    }, [
        filteredData,
        stages,
        bottomLayerMinWidth,
        color,
        typeNames
    ]);
    var ratioDisplay = useMemo(function() {
        var formatRaw = function formatRaw(v) {
            if (v === null || v === undefined) return undefined;
            if (typeof v === 'string') {
                var s = v.trim();
                if (!s) return undefined;
                return s.endsWith('%') ? s : "".concat(s, "%");
            }
            if (typeof v === 'number' && Number.isFinite(v)) {
                return "".concat(String(v), "%");
            }
            return undefined;
        };
        // 检查除顶层外，是否至少有一层提供了 ratio
        var anyNonTopProvided = stages.some(function(_, i) {
            if (i === 0) return false;
            var prevStage = stages[i - 1];
            var dp = (filteredData || []).find(function(d) {
                return isXValueEqual(d.x, prevStage);
            });
            var v = dp === null || dp === void 0 ? void 0 : dp.ratio;
            if (v === null || v === undefined) return false;
            if (typeof v === 'string') return v.trim() !== '';
            return true;
        });
        return stages.map(function(_, i) {
            if (i === 0) return anyNonTopProvided ? '100%' : undefined;
            var prevStage = stages[i - 1];
            var dp = (filteredData || []).find(function(d) {
                return isXValueEqual(d.x, prevStage);
            });
            return formatRaw(dp === null || dp === void 0 ? void 0 : dp.ratio);
        });
    }, [
        filteredData,
        stages
    ]);
    var ratioProvided = useMemo(function() {
        return stages.map(function(_, i) {
            if (i === 0) return false;
            var prevStage = stages[i - 1];
            var dp = (filteredData || []).find(function(d) {
                return isXValueEqual(d.x, prevStage);
            });
            var v = dp === null || dp === void 0 ? void 0 : dp.ratio;
            if (v === null || v === undefined) return false;
            if (typeof v === 'string') return v.trim() !== '';
            return true;
        });
    }, [
        filteredData,
        stages
    ]);
    // 过滤器选项
    var filterOptions = useMemo(function() {
        return categories.map(function(c) {
            return {
                label: c || '默认',
                value: c || '默认'
            };
        });
    }, [
        categories
    ]);
    var customOptions = useMemo(function() {
        return filterLabels === null || filterLabels === void 0 ? void 0 : filterLabels.map(function(l) {
            return {
                key: l,
                label: l
            };
        });
    }, [
        filterLabels
    ]);
    var isLight = theme === 'light';
    var axisTextColor = isLight ? 'rgba(0, 25, 61, 0.3255)' : 'rgba(255, 255, 255, 0.8)';
    var options = {
        responsive: true,
        maintainAspectRatio: false,
        indexAxis: 'y',
        layout: {
            padding: {
                left: 8,
                right: isMobile ? 72 : 96,
                top: 8,
                bottom: 8
            }
        },
        parsing: {
            // 允许使用 [start, end] 浮动条
            xAxisKey: undefined,
            yAxisKey: undefined
        },
        plugins: {
            legend: {
                display: showLegend,
                position: legendPosition,
                align: legendAlign,
                labels: {
                    color: axisTextColor,
                    font: {
                        size: isMobile ? 10 : 12,
                        weight: 'normal'
                    },
                    padding: isMobile ? 10 : 12,
                    usePointStyle: true,
                    pointStyle: 'rectRounded',
                    generateLabels: function generateLabels(chart) {
                        // @ts-ignore
                        var base = (ChartJS.defaults.plugins.legend.labels.generateLabels(chart) || []).map(function(it) {
                            return _object_spread_props(_object_spread({}, it), {
                                pointStyle: 'rectRounded'
                            });
                        });
                        // 若除顶层外没有任何 ratio，则移除“转化率”图例
                        var anyNonTopProvided = stages.some(function(_, i) {
                            if (i === 0) return false;
                            var prevStage = stages[i - 1];
                            var dp = (filteredData || []).find(function(d) {
                                return isXValueEqual(d.x, prevStage);
                            });
                            var v = dp === null || dp === void 0 ? void 0 : dp.ratio;
                            if (v === null || v === undefined) return false;
                            if (typeof v === 'string') return v.trim() !== '';
                            return true;
                        });
                        if (!anyNonTopProvided) return base;
                        return _to_consumable_array(base).concat([
                            {
                                text: (typeNames === null || typeNames === void 0 ? void 0 : typeNames.rate) || '转化率',
                                fillStyle: '#F1F2F4',
                                strokeStyle: '#F1F2F4',
                                lineWidth: 0,
                                hidden: !showTrapezoid,
                                datasetIndex: chart.data.datasets.length,
                                pointStyle: 'rectRounded'
                            }
                        ]);
                    }
                },
                onClick: function onClick(e, legendItem, legend) {
                    if (legendItem.text === ((typeNames === null || typeNames === void 0 ? void 0 : typeNames.rate) || '转化率')) {
                        setShowTrapezoid(function(v) {
                            return !v;
                        });
                        setPluginToggleKey(function(k) {
                            return k + 1;
                        });
                        return;
                    }
                    // 其它保持默认行为
                    // @ts-ignore
                    var defaultClick = ChartJS.defaults.plugins.legend.onClick;
                    if (typeof defaultClick === 'function') defaultClick.call(legend, e, legendItem, legend);
                }
            },
            tooltip: {
                backgroundColor: isLight ? 'rgba(255,255,255,0.95)' : 'rgba(0,0,0,0.85)',
                titleColor: isLight ? '#333' : '#fff',
                bodyColor: isLight ? '#333' : '#fff',
                borderColor: isLight ? 'rgba(0,0,0,0.12)' : 'rgba(255,255,255,0.2)',
                borderWidth: 1,
                cornerRadius: isMobile ? 6 : 8,
                padding: 8,
                displayColors: false,
                callbacks: {
                    title: function title(items) {
                        var it = items === null || items === void 0 ? void 0 : items[0];
                        return (it === null || it === void 0 ? void 0 : it.label) ? String(it.label) : '';
                    },
                    label: function label(ctx) {
                        var _ctx_dataIndex, _ref;
                        // 使用原始值而非调整后的视觉宽度
                        var idx = (_ctx_dataIndex = ctx.dataIndex) !== null && _ctx_dataIndex !== void 0 ? _ctx_dataIndex : 0;
                        var originalValue = (_ref = originalValues === null || originalValues === void 0 ? void 0 : originalValues[idx]) !== null && _ref !== void 0 ? _ref : 0;
                        var percentStr = ratioDisplay === null || ratioDisplay === void 0 ? void 0 : ratioDisplay[idx];
                        // 仅当传入了 ratio 时展示百分比，否则只展示数值
                        if (showPercent === false || !percentStr) {
                            return "".concat(originalValue);
                        }
                        return "".concat(originalValue, "（").concat(percentStr, "）");
                    }
                }
            }
        },
        scales: {
            y: {
                grid: {
                    display: false
                },
                ticks: {
                    display: false
                },
                title: {
                    display: false
                },
                border: {
                    display: false
                },
                afterFit: function afterFit(scale) {
                    var rows = Math.max(1, stages.length);
                    var per = BAR_THICKNESS + ROW_GAP;
                    var total = rows * per;
                    scale.height = total;
                }
            },
            x: {
                beginAtZero: true,
                grid: {
                    display: false
                },
                ticks: {
                    display: false
                },
                title: {
                    display: false
                },
                border: {
                    display: false
                }
            }
        },
        animation: {
            duration: isMobile ? 200 : 400
        }
    };
    var handleDownload = function handleDownload() {
        return downloadChart(chartRef.current, 'funnel-chart');
    };
    // 中间梯形 + 比率文本（梯形 #F1F2F4，文本 #626F86）
    var trapezoidPlugin = useMemo(function() {
        return {
            id: 'funnelTrapezoidLabels',
            afterDatasetsDraw: function afterDatasetsDraw(chart) {
                var _cdata_datasets_, _cdata_datasets;
                if (!showTrapezoid) return;
                var ctx = chart.ctx, cdata = chart.data, scales = chart.scales;
                var meta = chart.getDatasetMeta(0);
                if (!meta) return;
                var xScale = scales === null || scales === void 0 ? void 0 : scales.x;
                var ds = (cdata === null || cdata === void 0 ? void 0 : (_cdata_datasets = cdata.datasets) === null || _cdata_datasets === void 0 ? void 0 : (_cdata_datasets_ = _cdata_datasets[0]) === null || _cdata_datasets_ === void 0 ? void 0 : _cdata_datasets_.data) || [];
                var providedRatioText = ratioDisplay;
                var providedFlags = ratioProvided;
                var centerX = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(0) : undefined;
                // 逐对绘制 i 与 i+1 之间的梯形
                for(var i = 0; i < meta.data.length - 1; i++){
                    var _rawTop_, _rawTop_1, _rawBot_, _rawBot_1, _ref;
                    var elTop = meta.data[i];
                    var elBot = meta.data[i + 1];
                    var rawTop = ds === null || ds === void 0 ? void 0 : ds[i];
                    var rawBot = ds === null || ds === void 0 ? void 0 : ds[i + 1];
                    if (!Array.isArray(rawTop) || !Array.isArray(rawBot)) continue;
                    // 顶部、底部条的像素左右与宽度
                    var _ref1 = [
                        Number((_rawTop_ = rawTop[0]) !== null && _rawTop_ !== void 0 ? _rawTop_ : 0),
                        Number((_rawTop_1 = rawTop[1]) !== null && _rawTop_1 !== void 0 ? _rawTop_1 : 0)
                    ], sTop = _ref1[0], eTop = _ref1[1];
                    var _ref2 = [
                        Number((_rawBot_ = rawBot[0]) !== null && _rawBot_ !== void 0 ? _rawBot_ : 0),
                        Number((_rawBot_1 = rawBot[1]) !== null && _rawBot_1 !== void 0 ? _rawBot_1 : 0)
                    ], sBot = _ref2[0], eBot = _ref2[1];
                    var topLx = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(Math.min(sTop, eTop)) : elTop.x - Math.abs(eTop - sTop) / 2;
                    var topRx = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(Math.max(sTop, eTop)) : elTop.x + Math.abs(eTop - sTop) / 2;
                    var botLx = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(Math.min(sBot, eBot)) : elBot.x - Math.abs(eBot - sBot) / 2;
                    var botRx = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(Math.max(sBot, eBot)) : elBot.x + Math.abs(eBot - sBot) / 2;
                    var dpr = typeof window !== 'undefined' && (window.devicePixelRatio || 1) || 1;
                    var seam = (isMobile ? 0.25 : 0.35) / dpr;
                    var joinTop = elTop.y + elTop.height / 2;
                    var joinBot = elBot.y - elBot.height / 2;
                    var topY = joinTop + seam;
                    var botY = joinBot - seam;
                    // 如果该层未显式提供 ratio，则不绘制梯形
                    if (!(providedFlags === null || providedFlags === void 0 ? void 0 : providedFlags[i + 1])) {
                        continue;
                    }
                    var ratioText = (_ref = providedRatioText === null || providedRatioText === void 0 ? void 0 : providedRatioText[i + 1]) !== null && _ref !== void 0 ? _ref : '0%';
                    // 梯形边与上下柱完全对齐
                    var topL = Math.min(topLx, topRx);
                    var topR = Math.max(topLx, topRx);
                    var botL = Math.min(botLx, botRx);
                    var botR = Math.max(botLx, botRx);
                    // 绘制梯形
                    ctx.save();
                    ctx.beginPath();
                    ctx.moveTo(topL, topY);
                    ctx.lineTo(topR, topY);
                    ctx.lineTo(botR, botY);
                    ctx.lineTo(botL, botY);
                    ctx.closePath();
                    ctx.fillStyle = '#F1F2F4';
                    ctx.fill();
                    // 文本（展示该比率）
                    var midY = (topY + botY) / 2;
                    var cx = centerX !== null && centerX !== void 0 ? centerX : (Math.min(topL, botL) + Math.max(topR, botR)) / 2;
                    ctx.fillStyle = '#626F86';
                    ctx.font = "".concat(isMobile ? 10 : 12, "px sans-serif");
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText(String(ratioText), cx, midY);
                    ctx.restore();
                }
            }
        };
    }, [
        isMobile,
        showTrapezoid,
        JSON.stringify(filteredData.map(function(d) {
            return d === null || d === void 0 ? void 0 : d.ratio;
        }))
    ]);
    // 右侧阶段文本标签（跟随每个柱，显示 stage 名称）
    var rightLabelPlugin = useMemo(function() {
        return {
            id: 'funnelRightLabels',
            afterDatasetsDraw: function afterDatasetsDraw(chart) {
                var _Math;
                var _data_datasets_, _data_datasets;
                var ctx = chart.ctx, data = chart.data, scales = chart.scales;
                var meta = chart.getDatasetMeta(0);
                if (!meta) return;
                var xScale = scales === null || scales === void 0 ? void 0 : scales.x;
                var labels = (data === null || data === void 0 ? void 0 : data.labels) || [];
                ctx.save();
                ctx.fillStyle = axisTextColor;
                ctx.font = "".concat(isMobile ? 10 : 12, "px sans-serif");
                ctx.textAlign = 'left';
                ctx.textBaseline = 'middle';
                var ds = (data === null || data === void 0 ? void 0 : (_data_datasets = data.datasets) === null || _data_datasets === void 0 ? void 0 : (_data_datasets_ = _data_datasets[0]) === null || _data_datasets_ === void 0 ? void 0 : _data_datasets_.data) || [];
                // 计算所有条末端的像素坐标，找最大值作为对齐基准
                var ends = meta.data.map(function(el, i) {
                    var _raw_;
                    var raw = ds === null || ds === void 0 ? void 0 : ds[i];
                    if (!raw || !Array.isArray(raw)) return el.x;
                    var end = Number((_raw_ = raw[1]) !== null && _raw_ !== void 0 ? _raw_ : 0);
                    return (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(end) : el.x + Math.max(0, el.width / 2);
                });
                var maxEnd = (_Math = Math).max.apply(_Math, _to_consumable_array(ends));
                var padding = 12;
                meta.data.forEach(function(el, i) {
                    var _ref, _raw_, _raw_1, _ref1;
                    var raw = ds === null || ds === void 0 ? void 0 : ds[i];
                    if (!raw || !Array.isArray(raw)) return;
                    var y = el.y;
                    var label = (_ref = labels === null || labels === void 0 ? void 0 : labels[i]) !== null && _ref !== void 0 ? _ref : '';
                    ctx.fillText(label, maxEnd + padding, y);
                    // 在柱体中心绘制数值文本（白色）- 使用原始值
                    var start = Number((_raw_ = raw[0]) !== null && _raw_ !== void 0 ? _raw_ : 0);
                    var end = Number((_raw_1 = raw[1]) !== null && _raw_1 !== void 0 ? _raw_1 : 0);
                    var mid = (start + end) / 2;
                    var originalValue = (_ref1 = originalValues === null || originalValues === void 0 ? void 0 : originalValues[i]) !== null && _ref1 !== void 0 ? _ref1 : 0;
                    var cx = (xScale === null || xScale === void 0 ? void 0 : xScale.getPixelForValue) ? xScale.getPixelForValue(mid) : el.x;
                    ctx.save();
                    ctx.fillStyle = '#fff';
                    ctx.textAlign = 'center';
                    ctx.fillText(String(Math.round(originalValue)), cx, y);
                    ctx.restore();
                });
                ctx.restore();
            }
        };
    }, [
        isMobile,
        axisTextColor,
        originalValues
    ]);
    var containerClassName = useMemo(function() {
        if (isMobile) return 'w-full';
        if (typeof width === 'number') return '';
        if (typeof width === 'string' && width === '100%') return 'w-full';
        return '';
    }, [
        isMobile,
        width
    ]);
    var containerStyle = useMemo(function() {
        if (isMobile) return undefined;
        if (typeof width === 'number') return {
            width: width
        };
        if (typeof width === 'string' && width !== '100%') return {
            width: width
        };
        return undefined;
    }, [
        isMobile,
        width
    ]);
    var classNamesObj = classNamesProp;
    return wrapSSR(/*#__PURE__*/ React.createElement(ChartContainer, {
        baseClassName: baseClassName,
        className: classNames(classNamesObj === null || classNamesObj === void 0 ? void 0 : classNamesObj.root, className, containerClassName),
        theme: theme,
        isMobile: isMobile,
        variant: props.variant,
        style: _object_spread({}, containerStyle, props.style, (_props_styles = props.styles) === null || _props_styles === void 0 ? void 0 : _props_styles.root)
    }, /*#__PURE__*/ React.createElement(ChartToolBar, {
        title: title,
        theme: theme,
        onDownload: handleDownload,
        dataTime: dataTime,
        extra: toolbarExtra,
        loading: loading,
        className: classNames(classNamesObj === null || classNamesObj === void 0 ? void 0 : classNamesObj.toolbar),
        style: (_props_styles1 = props.styles) === null || _props_styles1 === void 0 ? void 0 : _props_styles1.toolbar,
        filter: renderFilterInToolbar && filterOptions && filterOptions.length > 1 ? /*#__PURE__*/ React.createElement(ChartFilter, _object_spread_props(_object_spread({
            filterOptions: filterOptions,
            selectedFilter: selectedFilter,
            onFilterChange: setSelectedFilter
        }, customOptions && {
            customOptions: customOptions,
            selectedCustomSelection: selectedFilterLabel,
            onSelectionChange: setSelectedFilterLabel
        }), {
            theme: theme,
            variant: "compact"
        })) : undefined
    }), !renderFilterInToolbar && filterOptions && filterOptions.length > 1 && /*#__PURE__*/ React.createElement(ChartFilter, _object_spread_props(_object_spread({
        filterOptions: filterOptions,
        selectedFilter: selectedFilter,
        onFilterChange: setSelectedFilter
    }, customOptions && {
        customOptions: customOptions,
        selectedCustomSelection: selectedFilterLabel,
        onSelectionChange: setSelectedFilterLabel
    }), {
        theme: theme
    })), statistics && /*#__PURE__*/ React.createElement("div", {
        className: classNames(classNamesObj === null || classNamesObj === void 0 ? void 0 : classNamesObj.statisticContainer, "".concat(baseClassName, "-statistic-container")),
        style: (_props_styles2 = props.styles) === null || _props_styles2 === void 0 ? void 0 : _props_styles2.statisticContainer
    }, statistics.map(function(config, index) {
        return /*#__PURE__*/ React.createElement(ChartStatistic, _object_spread_props(_object_spread({
            key: index
        }, config), {
            theme: theme
        }));
    })), /*#__PURE__*/ React.createElement("div", {
        className: classNames(classNamesObj === null || classNamesObj === void 0 ? void 0 : classNamesObj.wrapper, "".concat(baseClassName, "-wrapper")),
        style: _object_spread({
            height: finalHeight
        }, (_props_styles3 = props.styles) === null || _props_styles3 === void 0 ? void 0 : _props_styles3.wrapper)
    }, /*#__PURE__*/ React.createElement(Bar, {
        key: "funnel-".concat(pluginToggleKey),
        ref: chartRef,
        data: processedData,
        options: options,
        plugins: [
            trapezoidPlugin,
            rightLabelPlugin
        ]
    }))));
};
export default FunnelChart;
