import { prisma } from "@/lib/db";

/**
 * 404 monitor — port of includes/modules/404-monitor.
 *
 * Logs every public 404 with path/referrer/UA/IP, deduplicating to a single
 * row per path with `hits` counter. Used by /admin/404-monitor to surface
 * frequent broken paths so the user can create a Redirect.
 *
 * NOTE: We use the Setting table to enable/disable, so the engine stays
 * runtime-pluggable without a code deploy.
 */

let cache: { value: boolean; expiresAt: number } | null = null;

async function isEnabled(): Promise<boolean> {
  const now = Date.now();
  if (cache && cache.expiresAt > now) return cache.value;
  const row = await prisma.setting.findUnique({
    where: { key: "monitor.404_enabled" },
    select: { value: true },
  });
  const value = (row?.value ?? "true").toLowerCase() !== "false";
  cache = { value, expiresAt: now + 60_000 };
  return value;
}

export async function track404(input: {
  path: string;
  referrer?: string | null;
  userAgent?: string | null;
  ip?: string | null;
}): Promise<void> {
  if (!(await isEnabled())) return;
  const path = (input.path ?? "").trim().slice(0, 1024);
  if (!path || path === "/") return;
  if (path.startsWith("/_next") || path.startsWith("/api/") || path.startsWith("/admin"))
    return;

  // Find existing row, increment hits, update referrer/UA. Otherwise create.
  await prisma.$transaction(async (tx) => {
    const existing = await tx.notFoundLog.findUnique({
      where: { path },
      select: { id: true },
    });
    if (existing) {
      await tx.notFoundLog.update({
        where: { id: existing.id },
        data: {
          hits: { increment: 1 },
          lastReferrer: input.referrer ?? null,
          lastUserAgent: input.userAgent ?? null,
          lastIp: input.ip ?? null,
          lastSeen: new Date(),
        },
      });
    } else {
      await tx.notFoundLog.create({
        data: {
          path,
          hits: 1,
          lastReferrer: input.referrer ?? null,
          lastUserAgent: input.userAgent ?? null,
          lastIp: input.ip ?? null,
          firstSeen: new Date(),
          lastSeen: new Date(),
        },
      });
    }
  });
}
