"use server";

import { revalidatePath } from "next/cache";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/lib/db/client";
import { notifications } from "@/lib/db/schema";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { logAdminAction } from "@/lib/audit";

async function ensureAdmin() {
  const session = await requireAdmin();
  return (session.user as { id?: string }).id!;
}

const levelValues = ["info", "warning", "success"] as const;

function parseOptionalDate(value: FormDataEntryValue | null): Date | null {
  if (!value || typeof value !== "string" || value.trim() === "") return null;
  const d = new Date(value);
  return isNaN(d.getTime()) ? null : d;
}

const createSchema = z.object({
  title: z.string().min(2).max(200),
  body: z.string().max(2000).optional(),
  href: z.string().max(400).optional(),
  level: z.enum(levelValues).optional(),
});

export async function createNotification(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = createSchema.parse({
    title: formData.get("title"),
    body: formData.get("body") ?? "",
    href: formData.get("href") ?? "",
    level: (formData.get("level") as string) || undefined,
  });

  const [row] = await db
    .insert(notifications)
    .values({
      title: parsed.title,
      body: parsed.body ?? "",
      href: parsed.href ? parsed.href : null,
      level: parsed.level ?? "info",
      startsAt: parseOptionalDate(formData.get("startsAt")),
      endsAt: parseOptionalDate(formData.get("endsAt")),
    })
    .returning({ id: notifications.id });

  await logAdminAction({
    adminUserId: adminId,
    action: "create_notification",
    targetId: row.id,
  });

  revalidatePath("/admin/notifications");
  revalidatePath("/");
}

const updateSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(2).max(200),
  body: z.string().max(2000),
  href: z.string().max(400),
  level: z.enum(levelValues),
  active: z.string().optional(),
});

export async function updateNotification(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = updateSchema.parse({
    id: formData.get("id"),
    title: formData.get("title") ?? "",
    body: formData.get("body") ?? "",
    href: formData.get("href") ?? "",
    level: formData.get("level") ?? "info",
    active: (formData.get("active") as string) ?? undefined,
  });

  await db
    .update(notifications)
    .set({
      title: parsed.title,
      body: parsed.body,
      href: parsed.href || null,
      level: parsed.level,
      active: parsed.active === "on",
      startsAt: parseOptionalDate(formData.get("startsAt")),
      endsAt: parseOptionalDate(formData.get("endsAt")),
      updatedAt: new Date(),
    })
    .where(eq(notifications.id, parsed.id));

  await logAdminAction({
    adminUserId: adminId,
    action: "update_notification",
    targetId: parsed.id,
  });

  revalidatePath("/admin/notifications");
  revalidatePath("/");
}

export async function deleteNotification(formData: FormData) {
  const adminId = await ensureAdmin();
  const id = z.string().uuid().parse(formData.get("id"));
  await db.delete(notifications).where(eq(notifications.id, id));
  await logAdminAction({
    adminUserId: adminId,
    action: "delete_notification",
    targetId: id,
  });
  revalidatePath("/admin/notifications");
  revalidatePath("/");
}
