import { isNullish, uniqueBy } from "remeda";
import { array, kde } from "@visactor/vutils";
import { BinEndMeasureId, BinStartMeasureId } from "../../../../../dataReshape/index.js";
import { defaultRegressionLineColor, defaultRegressionLineLabelX, defaultRegressionLineLabelY } from "./common.js";
const kdeRegressionLine = (spec, context)=>{
    const result = {
        ...spec
    };
    const { advancedVSeed, vseed } = context;
    const { chartType, encoding = {}, dimensions = [], regressionLine } = advancedVSeed;
    const { dataset } = vseed;
    const lineTheme = advancedVSeed.config[chartType]?.regressionLine;
    const binValueType = advancedVSeed.config[chartType]?.binValueType;
    if (!regressionLine || !regressionLine.kdeRegressionLine) return result;
    const rowColumnFields = uniqueBy(dimensions.filter((dim)=>'row' === dim.encoding || 'column' === dim.encoding), (item)=>item.id);
    const lineList = array(regressionLine.kdeRegressionLine).filter((kdeLine)=>false !== kdeLine.enable);
    if (!result.extensionMark) result.extensionMark = [];
    lineList.forEach((line, lineIndex)=>{
        if (false === line.enable) return;
        const theme = lineTheme.kdeRegressionLine ?? {};
        const { color, lineWidth, lineDash, text, textColor, textFontSize, textFontWeight } = line;
        const childrenMarks = [];
        result.extensionMark.push({
            type: 'group',
            interactive: false,
            zIndex: 500,
            name: `kdeRegressionLine-${lineIndex}`,
            dataId: spec.data?.id,
            style: {
                data: (datum, ctx)=>{
                    const vchart = ctx.vchart;
                    const chart = vchart.getChart();
                    const series = chart.getAllSeries().filter((s)=>'bar' === s.type);
                    if (series && series.length) {
                        const s = series[0];
                        const fieldX = s.fieldX?.[0];
                        const scaleY = s.getYAxisHelper().getScale?.(0);
                        const viewData = s.getViewData()?.latestData;
                        if (!dataset || !dataset.length || !viewData || !viewData.length || !scaleY) return null;
                        const simpleData = dataset.filter((entry)=>rowColumnFields.length ? rowColumnFields.every((dim)=>entry[dim.id] === viewData[0][dim.id]) : true).map((d)=>+d[encoding.value?.[0]]);
                        const res = kde(simpleData, {
                            bandwidth: Math.abs(viewData[0][BinEndMeasureId] - viewData[0][BinStartMeasureId])
                        });
                        const N = Math.max(3, Math.floor(simpleData.length / 4));
                        const lineData = res.evaluateGrid(N);
                        const scaleR = (k)=>{
                            if ('percentage' === binValueType) return scaleY.scale(k * res.bandwidth);
                            return scaleY.scale(k * simpleData.length * res.bandwidth);
                        };
                        const linePoints = lineData.map((ld)=>{
                            const d = {
                                [fieldX]: ld.x
                            };
                            return {
                                x: s.dataToPositionX(d),
                                y: scaleR(ld.y)
                            };
                        });
                        return {
                            linePoints,
                            color: color ?? s.getOption().globalScale.getScale('color')?.scale(s.getSeriesKeys()[0])
                        };
                    }
                    return null;
                }
            },
            children: childrenMarks
        });
        childrenMarks.push({
            type: 'line',
            interactive: false,
            zIndex: 500,
            dataId: spec.data?.id,
            style: {
                lineWidth: lineWidth ?? theme.lineWidth,
                lineDash: lineDash ?? theme.lineDash,
                stroke: color ?? defaultRegressionLineColor,
                points: (datum, ctx, opt)=>{
                    const parentNode = opt.mark?._product?.parent;
                    if (parentNode?.attribute?.data) return parentNode.attribute.data.linePoints;
                    return [];
                }
            }
        });
        if (!isNullish(text)) childrenMarks.push({
            type: 'text',
            interactive: false,
            zIndex: 500,
            dataId: spec.data?.id,
            dataKey: ()=>`kdeRegressionLine-label-${lineIndex}`,
            style: {
                textAlign: 'end',
                fill: textColor ?? theme.textColor,
                fontSize: textFontSize ?? theme.textFontSize,
                fontWeight: textFontWeight ?? theme.textFontWeight,
                text: text,
                x: defaultRegressionLineLabelX,
                y: defaultRegressionLineLabelY
            }
        });
    });
    return result;
};
export { kdeRegressionLine };

//# sourceMappingURL=kdeRegressionLine.js.map