import { Router, Request, Response } from "express";
import { getDbStats } from "../db/queries";
import { pool } from "../db/client";
import { loadavg, totalmem, freemem, cpus } from "os";
import { execSync } from "child_process";

export const healthRouter = Router();

// GET /api/health — Health check with DB stats
healthRouter.get("/", async (_req: Request, res: Response) => {
  try {
    const start = Date.now();
    const stats = await getDbStats();
    const latencyMs = Date.now() - start;

    // Verification stats
    const verStats = await pool.query(`
      SELECT
        COUNT(*) FILTER (WHERE price_verified)  AS price_verified,
        COUNT(*) FILTER (WHERE image_verified)  AS image_verified,
        COUNT(*) FILTER (WHERE details_verified) AS details_verified,
        COUNT(*) FILTER (WHERE fully_verified)  AS fully_verified,
        COUNT(*)                                AS total
      FROM transceivers
    `).catch(() => ({ rows: [{}] }));
    const v = verStats.rows[0] || {};

    // Stock observations stats
    const stockStats = await pool.query(`
      SELECT
        COUNT(*)                                                        AS total_observations,
        COUNT(DISTINCT transceiver_id)                                  AS transceivers_with_stock,
        COUNT(DISTINCT source_vendor_id)                                AS vendors_with_stock,
        SUM(warehouse_de_qty)     FILTER (WHERE warehouse_de_qty > 0)  AS total_de_qty,
        SUM(warehouse_global_qty) FILTER (WHERE warehouse_global_qty > 0) AS total_global_qty,
        MAX(time)                                                       AS last_observation_at
      FROM stock_observations
    `).catch(() => ({ rows: [{}] }));
    const s = stockStats.rows[0] || {};

    // System metrics
    const [load1, load5, load15] = loadavg();
    const totalMem = totalmem();
    const freeMem  = freemem();
    const usedMem  = totalMem - freeMem;
    const coreCount = cpus().length;

    let diskUsedPct: number | null = null;
    let diskFreeGb:  number | null = null;
    try {
      const df = execSync("df -h / 2>/dev/null | tail -1", { timeout: 2000 }).toString().trim();
      const parts = df.split(/\s+/);
      diskUsedPct = parseInt(parts[4] ?? "0", 10) || null;
      diskFreeGb  = parseFloat(parts[3] ?? "0") || null;
    } catch { /* skip on systems without df */ }

    const loadStatus = load1 > coreCount * 0.9 ? "overloaded" : load1 > coreCount * 0.6 ? "busy" : "ok";

    res.json({
      success: true,
      status: "healthy",
      version: "0.3.0",
      uptime: process.uptime(),
      system: {
        load: { "1m": +load1.toFixed(2), "5m": +load5.toFixed(2), "15m": +load15.toFixed(2) },
        load_status: loadStatus,
        cpu_cores: coreCount,
        memory: {
          total_mb:  Math.round(totalMem / 1024 / 1024),
          used_mb:   Math.round(usedMem  / 1024 / 1024),
          free_mb:   Math.round(freeMem  / 1024 / 1024),
          used_pct:  Math.round(usedMem / totalMem * 100),
        },
        disk: {
          used_pct: diskUsedPct,
          free_gb:  diskFreeGb,
        },
        process_rss_mb: Math.round(process.memoryUsage().rss / 1024 / 1024),
      },
      database: {
        connected: true,
        latency_ms: latencyMs,
        stats,
      },
      verification: {
        price_verified:      Number(v.price_verified   || 0),
        image_verified:      Number(v.image_verified   || 0),
        details_verified:    Number(v.details_verified || 0),
        fully_verified:      Number(v.fully_verified   || 0),
        total:               Number(v.total            || 0),
        price_coverage_pct:  v.total ? Math.round(Number(v.price_verified) / Number(v.total) * 100) : 0,
        fully_verified_pct:  v.total ? Math.round(Number(v.fully_verified) / Number(v.total) * 100) : 0,
      },
      stock: {
        total_observations:      Number(s.total_observations      || 0),
        transceivers_with_stock: Number(s.transceivers_with_stock || 0),
        vendors_with_stock:      Number(s.vendors_with_stock      || 0),
        total_de_qty:            Number(s.total_de_qty            || 0),
        total_global_qty:        Number(s.total_global_qty        || 0),
        last_observation_at:     s.last_observation_at ?? null,
      },
    });
  } catch (err) {
    res.status(503).json({
      success: false,
      status: "unhealthy",
      database: { connected: false, error: String(err) },
    });
  }
});
