import ChartColoursHelper from './ChartColours.js';
import ChartLabelsHelper from './ChartLabels.js';
import chartConfig from './chart-config.js';
import DatasetHelper from '../../../utils/Dashboards/VisualisationDatasetHelper.js';
import { mapUnitToSymbol } from '../../../utils/Dashboards/VisualisationUnitHelper.js';

class Chart {
    labels = [];
    datasets = [];
    unit;
    responseData = [];
    backgroundColor = [];
    borderWidth = [0, 0];
    borderColor = [];
    hexColours = [];
    config = chartConfig;
    xAxisColumn;
    yAxisColumn;
    groupedData = [];
    chartColoursHelper;
    chartLabelsHelper;
    withData = (responseData) => {
        this.responseData = responseData;
        this.initHelpers();
        return this;
    };
    initUnit = (measures) => {
        this.unit = measures.find((m) => m.unit)?.unit;
    };
    initHelpers = () => {
        this.chartColoursHelper = new ChartColoursHelper();
        this.chartLabelsHelper = new ChartLabelsHelper();
    };
    // -----------------------------------------------------------------------------
    //  Datasets
    // ----------------------------------------------------------------------------
    /**
     * Creates chart.js datasets where:
     * - where each row is a dataset
     * - each column name is an x axis label
     *
     * @param {ChartMeasure[]} measures
     * @param {VisualisationDefinitionKey[]} keys
     * @memberof Chart
     */
    createDatasets = (measures, keys) => {
        this.datasets = this.responseData.map((row, datasetIndex) => {
            const label = this.chartLabelsHelper.getDatasetLabel(keys, row);
            const data = this.createDatasetValues(measures, row);
            const total = data.reduce((acc, val) => acc + val, 0);
            return {
                label,
                data,
                total,
                ...this.setStyles(datasetIndex),
            };
        });
        this.labels = this.chartLabelsHelper.getLabels(measures);
    };
    /**
     * Creates chart.js datasets where:
     * - ecah column is a dataset
     * - each value in a column is an x axis label
     *
     * @param {ChartMeasure[]} measures
     * @param {VisualisationDefinitionKey[]} keys
     * @memberof Chart
     */
    createListDatasets = (measures, keys) => {
        this.xAxisColumn = measures.find((col) => col.axis === 'x');
        this.yAxisColumn = measures.find((col) => col.axis === 'y');
        const yId = this.yAxisColumn?.id || '';
        const xId = this.xAxisColumn?.id || '';
        const keyIds = keys.map((key) => key.id);
        this.groupedData = keyIds.length ? DatasetHelper.groupRowsBy(this.responseData, keyIds) : [this.responseData];
        this.labels = this.chartLabelsHelper.getListLabels(this.groupedData, xId);
        this.datasets = this.groupedData.map((groupData, groupIndex) => {
            const data = Array(this.labels.length);
            groupData.forEach((row) => {
                const labelField = row[xId];
                const valueField = row[yId];
                const raw = valueField && valueField.raw ? Number(valueField.raw) : 0;
                const dataIndex = this.labels.findIndex((l) => l === labelField.raw);
                if (dataIndex !== -1) {
                    data[dataIndex] = Number(raw);
                }
            });
            const label = this.chartLabelsHelper.getDatasetLabel(keys, groupData[0]);
            return {
                label,
                data,
                total: data.reduce((acc, val) => acc + val, 0),
                ...this.setStyles(groupIndex),
            };
        });
        const unitSymbol = mapUnitToSymbol(this.yAxisColumn?.unit);
        this.labels = this.chartLabelsHelper.getListLabels(this.groupedData, xId, unitSymbol);
    };
    createDatasetValues = (measures, row) => {
        return measures.map((column) => {
            const rowId = column.id;
            return row[rowId] && row[rowId].raw ? Number(row[rowId].raw) : 0;
        });
    };
    // -----------------------------------------------------------------------------
    //  Styles
    // ----------------------------------------------------------------------------
    setStyles = (datasetIndex) => {
        return this.chartColoursHelper.setColourStyles(datasetIndex);
    };
    // -----------------------------------------------------------------------------
    //  Scales
    // ----------------------------------------------------------------------------
    setScales = (args) => {
        const labelText = args?.label || 'Total';
        const unitSymbol = mapUnitToSymbol(this.unit);
        const text = unitSymbol ? `${labelText} (${unitSymbol})` : labelText;
        const title = {
            display: true,
            text,
        };
        const scales = {
            x: {
                ...(args?.horizontal && { title }),
            },
            y: {
                ...(!args?.horizontal && { title }),
            },
        };
        this.config = {
            ...this.config,
            scales,
        };
    };
}

export { Chart, Chart as default };
//# sourceMappingURL=Chart.js.map
