"use server";

import { revalidatePath } from "next/cache";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/lib/db/client";
import { emailTemplates } from "@/lib/db/schema";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { logAdminAction } from "@/lib/audit";
import { clearTemplateCache, defaultsFor } from "@/lib/email/templates-db";
import { sendTemplatedEmail } from "@/lib/email/send";

const updateSchema = z.object({
  slug: z.string().min(1).max(100),
  name: z.string().min(1).max(200),
  description: z.string().max(500).optional(),
  subject: z.string().min(1).max(300),
  body: z.string().min(1).max(20_000),
});

export async function saveTemplate(formData: FormData) {
  const session = await requireAdmin();
  const adminId = (session.user as { id?: string }).id!;
  const parsed = updateSchema.parse({
    slug: formData.get("slug"),
    name: formData.get("name"),
    description: formData.get("description") ?? "",
    subject: formData.get("subject"),
    body: formData.get("body"),
  });

  const def = defaultsFor(parsed.slug);
  const variables = def?.variables ?? [];

  await db
    .insert(emailTemplates)
    .values({
      slug: parsed.slug,
      name: parsed.name,
      description: parsed.description ?? "",
      subject: parsed.subject,
      body: parsed.body,
      variables,
      updatedBy: adminId,
      updatedAt: new Date(),
    })
    .onConflictDoUpdate({
      target: emailTemplates.slug,
      set: {
        name: parsed.name,
        description: parsed.description ?? "",
        subject: parsed.subject,
        body: parsed.body,
        variables,
        updatedBy: adminId,
        updatedAt: new Date(),
      },
    });

  clearTemplateCache(parsed.slug);
  await logAdminAction({
    adminUserId: adminId,
    action: "email_template_update",
    metadata: { slug: parsed.slug },
  });
  revalidatePath("/admin/email-templates");
  revalidatePath(`/admin/email-templates/${parsed.slug}`);
}

export async function resetTemplateToDefault(formData: FormData) {
  const session = await requireAdmin();
  const adminId = (session.user as { id?: string }).id!;
  const slug = String(formData.get("slug") ?? "");
  const def = defaultsFor(slug);
  if (!def) throw new Error(`No default exists for ${slug}`);
  await db.delete(emailTemplates).where(eq(emailTemplates.slug, slug));
  clearTemplateCache(slug);
  await logAdminAction({
    adminUserId: adminId,
    action: "email_template_reset",
    metadata: { slug },
  });
  revalidatePath("/admin/email-templates");
  revalidatePath(`/admin/email-templates/${slug}`);
}

const testSchema = z.object({
  slug: z.string().min(1),
  recipient: z.string().email(),
});

export async function sendTestEmail(formData: FormData) {
  const session = await requireAdmin();
  const adminId = (session.user as { id?: string }).id!;
  const parsed = testSchema.parse({
    slug: formData.get("slug"),
    recipient: formData.get("recipient"),
  });
  const def = defaultsFor(parsed.slug);
  const sampleVars: Record<string, string> = {
    applicantName: "Jane Example",
    applicantEmail: "jane@example.org",
    institution: "Example University",
    country: "United Kingdom",
    motivation: "Sample motivation text for a preview send.",
    reviewUrl: "https://example.org/review/sample",
    name: "Jane Example",
    loginUrl: "https://orthoglobe.org/login",
    resetUrl: "https://orthoglobe.org/reset-password/sample-token",
    expiresInMinutes: "60",
    adminName: "Admin",
    changedAt: new Date().toUTCString(),
    notes: "Thanks for applying. Please reapply after your residency.",
    notesBlock: "Reviewer notes:\nThanks for applying. Please reapply after your residency.\n\n",
  };
  // Only include variables this template supports, so preview never leaks
  // unrelated placeholders.
  const filtered: Record<string, string> = {};
  for (const key of def?.variables ?? []) {
    if (sampleVars[key] !== undefined) filtered[key] = sampleVars[key];
  }
  await sendTemplatedEmail({
    to: parsed.recipient,
    templateSlug: parsed.slug,
    variables: filtered,
  });
  await logAdminAction({
    adminUserId: adminId,
    action: "email_template_test",
    metadata: { slug: parsed.slug, recipient: parsed.recipient },
  });
}
