import { isNullish, uniqueBy } from "remeda";
import { array, ecdf, isArray } from "@visactor/vutils";
import { defaultRegressionLineColor, defaultRegressionLineLabelX, defaultRegressionLineLabelY } from "./common.js";
const ecdfRegressionLine = (spec, context)=>{
    const result = {
        ...spec
    };
    const { advancedVSeed, vseed } = context;
    const { chartType, encoding = {}, dimensions = [], regressionLine } = advancedVSeed;
    const { dataset } = vseed;
    const lineTheme = advancedVSeed.config[chartType]?.regressionLine;
    if (!regressionLine || !regressionLine.ecdfRegressionLine) return result;
    const rowColumnFields = uniqueBy(dimensions.filter((dim)=>'row' === dim.encoding || 'column' === dim.encoding), (item)=>item.id);
    const lineList = array(regressionLine.ecdfRegressionLine).filter((ecdfLine)=>false !== ecdfLine.enable);
    if (!result.extensionMark) result.extensionMark = [];
    lineList.forEach((line, lineIndex)=>{
        if (false === line.enable) return;
        const theme = lineTheme?.ecdfRegressionLine ?? {};
        const { color, lineWidth, lineDash, text, textColor, textFontSize, textFontWeight } = line;
        const childrenMarks = [];
        result.extensionMark.push({
            type: 'group',
            interactive: false,
            zIndex: 500,
            name: `ecdfRegressionLine-${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 = ecdf(simpleData);
                        const N = Math.max(3, Math.floor(simpleData.length / 4));
                        const lineData = res.evaluateGrid(N);
                        const yRange = scaleY.range();
                        const y0 = yRange[0];
                        const y1 = yRange[yRange.length - 1];
                        const scaleR = (e)=>y0 + (y1 - y0) * e;
                        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: ()=>`ecdfRegressionLine-label-${lineIndex}`,
            style: {
                textAlign: 'end',
                fill: textColor ?? theme.textColor,
                fontSize: textFontSize ?? theme.textFontSize,
                fontWeight: textFontWeight ?? theme.textFontWeight,
                text: text,
                x: defaultRegressionLineLabelX,
                y: defaultRegressionLineLabelY
            }
        });
    });
    const leftAxis = result.axes?.find((v)=>'left' === v.orient);
    if (leftAxis && lineList.length) result.axes?.push({
        visible: true,
        orient: 'right',
        type: 'linear',
        base: 10,
        min: 0,
        max: 1,
        domainLine: {
            ...leftAxis.domainLine
        },
        grid: {
            visible: false
        },
        tick: {
            ...leftAxis.tick
        },
        title: {
            ...leftAxis.title,
            visible: false
        },
        label: {
            ...leftAxis.label,
            visible: true,
            formatMethod: (v)=>{
                const text = isArray(v) ? v[0] : v;
                return `${(100 * text).toFixed(1)}%`;
            }
        }
    });
    return result;
};
export { ecdfRegressionLine };

//# sourceMappingURL=ecdfRegressionLine.js.map