"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.aggregationFns = void 0;
const utils_1 = require("./utils");
const sum = (columnId, _leafRows, childRows) => {
    return childRows.reduce((acc, next) => {
        const nextValue = next.getValue(columnId);
        return acc + (typeof nextValue === 'number' ? nextValue : 0);
    }, 0);
};
const min = (columnId, _leafRows, childRows) => {
    let minVal;
    childRows.forEach((row) => {
        const value = row.getValue(columnId);
        const isValid = value != null && !Number.isNaN(value);
        if (isValid && (minVal === undefined || minVal > value)) {
            minVal = value;
        }
    });
    return minVal;
};
const max = (columnId, _leafRows, childRows) => {
    let maxVal;
    childRows.forEach((row) => {
        const value = row.getValue(columnId);
        const isValid = value != null && !Number.isNaN(value);
        if (isValid && (maxVal === undefined || maxVal < value)) {
            maxVal = value;
        }
    });
    return maxVal;
};
const extent = (columnId, _leafRows, childRows) => {
    let minVal;
    let maxVal;
    childRows.forEach((row) => {
        const value = row.getValue(columnId);
        if (value != null && !Number.isNaN(value)) {
            if (minVal === undefined) {
                minVal = value;
                maxVal = value;
            }
            else {
                if (minVal > value)
                    minVal = value;
                if (maxVal < value)
                    maxVal = value;
            }
        }
    });
    return [minVal, maxVal];
};
const mean = (columnId, leafRows) => {
    let count = 0;
    let total = 0;
    leafRows.forEach((row) => {
        const raw = row.getValue(columnId);
        const value = raw != null ? +raw : NaN;
        if (!Number.isNaN(value)) {
            count += 1;
            total += value;
        }
    });
    if (count)
        return total / count;
};
const median = (columnId, leafRows) => {
    if (!leafRows.length) {
        return;
    }
    const values = leafRows.map((row) => row.getValue(columnId));
    if (!(0, utils_1.isNumberArray)(values)) {
        return;
    }
    if (values.length === 1) {
        return values[0];
    }
    const mid = Math.floor(values.length / 2);
    const nums = values.sort((a, b) => a - b);
    return values.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};
const unique = (columnId, leafRows) => {
    return Array.from(new Set(leafRows.map((d) => d.getValue(columnId))).values());
};
const uniqueCount = (columnId, leafRows) => {
    return new Set(leafRows.map((d) => d.getValue(columnId))).size;
};
const count = (_columnId, leafRows) => {
    return leafRows.length;
};
exports.aggregationFns = {
    sum,
    min,
    max,
    extent,
    mean,
    median,
    unique,
    uniqueCount,
    count,
};
