"use server";

import { auth } from "@/auth";
import { db } from "@/db/client";
import { externalIds } from "@/db/schema";
import { and, eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";

/**
 * Server Actions are reachable by a direct POST, not only through the buttons
 * on the page, so the check belongs in here rather than in the layout that
 * happens to render them.
 */
async function requireAdmin() {
  const session = await auth();
  if (!session) redirect("/login");
  if (!session.user.isAdmin) redirect("/");
  return session;
}

function optionalString(value: FormDataEntryValue | null) {
  return typeof value === "string" && value.trim() ? value.trim() : null;
}

/**
 * Record a judgement on a title's TMDB link.
 *
 * The three states are mutually exclusive, so each verdict clears the other:
 * confirming a link that had been rejected has to actually un-reject it, or
 * the title stays in the rejected queue forever and the reviewer's second look
 * counts for nothing.
 *
 * `mediaItemId` rather than the external_ids row id, because the reviewer is
 * answering a question about a TITLE -- is this the right film? -- and the row
 * carrying the answer is an implementation detail they never see.
 */
async function recordVerdict(formData: FormData, verdict: "confirm" | "reject" | "reset") {
  const session = await requireAdmin();
  const mediaItemId = optionalString(formData.get("mediaItemId"));
  if (!mediaItemId) return;

  const now = new Date();
  const set =
    verdict === "confirm"
      ? { verifiedAt: now, verifiedBy: session.user.id, rejectedAt: null, rejectedBy: null }
      : verdict === "reject"
        ? { verifiedAt: null, verifiedBy: null, rejectedAt: now, rejectedBy: session.user.id }
        : { verifiedAt: null, verifiedBy: null, rejectedAt: null, rejectedBy: null };

  await db
    .update(externalIds)
    .set(set)
    .where(and(eq(externalIds.mediaItemId, mediaItemId), eq(externalIds.source, "tmdb")));

  revalidatePath("/admin/verify");
  revalidatePath("/admin/inventory");
}

export async function confirmTmdbLink(formData: FormData) {
  await recordVerdict(formData, "confirm");
}

export async function rejectTmdbLink(formData: FormData) {
  await recordVerdict(formData, "reject");
}

/** Put a title back in the queue -- for a verdict entered by mistake. */
export async function resetTmdbLink(formData: FormData) {
  await recordVerdict(formData, "reset");
}
