/**
 * routes/health.js
 *
 * Liveness + readiness probe. No auth, no CSRF, no rate limit.
 *
 * Liveness  — the process is up and the event loop is responsive.
 * Readiness — the DB is reachable, the three workers are running,
 *             and the key rotator has at least one active key for
 *             each critical service (scrape_do, resend).
 *
 * Usage:
 *   GET /health          → 200 ok / 503 degraded (with body)
 *   GET /health/live     → 200 always
 *   GET /health/ready    → 200 / 503 (readiness only)
 *
 * The deploy doc says to monitor /health every minute. The cron +
 * external monitor should alert on HTTP 503 or `status: degraded`.
 */

'use strict';

const express = require('express');
const router = express.Router();
const { db } = require('../config/db');

const startedAt = Date.now();

function getWorkerStates() {
  // Each worker module exports .start() and a `state` object describing
  // last tick / last failure. Use the global registry kept by app.js.
  const reg = global.__ncii_workers || {};
  return {
    caseDiscovery: reg.caseDiscovery || 'unknown',
    takedown:      reg.takedown      || 'unknown',
    autoEscalate:  reg.autoEscalate  || 'unknown',
    linkHealth:    reg.linkHealth    || 'unknown',
    weeklyDigest:  reg.weeklyDigest  || 'unknown',
    backup:        reg.backup        || 'unknown',
  };
}

function getKeyHealth() {
  const rows = db.prepare(`SELECT service, COUNT(*) as n,
    SUM(CASE WHEN is_active=1 AND (exhausted_until IS NULL OR exhausted_until < ?) THEN 1 ELSE 0 END) as active
    FROM api_keys WHERE service IN ('scrape_do','resend','MiniMax')
    GROUP BY service`).all(Date.now());
  const out = {};
  for (const r of rows) out[r.service] = { total: r.n, active: r.active };
  return out;
}

function getHealthSnapshot() {
  const uptime = Date.now() - startedAt;
  let dbOk = true;
  try { db.prepare('SELECT 1').get(); } catch (e) { dbOk = false; }
  const workers = getWorkerStates();
  const keys = getKeyHealth();
  const ready = dbOk
    && Object.values(workers).every(s => s === 'running' || s === 'unknown')
    && (keys.scrape_do?.active || 0) > 0
    && (keys.resend?.active    || 0) > 0;

  const body = {
    status: ready ? 'ok' : 'degraded',
    uptime_seconds: Math.floor(uptime / 1000),
    db: dbOk ? 'ok' : 'down',
    workers,
    keys,
    node_env: process.env.NODE_ENV || 'development',
    version: require('../package.json').version,
  };
  return { ready, body };
}

router.get('/', (req, res) => {
  const { ready, body } = getHealthSnapshot();
  res.status(ready ? 200 : 503).json(body);
});

router.get('/live', (req, res) => res.json({ status: 'ok' }));
router.get('/ready', (req, res) => {
  const { ready, body } = getHealthSnapshot();
  res.status(ready ? 200 : 503).json(body);
});

module.exports = router;
