"use server";

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

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

const createSchema = z.object({
  source: z.string().min(1).max(400),
  destination: z.string().min(1).max(1000),
  kind: z.enum(["permanent", "temporary"]).default("permanent"),
  notes: z.string().max(500).optional(),
});

export async function createRedirect(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = createSchema.parse({
    source: formData.get("source") ?? "",
    destination: formData.get("destination") ?? "",
    kind: formData.get("kind") ?? "permanent",
    notes: formData.get("notes") ?? "",
  });
  const source = normalisePath(parsed.source);
  if (!source.startsWith("/")) throw new Error("Source must start with /");
  const dest = parsed.destination.trim();
  if (!dest) throw new Error("Destination required");

  await db
    .insert(redirects)
    .values({
      source,
      destination: dest,
      kind: parsed.kind,
      notes: parsed.notes ?? "",
      createdBy: adminId,
    })
    .onConflictDoUpdate({
      target: redirects.source,
      set: {
        destination: dest,
        kind: parsed.kind,
        notes: parsed.notes ?? "",
        active: true,
        updatedAt: new Date(),
      },
    });

  await logAdminAction({
    adminUserId: adminId,
    action: "redirect_upsert",
    metadata: { source, destination: dest, kind: parsed.kind },
  });
  invalidateRedirectCache();
  revalidatePath("/admin/redirects");
}

const toggleSchema = z.object({ id: z.string().uuid(), active: z.enum(["1", "0"]) });

export async function toggleRedirect(formData: FormData) {
  const adminId = await ensureAdmin();
  const parsed = toggleSchema.parse({
    id: formData.get("id"),
    active: formData.get("active"),
  });
  await db
    .update(redirects)
    .set({ active: parsed.active === "1", updatedAt: new Date() })
    .where(eq(redirects.id, parsed.id));
  await logAdminAction({
    adminUserId: adminId,
    action: parsed.active === "1" ? "redirect_enable" : "redirect_disable",
    targetId: parsed.id,
  });
  invalidateRedirectCache();
  revalidatePath("/admin/redirects");
}

export async function deleteRedirect(formData: FormData) {
  const adminId = await ensureAdmin();
  const id = String(formData.get("id") ?? "");
  if (!id) throw new Error("id required");
  await db.delete(redirects).where(eq(redirects.id, id));
  await logAdminAction({
    adminUserId: adminId,
    action: "redirect_delete",
    targetId: id,
  });
  invalidateRedirectCache();
  revalidatePath("/admin/redirects");
}

export async function refreshRedirectCache() {
  const adminId = await ensureAdmin();
  invalidateRedirectCache();
  await logAdminAction({
    adminUserId: adminId,
    action: "redirect_cache_refresh",
  });
  revalidatePath("/admin/redirects");
}
