'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var parseUrl = require('parseurl');
var UserReports = require('../../../../../types/UserReports.js');
var ReportQuery = require('../../../../../types/ReportQuery.js');
var filtersTypeEnum = require('../../../../../components/_filters/filtersTypeEnum.js');
var definitionUtils = require('../../../../../utils/definitionUtils.js');
var utils$4 = require('../../../../../components/_reports/report-page/report-template/report-pagination/utils.js');
var utils$5 = require('../../../../../components/_reports/report-page/report-template/report-totals/utils.js');
var utils$3 = require('../../../../../components/_filters/utils.js');
var utils$2 = require('../../../../../components/_reports/report-heading/report-columns/report-columns-form/utils.js');
var utils$8 = require('../../../../../components/_reports/report-heading/report-actions/utils.js');
var utils$1 = require('../../../../../components/user-reports/utils.js');
var localsHelper = require('../../../../../utils/localsHelper.js');
var utils = require('../../../../../components/_reports/report-page/report-template/utils.js');
var utils$6 = require('../../../../../components/bookmark/utils.js');
var utils$7 = require('../../../download-report/utils.js');
var sessionHelper = require('../../../../../utils/sessionHelper.js');

const getData = async ({ res, req, services, token, userId, }) => {
    const { definitionsPath: definitionPath } = localsHelper.default.getValues(res);
    const { variantId, id, tableId, reportId } = (req.params);
    const reportVariantId = variantId || id;
    // Get the request data
    const requestedReportService = services.requestedReportService;
    const requestData = await requestedReportService.getReportByTableId(tableId, userId);
    const queryData = requestData?.query?.data;
    // Get the definition
    const definition = await services.reportingService.getDefinition(token, reportId, reportVariantId, definitionPath, queryData);
    const { variant } = definition;
    const { specification } = variant;
    if (!specification) {
        throw new Error('No specification found in variant definition');
    }
    // Get the columns
    const columns = utils$2.default.getColumns(specification, req);
    // initialise report query
    const reportQuery = await initReportQuery(definition, columns, res, req, services, requestData);
    // Get the reportData
    const reportData = await getReportData({ services, token, req, reportQuery });
    // Get the summary data, if applicable
    const { summaries } = definition.variant;
    const summariesData = !summaries ? [] : await getSummariesData(summaries, services, token, req, res);
    // Get the child data, if applicable
    const { childVariants } = definition.variant;
    const childData = !childVariants
        ? []
        : await getChildData(childVariants, services, token, req, res, requestData);
    return {
        definition,
        requestData,
        reportData,
        summariesData,
        childData,
        reportQuery,
        columns,
    };
};
const initReportQuery = async (definition, columns, res, req, services, requestData) => {
    const { definitionsPath } = localsHelper.default.getValues(res);
    const fields = definitionUtils.default.getFields(definition);
    const template = definitionUtils.default.getTemplate(definition);
    const filtersData = await utils$3.default.getFilters({
        fields,
        req,
        filtersType: filtersTypeEnum.FiltersType.INTERACTIVE,
        res,
        services,
    });
    // Sort
    const sortColumn = req.query?.['sortColumn'] || requestData?.sortBy?.data?.['sortColumn'];
    const sortedAsc = req.query?.['sortedAsc'] || requestData?.sortBy?.data?.['sortedAsc'];
    // Pagination
    const selectedPage = req.query?.['selectedPage'];
    const pageSize = req.query?.['pageSize'];
    // Filters
    const filtersQuery = utils$3.default.setRequestQueryFromFilterValues(filtersData.filters);
    const queryParams = {
        ...(sortColumn && { sortColumn }),
        ...(sortedAsc && { sortedAsc }),
        ...filtersQuery,
        ...(pageSize && { pageSize }),
        ...(selectedPage && { selectedPage }),
        ...(columns && { columns: columns.value }),
    };
    return new ReportQuery.ReportQuery({
        fields,
        template,
        queryParams,
        definitionsPath,
    });
};
const getReportData = async (args) => {
    const { services, token, req, reportQuery } = args;
    const { reportId, variantId, id, tableId } = (req.params);
    const reportVariantId = variantId || id;
    return services.reportingService.getAsyncReport(token, reportId, reportVariantId, tableId, reportQuery.toRecordWithFilterPrefix(true));
};
const getSummariesData = async (summaries, services, token, req, res) => {
    const { reportId, variantId, id, tableId } = (req.params);
    const { definitionsPath: dataProductDefinitionsPath } = localsHelper.default.getValues(res);
    const reportVariantId = variantId || id;
    return Promise.all(summaries.map(async (summary) => {
        const summaryReport = await services.reportingService.getAsyncSummaryReport(token, reportId, reportVariantId, tableId, summary.id, {
            dataProductDefinitionsPath,
        });
        return {
            ...summary,
            data: summaryReport,
        };
    }));
};
const getChildData = async (childVariants, services, token, req, res, requestData) => {
    const { definitionsPath: dataProductDefinitionsPath } = localsHelper.default.getValues(res);
    const { reportId } = req.params;
    const childExecutionData = requestData?.childExecutionData;
    if (!childExecutionData) {
        throw new Error('getChildData: No execution data found for child variants');
    }
    return Promise.all(childVariants.map(async (childVariant) => {
        const { specification } = childVariant;
        if (!specification) {
            throw new Error('getChildData: No specification found in child variant definition');
        }
        const query = new ReportQuery.ReportQuery({
            fields: specification?.fields || [],
            template: 'parent-child',
            queryParams: req.query,
            definitionsPath: dataProductDefinitionsPath,
        }).toRecordWithFilterPrefix(true);
        const childData = childExecutionData.find((e) => e.variantId === childVariant.id);
        if (!childData || !childData.tableId) {
            throw new Error('getChildData: No matching child execution data found');
        }
        const { tableId: childTableId } = childData;
        const childReport = await services.reportingService.getAsyncReport(token, reportId, childVariant.id, childTableId, query);
        return {
            id: childVariant.id,
            data: childReport,
        };
    }));
};
/**
 * Entry point function to render the report
 *
 * @param {AsyncReportUtilsParams} { req, res, services }
 * @return {*}
 */
const renderReport = async ({ req, res, services }) => {
    const { token, dprUser } = localsHelper.default.getValues(res);
    // Get the report data
    const { definition, requestData, reportData, childData, summariesData, reportQuery, columns } = await getData({
        req,
        res,
        services,
        token,
        userId: dprUser.id,
    });
    // Get the data table
    const dataTable = utils.default.createReportTemplateData(definition, columns, reportData, childData, summariesData, reportQuery);
    // Get the template data
    const templateData = await getTemplateData(req, res, services, definition, dataTable, columns, reportQuery, requestData);
    const renderData = {
        ...templateData,
        dataTable,
    };
    if (requestData && Object.keys(requestData).length) {
        utils$1.default.updateLastViewed({
            req,
            services,
            reportStateData: requestData,
            userId: dprUser.id,
            filters: templateData.filterData.filters,
        });
    }
    return { renderData };
};
const getTemplateData = async (req, res, services, definition, dataTable, columns, reportQuery, requestData) => {
    // get url data
    const url = parseUrl(req);
    if (!url) {
        throw new Error('Unable to set url data from request');
    }
    // get from definition
    const definitionData = extractDataFromDefinition(definition);
    const { fields, specification } = definitionData;
    // get from requestedData
    const requestedData = requestData ? extractDataFromRequest(requestData) : undefined;
    // Get the count
    const count = await getCount(definition, services, res, req, reportQuery);
    // Get the filters
    const filterData = await utils$3.default.getFilters({
        fields,
        req,
        res,
        services,
        filtersType: filtersTypeEnum.FiltersType.INTERACTIVE,
    });
    // Set the features
    const features = await setFeatures(services, res, req, columns, definitionData, requestedData);
    // Set the extra meta data
    const meta = setMetaData(res, req);
    let pagination;
    let totals;
    if (definitionData.template === 'list') {
        pagination = utils$4.default.getPaginationData(url, count, req);
        const { pageSize, currentPage, totalRows } = pagination;
        totals = utils$5.default.getTotals(pageSize, currentPage, totalRows, dataTable.rowCount);
    }
    return {
        ...(showColumns(specification) && { columns }),
        filterData,
        count,
        ...meta,
        ...features,
        ...definitionData,
        ...requestedData,
        ...(pagination && { pagination }),
        ...(totals && { totals }),
    };
};
const showColumns = (specification) => {
    const { template } = specification;
    return !['row-section', 'row-section-child', 'summary', 'summary-section'].includes(template);
};
const setMetaData = (res, req) => {
    const { csrfToken } = localsHelper.default.getValues(res);
    const { tableId, reportId, id } = req.params;
    return {
        csrfToken,
        loadType: UserReports.LoadType.ASYNC,
        type: UserReports.ReportType.REPORT,
        tableId,
        reportId,
        id,
    };
};
const setFeatures = async (services, res, req, columns, definitionData, requestData) => {
    const { tableId, reportId, id } = req.params;
    const bookmarkConfig = utils$6.setUpBookmark(res, req, services.bookmarkService);
    const downloadConfig = utils$7.setUpDownload(res, req, definitionData, columns, UserReports.LoadType.ASYNC, requestData);
    const actions = utils$8.default.setActions(definitionData, downloadConfig, requestData);
    const feedbackSubmissionFormPath = sessionHelper.getActiveJourneyValue(req, { id, reportId, tableId }, 'feedbackSubmissionFormPath');
    return {
        actions,
        downloadConfig,
        bookmarkConfig,
        feedbackFormHref: feedbackSubmissionFormPath,
    };
};
const getCount = async (definition, services, res, req, reportQuery) => {
    const { token } = localsHelper.default.getValues(res);
    const { tableId, reportId, id } = req.params;
    return !definition.variant.interactive || !definitionUtils.hasInteractiveFilters(definitionUtils.getFields(definition))
        ? services.reportingService.getAsyncCount(token, tableId)
        : services.reportingService.getAsyncInteractiveCount(token, tableId, reportId, id, reportQuery);
};
const extractDataFromDefinition = (definition) => {
    const { variant, name: reportName, description: reportDescription } = definition;
    const { classification, printable, specification, name, description } = variant;
    if (!specification) {
        throw new Error('No specification found in variant definition');
    }
    const { template, fields } = specification;
    return {
        reportName,
        name,
        description: description || reportDescription,
        classification,
        printable: Boolean(printable),
        specification,
        template,
        fields,
    };
};
const extractDataFromRequest = (requestData) => {
    const { query, url, timestamp } = requestData;
    return {
        executionId: requestData.executionId,
        requestedTimestamp: timestamp.requested ? new Date(timestamp.requested).toLocaleString() : undefined,
        querySummary: query?.summary || [],
        queryData: query?.data,
        requestUrl: url?.request,
        defaultQuery: url?.report?.default,
        dataProductDefinitionsPath: requestData.dataProductDefinitionsPath,
    };
};
var AsyncReportUtils = {
    renderReport,
    extractDataFromDefinition,
};

exports.default = AsyncReportUtils;
exports.getChildData = getChildData;
exports.getData = getData;
exports.getSummariesData = getSummariesData;
exports.renderReport = renderReport;
//# sourceMappingURL=utils.js.map
