/**
 * src/routes/monitoring.js
 * 
 * Public endpoints (called by the extension — no JWT needed, auth via license key)
 *   POST /api/monitor/error      — report an error
 *   POST /api/monitor/heartbeat  — ping while alive
 *
 * Admin endpoints (JWT required)
 *   GET  /api/admin/monitoring/errors
 *   GET  /api/admin/monitoring/heartbeats
 *   GET  /api/admin/monitoring/validation-logs
 *   GET  /api/admin/monitoring/stats
 *   DELETE /api/admin/monitoring/errors/:id
 */
const express = require('express');
const router = express.Router();
const db = require('../db');
const { requireAuth, requireSuperAdmin } = require('../middleware/auth');

// ── Public (extension → backend) ─────────────────────────────

/** POST /api/monitor/error */
router.post('/error', async (req, res) => {
    const { license_key, device_id, error_type, error_msg, error_stack, url, version } = req.body;
    if (!error_type) return res.status(400).json({ error: 'error_type required' });
    const ip = req.ip || req.headers['x-forwarded-for'];
    const ua = req.headers['user-agent'];
    try {
        await db.execute(
            `INSERT INTO extension_errors
             (license_key, device_id, error_type, error_msg, error_stack, url, version, user_agent, ip_address)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [license_key || null, device_id || null, error_type, error_msg || null,
            error_stack || null, url || null, version || null, ua || null, ip]
        );
        res.json({ ok: true });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

/** POST /api/monitor/heartbeat */
router.post('/heartbeat', async (req, res) => {
    const { license_key, device_id, version, page_host } = req.body;
    if (!license_key) return res.status(400).json({ error: 'license_key required' });
    const ip = req.ip || req.headers['x-forwarded-for'];
    try {
        await db.execute(
            `INSERT INTO extension_heartbeats (license_key, device_id, version, page_host, ip_address)
             VALUES (?, ?, ?, ?, ?)`,
            [license_key, device_id || null, version || null, page_host || null, ip]
        );
        // Update last_seen_at on the license
        await db.execute(
            `UPDATE licenses SET last_seen_at = NOW() WHERE license_key = ?`,
            [license_key]
        );
        res.json({ ok: true });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

// ── Admin (JWT protected) ─────────────────────────────────────

/** GET /api/admin/monitoring/stats */
router.get('/stats', requireAuth, requireSuperAdmin, async (req, res) => {
    try {
        const [[{ total_errors }]] = await db.query(
            `SELECT COUNT(*) as total_errors FROM extension_errors WHERE created_at >= NOW() - INTERVAL 24 HOUR`
        );
        const [[{ active_devices }]] = await db.query(
            `SELECT COUNT(DISTINCT license_key) as active_devices FROM extension_heartbeats WHERE created_at >= NOW() - INTERVAL 15 MINUTE`
        );
        const [[{ heartbeats_today }]] = await db.query(
            `SELECT COUNT(*) as heartbeats_today FROM extension_heartbeats WHERE created_at >= CURDATE()`
        );
        const [[{ failed_validations }]] = await db.query(
            `SELECT COUNT(*) as failed_validations FROM license_validation_logs WHERE result != 'ok' AND created_at >= NOW() - INTERVAL 24 HOUR`
        );
        res.json({ total_errors, active_devices, heartbeats_today, failed_validations });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

/** GET /api/admin/monitoring/errors?page=1&limit=50&type=&license_key= */
router.get('/errors', requireAuth, requireSuperAdmin, async (req, res) => {
    const limit = Math.min(parseInt(req.query.limit) || 50, 200);
    const offset = (Math.max(parseInt(req.query.page) || 1, 1) - 1) * limit;
    const type = req.query.type || '';
    const key = req.query.license_key || '';

    let where = 'WHERE 1=1';
    const params = [];
    if (type) { where += ' AND error_type = ?'; params.push(type); }
    if (key) { where += ' AND license_key = ?'; params.push(key); }
    params.push(limit, offset);

    try {
        const [errors] = await db.query(
            `SELECT id, license_key, device_id, error_type, error_msg, url, version, ip_address, created_at
             FROM extension_errors ${where}
             ORDER BY created_at DESC LIMIT ? OFFSET ?`,
            params
        );
        const [[{ total }]] = await db.query(
            `SELECT COUNT(*) as total FROM extension_errors ${where}`,
            params.slice(0, -2)
        );
        // Error type breakdown for chart
        const [breakdown] = await db.query(
            `SELECT error_type, COUNT(*) as count FROM extension_errors
             WHERE created_at >= NOW() - INTERVAL 7 DAY
             GROUP BY error_type ORDER BY count DESC LIMIT 10`
        );
        res.json({ errors, total, breakdown });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

/** DELETE /api/admin/monitoring/errors/:id */
router.delete('/errors/:id', requireAuth, requireSuperAdmin, async (req, res) => {
    try {
        await db.execute('DELETE FROM extension_errors WHERE id = ?', [req.params.id]);
        res.json({ ok: true });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

/** GET /api/admin/monitoring/heartbeats — últimos heartbeats agrupados por licença */
router.get('/heartbeats', requireAuth, requireSuperAdmin, async (req, res) => {
    try {
        const [heartbeats] = await db.query(`
            SELECT
                h.license_key,
                h.device_id,
                MAX(h.version) as version,
                MAX(h.page_host) as page_host,
                MAX(h.ip_address) as ip_address,
                MAX(h.created_at) as last_seen,
                COUNT(*) as ping_count_today,
                CASE WHEN MAX(h.created_at) >= NOW() - INTERVAL 15 MINUTE THEN 1 ELSE 0 END as is_online
            FROM extension_heartbeats h
            WHERE h.created_at >= CURDATE()
            GROUP BY h.license_key, h.device_id
            ORDER BY last_seen DESC
            LIMIT 100
        `);
        // Also get licenses that have NOT pinged today
        const [offline] = await db.query(`
            SELECT l.license_key, l.last_seen_at, l.bound_user, l.status
            FROM licenses l
            WHERE l.status = 'active'
              AND l.last_seen_at IS NOT NULL
              AND l.license_key NOT IN (
                SELECT DISTINCT license_key FROM extension_heartbeats WHERE created_at >= CURDATE()
              )
            ORDER BY l.last_seen_at DESC
            LIMIT 50
        `);
        res.json({ heartbeats, offline });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

/** GET /api/admin/monitoring/validation-logs */
router.get('/validation-logs', requireAuth, requireSuperAdmin, async (req, res) => {
    const limit = Math.min(parseInt(req.query.limit) || 100, 500);
    const result = req.query.result || '';
    const params = [];
    let where = 'WHERE 1=1';
    if (result) { where += ' AND result = ?'; params.push(result); }
    params.push(limit);
    try {
        const [logs] = await db.query(
            `SELECT id, license_key, device_id, result, ip_address, created_at
             FROM license_validation_logs ${where}
             ORDER BY created_at DESC LIMIT ?`,
            params
        );
        const [summary] = await db.query(`
            SELECT result, COUNT(*) as count
            FROM license_validation_logs
            WHERE created_at >= NOW() - INTERVAL 24 HOUR
            GROUP BY result
        `);
        res.json({ logs, summary });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

// Timeline of errors per hour (for chart)
router.get('/errors/timeline', requireAuth, requireSuperAdmin, async (req, res) => {
    const hours = Math.min(parseInt(req.query.hours) || 24, 168);
    try {
        const [timeline] = await db.query(`
            SELECT
                DATE_FORMAT(created_at, '%Y-%m-%d %H:00') as hour,
                COUNT(*) as count,
                error_type
            FROM extension_errors
            WHERE created_at >= NOW() - INTERVAL ? HOUR
            GROUP BY hour, error_type
            ORDER BY hour ASC
        `, [hours]);
        res.json({ timeline });
    } catch (e) { res.status(500).json({ error: e.message }); }
});

module.exports = router;
