import { NextResponse } from "next/server";
import { prisma } from "@capakraken/db";
import { createNotificationsForUsers } from "@capakraken/api";
import { logger } from "@capakraken/api/lib/logger";
import { createConnection } from "net";
import { verifyCronSecret } from "~/lib/cron-auth.js";

export const dynamic = "force-dynamic";
export const runtime = "nodejs";

const REDIS_URL = process.env["REDIS_URL"] ?? "redis://localhost:6380";

async function checkPostgres(): Promise<{ status: "ok" | "error"; latencyMs: number }> {
  const start = Date.now();
  try {
    await prisma.$queryRaw`SELECT 1`;
    return { status: "ok", latencyMs: Date.now() - start };
  } catch {
    return { status: "error", latencyMs: Date.now() - start };
  }
}

async function checkRedis(): Promise<{ status: "ok" | "error"; latencyMs: number }> {
  const start = Date.now();
  return new Promise((resolve) => {
    try {
      const url = new URL(REDIS_URL);
      const host = url.hostname || "localhost";
      const port = parseInt(url.port || "6379", 10);
      const timeout = 3000;

      const socket = createConnection({ host, port }, () => {
        socket.write("*1\r\n$4\r\nPING\r\n");
      });

      socket.setTimeout(timeout);

      socket.on("data", (data) => {
        const response = data.toString();
        socket.destroy();
        resolve({
          status: response.includes("PONG") ? "ok" : "error",
          latencyMs: Date.now() - start,
        });
      });

      socket.on("timeout", () => {
        socket.destroy();
        resolve({ status: "error", latencyMs: Date.now() - start });
      });

      socket.on("error", () => {
        socket.destroy();
        resolve({ status: "error", latencyMs: Date.now() - start });
      });
    } catch {
      resolve({ status: "error", latencyMs: Date.now() - start });
    }
  });
}

/**
 * GET /api/cron/health-check
 *
 * Self-health-check endpoint that verifies PostgreSQL and Redis connectivity.
 * If any check fails, creates a CRITICAL notification for all ADMIN users.
 *
 * Protected by CRON_SECRET environment variable.
 * When set, requests must include `Authorization: Bearer <secret>`.
 */
export async function GET(request: Request) {
  const deny = verifyCronSecret(request);
  if (deny) return deny;

  try {
    const [postgres, redis] = await Promise.all([
      checkPostgres(),
      checkRedis(),
    ]);

    const allHealthy = postgres.status === "ok" && redis.status === "ok";

    // If any check fails, alert all ADMIN users
    if (!allHealthy) {
      const failedChecks: string[] = [];
      if (postgres.status !== "ok") failedChecks.push("PostgreSQL");
      if (redis.status !== "ok") failedChecks.push("Redis");

      const adminUsers = await prisma.user.findMany({
        where: { systemRole: "ADMIN" },
        select: { id: true },
      });

      if (adminUsers.length > 0) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        await createNotificationsForUsers({
          db: prisma as any,
          userIds: adminUsers.map((u) => u.id),
          type: "SYSTEM_ALERT",
          title: "CRITICAL: Health Check Failed",
          body: `The following services are unreachable: ${failedChecks.join(", ")}. Immediate attention required.`,
          category: "system",
          priority: "CRITICAL",
          link: "/admin/settings",
        });
      }
    }

    return NextResponse.json(
      {
        ok: allHealthy,
        checks: {
          postgres: postgres.status,
          postgresLatencyMs: postgres.latencyMs,
          redis: redis.status,
          redisLatencyMs: redis.latencyMs,
        },
        timestamp: new Date().toISOString(),
      },
      { status: allHealthy ? 200 : 503 },
    );
  } catch (error) {
    logger.error({ error, route: "/api/cron/health-check" }, "Health check cron failed");
    return NextResponse.json(
      { ok: false, error: "Internal error" },
      { status: 500 },
    );
  }
}
