// Atlas InfoSec Action Plans Routes
// Proxies CRUD operations to the Atlas API and maintains a local cache
// for fast badge rendering on the ReportingPage.

const express = require('express');
const pool = require('../db');
const { requireAuth, requireGroup } = require('../middleware/auth');
const logAudit = require('../helpers/auditLog');
const { isConfigured, atlasGet, atlasPut, atlasPatch, atlasPost } = require('../helpers/atlasApi');

const fs = require('fs');
const path = require('path');

const VALID_PLAN_TYPES = ['decommission', 'remediation', 'false_positive', 'risk_acceptance', 'scan_exclusion'];
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;

// Diagnostic log helper
function syncLog(msg) {
    const line = `${new Date().toISOString()} ${msg}\n`;
    try { fs.appendFileSync(path.join(__dirname, '..', 'atlas-sync-debug.log'), line); } catch (_) { /* ignore */ }
    console.log(msg);
}

// ---------------------------------------------------------------------------
// Pure aggregation function — exported for testability
// ---------------------------------------------------------------------------
function aggregateAtlasMetrics(rows) {
    const result = {
        totalHosts: rows.length,
        hostsWithPlans: 0,
        hostsWithoutPlans: 0,
        plansByType: {},
        plansByStatus: {},
        totalPlans: 0
    };

    for (const row of rows) {
        if (row.has_action_plan === true || row.has_action_plan === 1) {
            result.hostsWithPlans++;
        } else {
            result.hostsWithoutPlans++;
        }

        let plans;
        try {
            plans = JSON.parse(row.plans_json);
        } catch (e) {
            continue;
        }

        if (!Array.isArray(plans)) continue;

        for (const plan of plans) {
            result.totalPlans++;
            if (plan.plan_type) {
                result.plansByType[plan.plan_type] = (result.plansByType[plan.plan_type] || 0) + 1;
            }
            if (plan.status) {
                result.plansByStatus[plan.status] = (result.plansByStatus[plan.status] || 0) + 1;
            }
        }
    }

    return result;
}

// ---------------------------------------------------------------------------
// Router factory
// ---------------------------------------------------------------------------
function createAtlasRouter() {
    const router = express.Router();

    /**
     * GET /metrics
     *
     * Returns aggregated Atlas action plan metrics from the local cache.
     *
     * @returns {Object} 200 - { totalHosts, hostsWithPlans, hostsWithoutPlans, plansByType, plansByStatus, totalPlans }
     * @returns {Object} 503 - { error } when Atlas API is not configured
     * @returns {Object} 500 - { error } on database failure
     */
    router.get('/metrics', requireAuth(), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        try {
            const { rows } = await pool.query(
                `SELECT has_action_plan, plans_json FROM atlas_action_plans_cache`
            );
            const metrics = aggregateAtlasMetrics(rows);
            res.json(metrics);
        } catch (err) {
            console.error('[Atlas] Error fetching metrics:', err.message);
            res.status(500).json({ error: 'Failed to fetch Atlas metrics.' });
        }
    });

    /**
     * GET /status
     *
     * Returns the full atlas_action_plans_cache table contents for status display.
     *
     * @returns {Array} 200 - Array of { host_id, has_action_plan, plan_count, plans_json, synced_at }
     * @returns {Object} 503 - { error } when Atlas API is not configured
     * @returns {Object} 500 - { error } on database failure
     */
    router.get('/status', requireAuth(), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        try {
            const { rows } = await pool.query(
                `SELECT host_id, has_action_plan, plan_count, plans_json, synced_at FROM atlas_action_plans_cache`
            );
            res.json(rows);
        } catch (err) {
            console.error('[Atlas] Error fetching status:', err.message);
            res.status(500).json({ error: 'Failed to fetch Atlas status.' });
        }
    });

    /**
     * POST /sync
     *
     * Syncs action plan data from Atlas for all hosts found in ivanti_findings.
     * Fetches plans per host in batches of 5 and upserts into the local cache.
     * Requires Admin or Standard_User group.
     *
     * @returns {Object} 200 - { synced, withPlans, failed }
     * @returns {Object} 503 - { error } when Atlas API is not configured
     * @returns {Object} 500 - { error } on unexpected failure
     */
    router.post('/sync', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        try {
            // Read Ivanti findings and extract unique non-null hostIds
            const { rows: findingsRows } = await pool.query(
                `SELECT DISTINCT host_id FROM ivanti_findings WHERE host_id IS NOT NULL AND host_id > 0`
            );
            const hostIds = findingsRows.map(r => r.host_id);

            if (hostIds.length === 0) {
                return res.json({ synced: 0, withPlans: 0, failed: 0 });
            }

            let synced = 0;
            let withPlans = 0;
            let failed = 0;
            const BATCH_SIZE = 5;

            for (let i = 0; i < hostIds.length; i += BATCH_SIZE) {
                const batch = hostIds.slice(i, i + BATCH_SIZE);
                const results = await Promise.allSettled(
                    batch.map(async (hostId) => {
                        const result = await atlasGet('/hosts/' + hostId + '/action-plans');
                        return { hostId, result };
                    })
                );

                for (const settled of results) {
                    if (settled.status === 'rejected') {
                        failed++;
                        console.warn('[Atlas Sync] Request failed for host:', settled.reason?.message || settled.reason);
                        continue;
                    }

                    const { hostId, result } = settled.value;

                    if (result.status >= 200 && result.status < 300) {
                        let allPlans = [];
                        let activePlans = [];
                        try {
                            const parsed = JSON.parse(result.body);
                            if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
                                activePlans = Array.isArray(parsed.active) ? parsed.active : [];
                                const inactive = Array.isArray(parsed.inactive) ? parsed.inactive : [];
                                allPlans = [...activePlans, ...inactive];
                            } else if (Array.isArray(parsed)) {
                                allPlans = parsed;
                                activePlans = parsed;
                            }
                        } catch (e) {
                            allPlans = [];
                            activePlans = [];
                        }

                        const planCount = activePlans.length;
                        const hasActionPlan = planCount > 0;

                        try {
                            if (!hasActionPlan) {
                                const { rows: existingRows } = await pool.query(
                                    `SELECT has_action_plan, plans_json, synced_at FROM atlas_action_plans_cache WHERE host_id = $1`,
                                    [hostId]
                                );
                                const existing = existingRows[0];
                                if (existing && existing.has_action_plan === true) {
                                    let existingPlans = [];
                                    try { existingPlans = JSON.parse(existing.plans_json || '[]'); } catch (_) {}
                                    const hasBulkStub = existingPlans.some(p => p.source === 'bulk-create');
                                    if (hasBulkStub) {
                                        const ageMs = Date.now() - new Date(existing.synced_at).getTime();
                                        const TEN_MINUTES = 10 * 60 * 1000;
                                        if (ageMs < TEN_MINUTES) {
                                            synced++;
                                            withPlans++;
                                            continue;
                                        }
                                    }
                                }
                            }

                            await pool.query(
                                `INSERT INTO atlas_action_plans_cache (host_id, has_action_plan, plan_count, plans_json, synced_at)
                                 VALUES ($1, $2, $3, $4, NOW())
                                 ON CONFLICT(host_id) DO UPDATE SET
                                     has_action_plan = EXCLUDED.has_action_plan,
                                     plan_count = EXCLUDED.plan_count,
                                     plans_json = EXCLUDED.plans_json,
                                     synced_at = EXCLUDED.synced_at`,
                                [hostId, hasActionPlan, planCount, JSON.stringify(allPlans)]
                            );
                        } catch (dbErr) {
                            console.error('[Atlas Sync] DB upsert failed for host', hostId, ':', dbErr.message);
                        }

                        synced++;
                        if (hasActionPlan) withPlans++;
                    } else {
                        failed++;
                        console.warn(`[Atlas Sync] Non-2xx response for host ${hostId}: status ${result.status}`);
                    }
                }
            }

            logAudit({
                userId: req.user.id,
                username: req.user.username,
                action: 'ATLAS_SYNC',
                entityType: 'atlas_action_plans',
                entityId: null,
                details: { synced, withPlans, failed, totalHosts: hostIds.length },
                ipAddress: req.ip
            });

            res.json({ synced, withPlans, failed });
        } catch (err) {
            console.error('[Atlas Sync] Unexpected error:', err.message);
            res.status(500).json({ error: 'Atlas sync failed: ' + err.message });
        }
    });

    /**
     * GET /hosts/:hostId/action-plans
     *
     * Proxies a request to Atlas to retrieve action plans for a specific host.
     *
     * @param {number} req.params.hostId - Positive integer host identifier
     * @returns {Object} 2xx - Action plans response from Atlas API
     * @returns {Object} 400 - { error } when hostId is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.get('/hosts/:hostId/action-plans', requireAuth(), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const hostId = parseInt(req.params.hostId, 10);
        if (!Number.isInteger(hostId) || hostId <= 0) {
            return res.status(400).json({ error: 'hostId must be a positive integer' });
        }

        try {
            const result = await atlasGet('/hosts/' + hostId + '/action-plans');
            if (result.status >= 200 && result.status < 300) {
                let body;
                try { body = JSON.parse(result.body); } catch (e) { body = result.body; }
                res.status(result.status).json(body);
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] GET action-plans failed for host', hostId, ':', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    /**
     * PUT /hosts/:hostId/action-plans
     *
     * Creates a new action plan for a host via the Atlas API.
     * Requires Admin or Standard_User group.
     *
     * @param {number} req.params.hostId - Positive integer host identifier
     * @param {Object} req.body
     * @param {string} req.body.plan_type - One of: decommission, remediation, false_positive, risk_acceptance, scan_exclusion
     * @param {string} req.body.commit_date - Date in YYYY-MM-DD format
     * @returns {Object} 2xx - Created plan response from Atlas API
     * @returns {Object} 400 - { error } when hostId, plan_type, or commit_date is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.put('/hosts/:hostId/action-plans', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const hostId = parseInt(req.params.hostId, 10);
        if (!Number.isInteger(hostId) || hostId <= 0) {
            return res.status(400).json({ error: 'hostId must be a positive integer' });
        }

        const { plan_type, commit_date } = req.body || {};
        if (!plan_type || !VALID_PLAN_TYPES.includes(plan_type)) {
            return res.status(400).json({ error: 'plan_type must be one of: ' + VALID_PLAN_TYPES.join(', ') });
        }
        if (!commit_date || !DATE_PATTERN.test(commit_date)) {
            return res.status(400).json({ error: 'commit_date must be a valid YYYY-MM-DD date string' });
        }

        try {
            const result = await atlasPut('/hosts/' + hostId + '/action-plans', req.body);

            logAudit({
                userId: req.user.id,
                username: req.user.username,
                action: 'ATLAS_CREATE_PLAN',
                entityType: 'atlas_action_plan',
                entityId: String(hostId),
                details: { hostId, plan_type, commit_date },
                ipAddress: req.ip
            });

            if (result.status >= 200 && result.status < 300) {
                let body;
                try { body = JSON.parse(result.body); } catch (e) { body = result.body; }
                res.status(result.status).json(body);
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] PUT action-plans failed for host', hostId, ':', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    /**
     * PATCH /hosts/:hostId/action-plans
     *
     * Updates an existing action plan for a host via the Atlas API.
     * Requires Admin or Standard_User group.
     *
     * @param {number} req.params.hostId - Positive integer host identifier
     * @param {Object} req.body
     * @param {string} req.body.action_plan_id - Non-empty string identifying the plan to update
     * @param {Object} req.body.updates - Object containing fields to update
     * @returns {Object} 2xx - Updated plan response from Atlas API
     * @returns {Object} 400 - { error } when hostId, action_plan_id, or updates is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.patch('/hosts/:hostId/action-plans', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const hostId = parseInt(req.params.hostId, 10);
        if (!Number.isInteger(hostId) || hostId <= 0) {
            return res.status(400).json({ error: 'hostId must be a positive integer' });
        }

        const { action_plan_id, updates } = req.body || {};
        if (!action_plan_id || typeof action_plan_id !== 'string' || action_plan_id.trim() === '') {
            return res.status(400).json({ error: 'action_plan_id is required and must be a non-empty string' });
        }
        if (!updates || typeof updates !== 'object' || Array.isArray(updates)) {
            return res.status(400).json({ error: 'updates is required and must be an object' });
        }

        try {
            const result = await atlasPatch('/hosts/' + hostId + '/action-plans', req.body);

            logAudit({
                userId: req.user.id,
                username: req.user.username,
                action: 'ATLAS_UPDATE_PLAN',
                entityType: 'atlas_action_plan',
                entityId: String(hostId),
                details: { hostId, action_plan_id },
                ipAddress: req.ip
            });

            if (result.status >= 200 && result.status < 300) {
                let body;
                try { body = JSON.parse(result.body); } catch (e) { body = result.body; }
                res.status(result.status).json(body);
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] PATCH action-plans failed for host', hostId, ':', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    /**
     * POST /hosts/bulk-action-plans
     *
     * Creates action plans for multiple hosts in a single request via the Atlas API.
     * Optimistically updates the local cache with stub plans after a successful response.
     * Requires Admin or Standard_User group.
     *
     * @param {Object} req.body
     * @param {number[]} req.body.host_ids - Non-empty array of positive integer host identifiers
     * @param {string} req.body.plan_type - One of: decommission, remediation, false_positive, risk_acceptance, scan_exclusion
     * @param {string} req.body.commit_date - Date in YYYY-MM-DD format
     * @returns {Object} 2xx - Bulk creation response from Atlas API
     * @returns {Object} 400 - { error } when host_ids, plan_type, or commit_date is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.post('/hosts/bulk-action-plans', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const { host_ids, plan_type, commit_date } = req.body || {};
        if (!Array.isArray(host_ids) || host_ids.length === 0) {
            return res.status(400).json({ error: 'host_ids must be a non-empty array of positive integers' });
        }
        for (const id of host_ids) {
            if (!Number.isInteger(id) || id <= 0) {
                return res.status(400).json({ error: 'host_ids must be a non-empty array of positive integers' });
            }
        }
        if (!plan_type || !VALID_PLAN_TYPES.includes(plan_type)) {
            return res.status(400).json({ error: 'plan_type must be one of: ' + VALID_PLAN_TYPES.join(', ') });
        }
        if (!commit_date || !DATE_PATTERN.test(commit_date)) {
            return res.status(400).json({ error: 'commit_date must be a valid YYYY-MM-DD date string' });
        }

        try {
            const result = await atlasPost('/hosts/create-bulk-action-plans', req.body);

            if (result.status >= 200 && result.status < 300) {
                let body;
                try { body = JSON.parse(result.body); } catch (e) { body = result.body; }

                // Optimistically update local cache
                for (const hid of host_ids) {
                    try {
                        const { rows: existingRows } = await pool.query(
                            `SELECT plan_count, plans_json FROM atlas_action_plans_cache WHERE host_id = $1`,
                            [hid]
                        );
                        const existing = existingRows[0];

                        let existingPlans = [];
                        if (existing && existing.plans_json) {
                            try { existingPlans = JSON.parse(existing.plans_json); } catch (_) {}
                        }

                        const stubPlan = { plan_type, commit_date, source: 'bulk-create', created_at: new Date().toISOString() };
                        const updatedPlans = [...existingPlans, stubPlan];
                        const newCount = updatedPlans.length;

                        await pool.query(
                            `INSERT INTO atlas_action_plans_cache (host_id, has_action_plan, plan_count, plans_json, synced_at)
                             VALUES ($1, true, $2, $3, NOW())
                             ON CONFLICT(host_id) DO UPDATE SET
                                 has_action_plan = true,
                                 plan_count = EXCLUDED.plan_count,
                                 plans_json = EXCLUDED.plans_json,
                                 synced_at = EXCLUDED.synced_at`,
                            [hid, newCount, JSON.stringify(updatedPlans)]
                        );
                    } catch (cacheErr) {
                        console.error('[Atlas] Cache update failed for host', hid, ':', cacheErr.message);
                    }
                }

                logAudit({
                    userId: req.user.id,
                    username: req.user.username,
                    action: 'ATLAS_BULK_CREATE_PLANS',
                    entityType: 'atlas_action_plan',
                    entityId: null,
                    details: { host_ids, plan_type, commit_date, count: host_ids.length },
                    ipAddress: req.ip
                });

                res.status(result.status).json(body);
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] POST bulk-action-plans failed:', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    /**
     * POST /hosts/:hostId/refresh-cache
     *
     * Triggers Atlas to refresh its Ivanti data cache, then updates the local
     * action plans cache for the specified host. Useful when action plan creation
     * fails due to stale finding IDs.
     * Requires Admin or Standard_User group.
     *
     * @param {number} req.params.hostId - Positive integer host identifier
     * @returns {Object} 200 - { success, message } on successful cache refresh
     * @returns {Object} 400 - { error } when hostId is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.post('/hosts/:hostId/refresh-cache', requireAuth(), requireGroup('Admin', 'Standard_User'), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const hostId = parseInt(req.params.hostId, 10);
        if (!Number.isInteger(hostId) || hostId <= 0) {
            return res.status(400).json({ error: 'hostId must be a positive integer' });
        }

        try {
            const result = await atlasPost('/cache/refresh-ivanti', {}, { timeout: 30000 });

            if (result.status >= 200 && result.status < 300) {
                // Also refresh our local action plans cache for this host
                const plansResult = await atlasGet('/hosts/' + hostId + '/action-plans');
                if (plansResult.status >= 200 && plansResult.status < 300) {
                    let allPlans = [];
                    let activePlans = [];
                    try {
                        const parsed = JSON.parse(plansResult.body);
                        if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
                            activePlans = Array.isArray(parsed.active) ? parsed.active : [];
                            const inactive = Array.isArray(parsed.inactive) ? parsed.inactive : [];
                            allPlans = [...activePlans, ...inactive];
                        } else if (Array.isArray(parsed)) {
                            allPlans = parsed;
                            activePlans = parsed;
                        }
                    } catch (_) {}

                    const planCount = activePlans.length;
                    const hasActionPlan = planCount > 0;

                    await pool.query(
                        `INSERT INTO atlas_action_plans_cache (host_id, has_action_plan, plan_count, plans_json, synced_at)
                         VALUES ($1, $2, $3, $4, NOW())
                         ON CONFLICT(host_id) DO UPDATE SET
                             has_action_plan = EXCLUDED.has_action_plan,
                             plan_count = EXCLUDED.plan_count,
                             plans_json = EXCLUDED.plans_json,
                             synced_at = EXCLUDED.synced_at`,
                        [hostId, hasActionPlan, planCount, JSON.stringify(allPlans)]
                    );
                }

                res.json({ success: true, message: 'Atlas cache refreshed for host ' + hostId });
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] POST refresh-cache failed for host', hostId, ':', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    /**
     * POST /hosts/vulnerabilities
     *
     * Fetches Ivanti vulnerability data for the specified hosts from Atlas.
     *
     * @param {Object} req.body
     * @param {number[]} req.body.host_ids - Non-empty array of positive integer host identifiers
     * @returns {Object} 2xx - Vulnerability data response from Atlas API
     * @returns {Object} 400 - { error } when host_ids is invalid
     * @returns {Object} 502 - { error } when Atlas API is unreachable
     * @returns {Object} 503 - { error } when Atlas API is not configured
     */
    router.post('/hosts/vulnerabilities', requireAuth(), async (req, res) => {
        if (!isConfigured) {
            return res.status(503).json({ error: 'Atlas API is not configured. Check ATLAS_API_URL, ATLAS_API_USER, and ATLAS_API_PASS environment variables.' });
        }

        const { host_ids } = req.body || {};
        if (!Array.isArray(host_ids) || host_ids.length === 0) {
            return res.status(400).json({ error: 'host_ids must be a non-empty array of positive integers' });
        }
        for (const id of host_ids) {
            if (!Number.isInteger(id) || id <= 0) {
                return res.status(400).json({ error: 'host_ids must be a non-empty array of positive integers' });
            }
        }

        try {
            const result = await atlasPost('/ivanti-vulnerabilities-by-host', { host_ids }, { timeout: 30000 });

            if (result.status >= 200 && result.status < 300) {
                let body;
                try { body = JSON.parse(result.body); } catch (e) { body = result.body; }
                res.status(result.status).json(body);
            } else {
                let errorBody;
                try { errorBody = JSON.parse(result.body); } catch (e) { errorBody = { error: result.body }; }
                res.status(result.status).json(errorBody);
            }
        } catch (err) {
            console.error('[Atlas] POST hosts/vulnerabilities failed:', err.message);
            res.status(502).json({ error: 'Failed to reach Atlas API: ' + err.message });
        }
    });

    return router;
}

module.exports = createAtlasRouter;
module.exports.aggregateAtlasMetrics = aggregateAtlasMetrics;
