import { Router, type Request, type Response } from "express";
import { db, jobs } from "@workspace/db";
import { sql, gte } from "drizzle-orm";
import { makeLogger } from "../lib/logger.js";

const router = Router();
const logger = makeLogger("stats");

/**
 * GET /api/stats/activity
 *
 * Returns job counts bucketed by hour for the past 24 hours.
 * Each bucket represents a UTC hour (0–23).
 * Hours with no activity are included as 0.
 *
 * Response shape:
 *   { hours: number[24], generatedAt: string }
 *   hours[0] = oldest hour (24h ago), hours[23] = current hour
 */
router.get("/api/stats/activity", async (_req: Request, res: Response) => {
  try {
    const now = new Date();
    const windowStart = new Date(now.getTime() - 24 * 60 * 60 * 1000);

    // Count completed jobs grouped by the hour they were created,
    // within the last 24h window.
    const rows = await db
      .select({
        hour: sql<number>`cast(extract(epoch from date_trunc('hour', created_at)) as bigint)`,
        count: sql<number>`cast(count(*) as int)`,
      })
      .from(jobs)
      .where(gte(jobs.createdAt, windowStart))
      .groupBy(sql`date_trunc('hour', created_at)`);

    // Build a map: epoch-hour → count
    const byEpochHour = new Map<number, number>();
    for (const row of rows) {
      byEpochHour.set(Number(row.hour), Number(row.count));
    }

    // Build 24-slot array aligned to whole hours, oldest first.
    // slot 0 = floor(now - 24h), slot 23 = floor(now)
    const currentHourEpoch = Math.floor(now.getTime() / (3600 * 1000)) * 3600;
    const hours: number[] = [];
    for (let i = 23; i >= 0; i--) {
      const slotEpoch = currentHourEpoch - i * 3600;
      hours.push(byEpochHour.get(slotEpoch) ?? 0);
    }

    res.json({ hours, generatedAt: now.toISOString() });
  } catch (err) {
    const message = err instanceof Error ? err.message : "Failed to fetch activity stats";
    logger.error("activity stats failed", { error: message });
    res.status(500).json({ error: message });
  }
});

export default router;
