import { buildJourneyKey } from '../utils/sessionHelper.js';
import { getRouteLocals } from '../utils/localsHelper.js';
import { setNestedPath } from '../utils/urlHelper.js';
import { LoadType } from '../types/UserReports.js';

const storeActiveReportSessionData = (services, loadType = LoadType.ASYNC) => async (req, res, next) => {
    if (!req.session) {
        return next(new Error('Session not initialized'));
    }
    if (req.method !== 'GET') {
        return next();
    }
    // --- Initialise Session Namespace -------------------------------------
    if (!req.session.activeReport) {
        req.session.activeReport = {};
    }
    const store = req.session.activeReport;
    // --- Build Key Variants & Data configurataions -------------------------
    const { baseKey, execKey, tableKey } = buildKeyVariants(req);
    const { baseData, execData, tableData } = await buildDataConfiguration(req, res, services, loadType);
    // --- Write Base Key (always updated) ----------------------------------
    store[baseKey] = {
        ...(store[baseKey] ?? {}),
        ...baseData,
    };
    // --- Write Exec Key (async loading) -----------------------------------
    if (execKey && execData) {
        store[execKey] = {
            ...(store[execKey] ?? {}),
            ...execData,
        };
    }
    // --- Write Table Key (final async state) ------------------------------
    if (tableKey && tableData) {
        store[tableKey] = {
            ...(store[tableKey] ?? {}),
            ...tableData,
        };
    }
    return next();
};
/**
 * Creates the active report data configuration
 *
 * @param {Request} req
 * @param {Response} res
 * @param {Services} services
 * @return {*}
 */
const buildDataConfiguration = async (req, res, services, loadType) => {
    // Normalise Express params (string | string[])
    const asString = (v) => (Array.isArray(v) ? v[0] : v);
    const p = req.params;
    const id = asString(p['id']);
    const reportId = asString(p['reportId']);
    const executionId = asString(p['executionId']);
    const tableId = asString(p['tableId']);
    // --- Fetch Dynamic Values ---------------------------------------------
    const reportIsBookmarked = await setUpBookmark(req, res, services.bookmarkService);
    const downloadEnabled = await setUpDownloadConfig(req, res, services.downloadPermissionService);
    const feedbackSubmissionFormPath = setupDownloadFeedbackPaths(req, res);
    const reportUrls = setUpReportUrls(req);
    // --- Prepare Data Payloads --------------------------------------------
    const baseData = {
        id,
        reportId,
        reportIsBookmarked,
        downloadEnabled,
        loadType,
    };
    // Sync: these values never change → store them under baseKey
    if (loadType === LoadType.SYNC) {
        Object.assign(baseData, {
            feedbackSubmissionFormPath,
            ...reportUrls,
        });
    }
    const execData = executionId ? { executionId } : undefined;
    const tableData = tableId
        ? {
            tableId,
            ...(executionId && { executionId }),
            ...(feedbackSubmissionFormPath && { feedbackSubmissionFormPath }),
            ...reportUrls,
        }
        : undefined;
    return {
        baseData,
        execData,
        tableData,
    };
};
/**
 * initialises the active report keys
 *
 * @param {Request} req
 * @return {*}
 */
const buildKeyVariants = (req) => {
    const { id, reportId } = req.params;
    const { executionId, tableId } = req.params;
    const baseKey = buildJourneyKey({ reportId, id });
    const execKey = executionId ? buildJourneyKey({ reportId, id, executionId }) : undefined;
    const tableKey = tableId ? buildJourneyKey({ reportId, id, tableId }) : undefined;
    return {
        baseKey,
        execKey,
        tableKey,
    };
};
/**
 * Sets up the active report journey URLS
 *
 * @param {Request} req
 * @return {*}
 */
const setUpReportUrls = (req) => {
    let currentReportPathname;
    let currentReportSearch;
    let currentReportUrl;
    if (req.originalUrl.includes('view-report')) {
        const url = new URL(req.originalUrl, `${req.protocol}://${req.get('host')}`);
        currentReportPathname = url.pathname;
        currentReportSearch = url.search;
        currentReportUrl = req.originalUrl;
    }
    return {
        ...(currentReportPathname && { currentReportPathname }),
        ...(currentReportSearch && { currentReportSearch }),
        ...(currentReportUrl && { currentReportUrl }),
    };
};
/**
 * Sets up the bookmark configuration for the active report
 *
 * @param {Request} req
 * @param {Response} res
 * @param {BookmarkService} service
 * @return {*}
 */
const setUpBookmark = async (req, res, service) => {
    const { reportId, id } = req.params;
    const userId = res.locals['dprUser'].id;
    let reportIsBookmarked = false;
    if (reportId && id && userId) {
        reportIsBookmarked = (await service.isBookmarked(id, reportId, userId)) || false;
    }
    return reportIsBookmarked;
};
/**
 * Sets up the download configuration for the active report
 *
 * @param {Request} req
 * @param {Response} res
 * @param {DownloadPermissionService} service
 * @return {*}
 */
const setUpDownloadConfig = async (req, res, service) => {
    const { reportId, id } = req.params;
    const userId = res.locals['dprUser'].id;
    let downloadEnabled = false;
    if (reportId && id && userId) {
        downloadEnabled = await service.downloadEnabledForReport(userId, reportId, id);
    }
    return downloadEnabled;
};
/**
 * Sets up the feedback configuration for the active report
 *
 * @param {Request} req
 * @param {Response} res
 * @return {*}
 */
const setupDownloadFeedbackPaths = (req, res) => {
    const { reportId, id, tableId } = req.params;
    const { nestedBaseUrl } = getRouteLocals(res);
    let feedbackSubmissionFormPath;
    if (reportId && id) {
        feedbackSubmissionFormPath = tableId
            ? `/dpr/download-report/request-download/${reportId}/${id}/tableId/${tableId}/form`
            : `/dpr/download-report/request-download/${reportId}/${id}/form`;
        feedbackSubmissionFormPath = setNestedPath(feedbackSubmissionFormPath, nestedBaseUrl);
    }
    return feedbackSubmissionFormPath;
};

export { buildKeyVariants, storeActiveReportSessionData };
//# sourceMappingURL=setUpActiveReport.js.map
