"use strict";
/* eslint-disable complexity */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformSeriesMixin = void 0;
const defaults_1 = require("../defaults");
const common_1 = require("../utils/common");
class TransformSeriesMixin {
    /**
     * @internal
     * @param this Yagr instance
     * @description Transforms series data according to config
     * @returns uPlot series data
     */
    transformSeries() {
        const processingStartTime = performance.now();
        const result = [];
        const config = this.config;
        const timeline = config.timeline;
        let processing = config.processing || false;
        let series = this.config.series.map(({ data }) => data);
        if (processing && processing.interpolation) {
            series = (0, common_1.preprocess)(series, timeline, processing);
            processing = false;
        }
        const shouldMapNullValues = Boolean(processing && processing.nullValues);
        const nullValues = (processing && processing.nullValues) || {};
        /**
         * Stacks are represented as:
         * {
         *    [scale]: {
         *        [],  // stacking group idx 0 (default for all on scale),
         *        [],  // stacking group idx 1
         *    ]
         * }
         *
         * All stacked points are accumulating inside of series' scale group
         */
        const stacks = {};
        for (let sIdx = 0; sIdx < series.length; sIdx++) {
            let dataLine = [];
            const realSerieIdx = sIdx + 1;
            const serie = series[sIdx];
            const serieConfigIndex = this.options.series.length - realSerieIdx;
            const serieOptions = this.options.series[serieConfigIndex];
            const scale = serieOptions.scale || defaults_1.DEFAULT_Y_SCALE;
            const scaleConfig = this.config.scales[scale] || {};
            const isStacking = scaleConfig.stacking;
            const sGroup = serieOptions.stackGroup || 0;
            let empty = true;
            if (isStacking && !stacks[scale]) {
                this.options.focus = this.options.focus || { alpha: 1.1 };
                this.options.focus.alpha = 1.1;
                stacks[scale] = [];
            }
            if (isStacking && !stacks[scale][sGroup]) {
                stacks[scale][sGroup] = new Array(timeline.length).fill(0);
            }
            serieOptions.count = 0;
            for (let idx = 0; idx < serie.length; idx++) {
                let value = serie[idx];
                if (shouldMapNullValues && nullValues[String(value)]) {
                    value = null;
                }
                if (serieOptions.transform) {
                    serieOptions._transformed = true;
                    value = serieOptions.transform(value, series, idx);
                }
                if (scaleConfig.transform) {
                    serieOptions._transformed = true;
                    value = scaleConfig.transform(value, series, idx);
                }
                if (value === null) {
                    if (serieOptions.type === 'line' || serieOptions.type === 'dots') {
                        dataLine.push(null);
                        continue;
                    }
                    else {
                        value = isStacking ? 0 : null;
                    }
                }
                empty = false;
                if (scaleConfig.normalize) {
                    const sum = (0, common_1.getSumByIdx)(this.options.series, idx, scale);
                    value = sum && ((value !== null && value !== void 0 ? value : 0) / sum) * (scaleConfig.normalizeBase || 100);
                    serieOptions.normalizedData = serieOptions.normalizedData || [];
                    serieOptions.normalizedData[idx] = value;
                }
                if (scaleConfig.stacking) {
                    if (serieOptions.show === false || serieOptions.showInGraph === false) {
                        value = 0;
                    }
                    value = stacks[scale][sGroup][idx] += (value !== null && value !== void 0 ? value : 0);
                }
                if (scaleConfig.type === 'logarithmic' && value === 0) {
                    value = 1;
                }
                serieOptions.sum = (serieOptions.sum || 0) + (value || 0);
                const originalValue = serieOptions.$c[idx];
                if (typeof originalValue === 'number') {
                    serieOptions.count += 1;
                }
                dataLine.push(value);
            }
            serieOptions.avg = (serieOptions.sum || 0) / serieOptions.count;
            serieOptions.empty = empty;
            if (serieOptions.postProcess) {
                dataLine = serieOptions.postProcess(dataLine, sIdx, this);
            }
            result.unshift(dataLine);
        }
        result.unshift(this.config.timeline);
        this.series = result;
        this.execHooks('processed', {
            chart: this,
            meta: {
                processTime: performance.now() - processingStartTime,
            },
        });
        return this.series;
    }
}
exports.TransformSeriesMixin = TransformSeriesMixin;
