import { hasOptionalKeys, filterRowsByKeys } from './VisualisationOptionalKeysHelper.js';

/**
 * Creates the dataset for a single visualisation
 * - given the visualisation definition will extract the relevant
 * - rows from the master dataset to produce a visualisation dataset
 *
 * @param {components['schemas']['DashboardVisualisationDefinition']} visDefinition
 * @param {DashboardDataResponse[]} dashboardData
 * @return {DashboardDataResponse[]} the visualisation dataset
 */
const getDatasetRows = (visDefinition, dashboardData) => {
    const { measures, filters, expectNulls } = visDefinition.columns;
    const { keys } = visDefinition.columns;
    const displayColumnsIds = measures.map((col) => col.id);
    const keyColumnsIds = keys?.map((col) => col.id) || [];
    let filterColIds = filters?.map((col) => col.id) || [];
    filterColIds = [...new Set(filterColIds)];
    const hasOptionalKeys$1 = hasOptionalKeys(keys || []);
    if (dashboardData.length && dashboardData[0]['ts'])
        keyColumnsIds.unshift('ts');
    const filtered = dashboardData.filter((datasetRow) => {
        const validRow = [];
        Object.keys(datasetRow).forEach((fieldId) => {
            const value = datasetRow[fieldId].raw;
            // All rows are valid until proven otherwise
            let valid = true;
            // 1. check if the column value is equal to a defined column value
            if (filterColIds.includes(fieldId) && filters) {
                const filterValues = filters ? filters.filter((f) => f.id === fieldId).map((f) => f.equals) : [];
                const validFilters = [];
                filterValues.forEach((filterValue) => {
                    if (filterValue === null) {
                        validFilters.push(value === '' || value === undefined || value === null);
                    }
                    else {
                        validFilters.push(filterValue === value);
                    }
                });
                valid = validFilters.some(Boolean);
                // 3. check keys exist in the defined columns
            }
            else if (keyColumnsIds.includes(fieldId) && hasOptionalKeys$1) {
                valid = true;
                // 3. check keys exist in the defined columns
            }
            else if (keyColumnsIds.includes(fieldId) && !hasOptionalKeys$1) {
                valid = value !== '' && value !== undefined && value !== null;
                // 2. check values exist in the defined columns
            }
            else if (displayColumnsIds.includes(fieldId)) {
                valid = value !== '' && value !== undefined && value !== null;
                // 3. check that all remaining columns are null.
            }
            else if (expectNulls) {
                valid = value === '' || value === undefined || value === null;
            }
            validRow.push(valid);
        });
        return validRow.every((val) => val);
    });
    if (hasOptionalKeys$1) {
        return filterRowsByKeys(filtered, keys || []);
    }
    return filtered;
};
const getLastestDataset = (dashboardData) => {
    const latestTimestamp = dashboardData[dashboardData.length - 1]?.['ts']?.raw;
    if (latestTimestamp) {
        return dashboardData.filter((data) => data['ts'].raw === latestTimestamp);
    }
    return dashboardData;
};
const getEarliestDataset = (dashboardData) => {
    const latestTimestamp = dashboardData[0]?.['ts']?.raw;
    if (latestTimestamp) {
        return dashboardData.filter((data) => data['ts'].raw === latestTimestamp);
    }
    return dashboardData;
};
const groupRowsByTimestamp = (dashboardData) => {
    const uniqueTimestamps = [...new Set(dashboardData.map((item) => item['ts'].raw))];
    return uniqueTimestamps.map((ts) => {
        return dashboardData.filter((d) => d['ts'].raw === ts);
    });
};
const groupRowsByKey = (dashboardData, key) => {
    const uniqueKeyValues = [...new Set(dashboardData.map((item) => item[key].raw))];
    return uniqueKeyValues.map((keyValue) => {
        return dashboardData.filter((d) => d[key].raw === keyValue);
    });
};
const groupRowsBy = (dashboardData, groupIds) => {
    const grouped = dashboardData.reduce((acc, row) => {
        // Create a unique composite key from the grouping fields
        const key = groupIds.map((id) => row[id]?.raw ?? '').join('|');
        // Build or append to the group
        acc[key] = acc[key] ? [...acc[key], row] : [row];
        return acc;
    }, {});
    // Return the groups as an array of arrays
    return Object.values(grouped);
};
const getGroupKey = (rawData, keys) => {
    if (!keys || !keys.length || !rawData.length) {
        return undefined;
    }
    const data = rawData[0];
    let index = keys.length - 1;
    let keyFound = false;
    while (!keyFound) {
        const k = `${keys[index]?.id}`;
        if (k && index !== -1 && (!data[k] || !data[k].raw || data[k].raw === '' || data[k].raw === null)) {
            index -= 1;
        }
        else {
            keyFound = true;
        }
    }
    return index !== -1 ? keys[index] : undefined;
};
const filterRowsByDisplayColumns = (listDefinition, dashboardData, includeKeys = false) => {
    const { keys: keyCols, measures } = listDefinition.columns;
    const keys = keyCols || [];
    let displayColumns = [...measures];
    if (includeKeys) {
        displayColumns = [...keys, ...measures];
    }
    const displayColumnsIds = displayColumns.map((col) => col.id);
    return dashboardData.map((datasetRow) => {
        return Object.keys(datasetRow)
            .filter((key) => displayColumnsIds.includes(key))
            .reduce((acc, key) => {
            acc[key] = datasetRow[key];
            return acc;
        }, {});
    });
};
var DatasetHelper = {
    getDatasetRows,
    getLastestDataset,
    getEarliestDataset,
    filterRowsByDisplayColumns,
    groupRowsByTimestamp,
    groupRowsByKey,
    groupRowsBy,
    getGroupKey,
};

export { DatasetHelper as default, filterRowsByDisplayColumns, getDatasetRows, getEarliestDataset, getGroupKey, getLastestDataset, groupRowsBy, groupRowsByKey, groupRowsByTimestamp };
//# sourceMappingURL=VisualisationDatasetHelper.js.map
