import { ReportType } from '../../../../../types/UserReports.js';
import DefinitionUtils, { getDashboardFields } from '../../../../../utils/definitionUtils.js';
import FiltersUtils from '../../../../../components/_filters/utils.js';
import ReportActionsUtils from '../../../../../components/_reports/report-heading/report-actions/utils.js';
import { ReportQuery } from '../../../../../types/ReportQuery.js';
import localsHelper from '../../../../../utils/localsHelper.js';
import { FilterType } from '../../../../../components/_filters/filter-input/enum.js';
import { validateDashboardVisualisations } from '../../../../../components/_dashboards/dashboard-visualisation/utils.js';
import { createDashboardSections } from '../../../../../components/_dashboards/dashboard-section/utils.js';
import DashboardSchema from './validate.js';
import { setUpBookmark } from '../../../../../components/bookmark/utils.js';
import { buildAppliedFilters } from '../../../../../components/_filters/filters-applied/utils.js';
import { extractFiltersFromQuery } from '../../../../../utils/queryMappers.js';
import { updateLastViewedAsync } from '../../utils.js';
import { ErrorHandler } from '../../../../../utils/ErrorHandler/ErrorHandler.js';

const setDashboardActions = (dashboardDefinition, reportDefinition, requestData) => {
    const reportName = reportDefinition.name;
    const { name } = dashboardDefinition;
    const actionsUrl = requestData?.url?.request?.fullUrl;
    const executionId = requestData?.executionId;
    let actions = {};
    if (actionsUrl) {
        actions = {
            share: {
                reportName,
                name,
                url: actionsUrl,
            },
            copy: {
                url: actionsUrl,
            },
        };
        if (executionId) {
            actions = {
                ...actions,
                refresh: {
                    url: actionsUrl,
                    executionId,
                },
            };
        }
    }
    return ReportActionsUtils.getActions(actions);
};
const getDefinitionData = async ({ req, res, services, queryData, }) => {
    const { token } = localsHelper.getValues(res);
    const { reportId, id, tableId } = req.params;
    const dataProductDefinitionsPath = req.query['dataProductDefinitionsPath'];
    // Dashboard Definition,
    const dashboardDefinition = await services.dashboardService.getDefinition(token, reportId, id, dataProductDefinitionsPath, queryData);
    // Validate definition
    DashboardSchema.DashboardSchema.parse(dashboardDefinition);
    // validate visualisations
    await validateDashboardVisualisations(dashboardDefinition);
    // Report summary data
    const reportDefinition = await DefinitionUtils.getReportSummary(reportId, services.reportingService, token, dataProductDefinitionsPath);
    // Get the filters
    const fields = getDashboardFields(dashboardDefinition);
    const filters = await FiltersUtils.getInteractiveFilters({
        fields,
        req,
    });
    // Get the applied Filters
    const appliedFilters = buildAppliedFilters(req, { reportId, id, tableId }, fields);
    // Create the query
    const query = new ReportQuery({
        fields,
        queryParams: extractFiltersFromQuery(req.query),
        definitionsPath: dataProductDefinitionsPath,
        reportType: ReportType.DASHBOARD,
    }).toRecordWithFilterPrefix(true);
    return {
        query,
        filters,
        dashboardDefinition,
        reportDefinition,
        appliedFilters,
        fields,
    };
};
const updateStore = async (services, tableId, userId, sections, req, fields) => {
    const { requestedReportService } = services;
    const dashboardRequestData = await requestedReportService.getReportByTableId(tableId, userId);
    // Add to recently viewed
    if (sections && sections.length && dashboardRequestData) {
        await updateLastViewedAsync(req, services, dashboardRequestData, userId, fields);
    }
    return dashboardRequestData;
};
const getPartialDate = (filters) => {
    let partialDate;
    const granularDateRangeFilter = (filters.find((f) => f.type === FilterType.granularDateRange.toLowerCase()));
    if (granularDateRangeFilter) {
        partialDate = granularDateRangeFilter.value.partialDate;
    }
    return partialDate;
};
const renderAsyncDashboard = async ({ req, res, services }) => {
    const { token, csrfToken, dprUser } = localsHelper.getValues(res);
    const { reportId, id, tableId } = req.params;
    const { bookmarkService, requestedReportService } = services;
    const { id: userId } = dprUser;
    let requestData = await requestedReportService.getReportByTableId(tableId, userId);
    const queryData = requestData?.query?.data;
    // Get the definition Data
    const { query, filters, reportDefinition, dashboardDefinition, appliedFilters, fields } = await getDefinitionData({
        req,
        res,
        services,
        queryData,
    });
    // Get the dashboard data and check if expired
    const { dashboardData, expired } = await getDashboardData(token, reportId, id, tableId, query, services);
    const partialDate = getPartialDate(filters);
    const bookmarkConfig = setUpBookmark(res, req, bookmarkService);
    // Get the dashboard parts
    const dashboardFeatureFlags = res.app.locals['featureFlags'].flags;
    const sections = createDashboardSections(dashboardDefinition, dashboardData, query, dashboardFeatureFlags, partialDate);
    // Update the store
    if (requestedReportService) {
        requestData = await updateStore(services, tableId, dprUser.id, sections, req, fields);
    }
    return {
        dashboardData: {
            token,
            id,
            reportId,
            name: dashboardDefinition.name,
            description: dashboardDefinition.description,
            reportName: reportDefinition.name,
            csrfToken,
            sections,
            filters,
            type: ReportType.DASHBOARD,
            actions: setDashboardActions(dashboardDefinition, reportDefinition, requestData),
            bookmarkConfig,
            appliedFilters,
        },
        expired,
    };
};
/**
 * Gets the data for a dashboard
 *
 * @param {string} token
 * @param {string} reportId
 * @param {string} id
 * @param {string} tableId
 * @param {(Record<string, string | string[]>)} query
 * @param {Services} services
 * @return {*}
 */
const getDashboardData = async (token, reportId, id, tableId, query, services) => {
    let dashboardData = [];
    let expired = false;
    try {
        const dashboardResultData = await services.dashboardService.getAsyncDashboard(token, id, reportId, tableId, query);
        dashboardData = Array.isArray(dashboardResultData) ? dashboardResultData.flat().filter(Boolean) : [];
    }
    catch (error) {
        const dprError = new ErrorHandler(error).formatError();
        if (dprError.status === 404) {
            expired = true;
        }
        else {
            throw error;
        }
    }
    return {
        dashboardData,
        expired,
    };
};
var DashboardUtils = {
    renderAsyncDashboard,
    getDefinitionData,
    setDashboardActions,
};

export { DashboardUtils as default, renderAsyncDashboard };
//# sourceMappingURL=utils.js.map
