import { normalizeQueryStringArray } from '../../../utils/urlHelper.js';
import { FilterType } from '../../../components/_filters/filter-input/enum.js';
import localsHelper from '../../../utils/localsHelper.js';
import DefinitionUtils from '../../../utils/definitionUtils.js';
import { DateMapper } from '../../../utils/DateMapper/DateMapper.js';
import ColumnsUtils from '../../../components/_reports/report-heading/report-columns/report-columns-form/utils.js';

const applyReportInteractiveQuery = async (req, res, services, applyType) => {
    const { reportId, id } = req.params;
    const { token, definitionsPath } = localsHelper.getValues(res);
    // Get the definition
    const definition = await services.reportingService.getDefinition(token, reportId, id, definitionsPath);
    const fields = definition.variant.specification?.fields || [];
    return applyInteractiveQuery(req, res, services, applyType, fields);
};
const applyDashboardInteractiveQuery = async (req, res, services, applyType) => {
    const { reportId, id } = req.params;
    const { token, definitionsPath } = localsHelper.getValues(res);
    // Get the definition
    const definition = await services.dashboardService.getDefinition(token, reportId, id, definitionsPath);
    const fields = definition.filterFields || [];
    return applyInteractiveQuery(req, res, services, applyType, fields);
};
const applyInteractiveQuery = async (req, res, services, applyType, fields) => {
    const { tableId, id } = req.params;
    const { dprUser } = localsHelper.getValues(res);
    // get the report state
    let reportStateData;
    if (tableId) {
        // means its an async report
        reportStateData = await services.recentlyViewedService?.getReportByTableId(tableId, dprUser.id);
    }
    else {
        // its a sync report and can be indentified by ID as will always only be 1
        reportStateData = await services.recentlyViewedService?.getReportById(id, dprUser.id);
    }
    // Get the stored interactive query data
    const interactiveQueryData = reportStateData?.interactiveQuery?.data;
    const preventDefault = interactiveQueryData?.['preventDefault'];
    const pageSize = interactiveQueryData?.['pageSize'];
    const selectedPage = applyType === 'columns' ? interactiveQueryData?.['selectedPage'] : 1;
    const sortColumn = interactiveQueryData?.['sortColumn'];
    const sortedAsc = interactiveQueryData?.['sortedAsc'];
    // Create merged form data
    let formData = {
        ...(preventDefault && { preventDefault }),
        ...(selectedPage && { selectedPage }),
        ...(pageSize && { pageSize }),
        ...(sortColumn && { sortColumn }),
        ...(sortedAsc && { sortedAsc }),
        ...req.body,
    };
    if (applyType === 'columns') {
        const { columns } = req.body;
        const mandatoryCols = ColumnsUtils.mandatoryColumns(fields);
        let bodyColumns = [];
        if (columns) {
            bodyColumns = Array.isArray(columns) ? columns : [columns];
        }
        const columnsData = [...mandatoryCols, ...bodyColumns];
        // Ensure filters are set correctly from the saved state.
        let filters = {};
        if (interactiveQueryData) {
            filters = Object.keys(interactiveQueryData)
                .filter((key) => key.includes('filters.'))
                .reduce((acc, key) => ({ ...acc, [key]: interactiveQueryData[key] }), {});
        }
        formData = { ...formData, columns: columnsData, ...filters };
    }
    else {
        const normalizedColumns = normalizeQueryStringArray(interactiveQueryData?.['columns']) || [];
        formData = { ...formData, columns: normalizedColumns };
    }
    // Create query string
    const filtersString = createQueryParamsFromFormData({
        formData,
        fields,
    });
    // Redirect back to report
    res.redirect(`${req.baseUrl}?${filtersString}`);
};
const createQueryParamsFromFormData = ({ formData, fields, }) => {
    // create the query string
    const params = new URLSearchParams();
    Object.keys(formData).forEach((key) => {
        const value = formData[key];
        if (value && key !== '_csrf') {
            const fieldId = key.split('.')[1]; // filters are prefixed with 'filters.'
            if (fieldId) {
                const filter = DefinitionUtils.getFilter(fields, fieldId);
                if (filter) {
                    const { type: filterType } = filter;
                    switch (filterType.toLocaleLowerCase()) {
                        // DATE RANGE TYPES
                        case FilterType.date.toLocaleLowerCase():
                        case FilterType.dateRange.toLocaleLowerCase():
                        case FilterType.granularDateRange.toLocaleLowerCase():
                            {
                                let dateValue = value;
                                const dateMapper = new DateMapper();
                                const currentDateFormat = dateMapper.getDateType(dateValue);
                                if (currentDateFormat !== 'none') {
                                    dateValue = dateMapper.toDateString(dateValue, 'iso') || '';
                                }
                                if (dateValue) {
                                    params.append(key, dateValue);
                                }
                            }
                            break;
                        // MULTIVALUE TYPES: string[] || string if only one value selected
                        case FilterType.multiselect.toLocaleLowerCase():
                            if (Array.isArray(value)) {
                                const multiselectValue = value;
                                multiselectValue.forEach((v) => {
                                    params.append(key, v);
                                });
                            }
                            else {
                                params.append(key, value);
                            }
                            break;
                        // OTHER TYPES - always a string
                        default:
                            params.append(key, value);
                            break;
                    }
                }
            }
            else if (Array.isArray(value)) {
                value.forEach((v) => {
                    params.append(key, v);
                });
            }
            else {
                params.append(key, value);
            }
        }
    });
    return params.toString();
};
var ViewReportUtils = {
    applyDashboardInteractiveQuery,
    applyReportInteractiveQuery,
};

export { applyDashboardInteractiveQuery, applyReportInteractiveQuery, ViewReportUtils as default };
//# sourceMappingURL=utils.js.map
