import { z } from "zod";
import prisma from "@/server/db/prisma";
import { requireAdmin } from "@/server/auth/requireAdmin";
import { parseJson } from "@/server/http/parse";
import { ok } from "@/server/http/response";
import { withErrorHandling } from "@/server/http/withErrorHandling";
import { setCacheHeaders } from "@/server/http/cacheHeaders";

/** Sentinel value returned in place of the real SMTP password. */
const PASSWORD_MASK = "••••••••";

export const GET = withErrorHandling(async () => {
  const settings = await prisma.emailSettings.findFirst({
    select: {
      id: true,
      smtpHost: true,
      smtpPort: true,
      smtpUser: true,
      smtpPassword: true,
      companyEmail: true,
      companyName: true,
      confirmationTemplate: true,
      notificationTemplate: true,
    },
  });

  // Never expose the real SMTP password over the wire.
  const masked = settings
    ? { ...settings, smtpPassword: settings.smtpPassword ? PASSWORD_MASK : "" }
    : settings;

  const response = ok(masked);
  return setCacheHeaders(response, "none"); // Don't cache sensitive email settings
});

const EmailSettingsUpsertSchema = z.object({
  id: z.number().int().optional(),
  smtpHost: z.string().min(1),
  smtpPort: z.number().int(),
  smtpUser: z.string().min(1),
  smtpPassword: z.string().min(1),
  companyEmail: z.string().email(),
  companyName: z.string().min(1),
  confirmationTemplate: z.string().default(""),
  notificationTemplate: z.string().default(""),
});

export const POST = withErrorHandling(async (request: Request) => {
  await requireAdmin(request);
  const data = await parseJson(request, EmailSettingsUpsertSchema);

  // If the client sends back the mask, it means "keep the existing password".
  let smtpPassword = data.smtpPassword;
  if (smtpPassword === PASSWORD_MASK) {
    const existing = await prisma.emailSettings.findFirst({
      where: data.id ? { id: data.id } : undefined,
      select: { smtpPassword: true },
    });
    smtpPassword = existing?.smtpPassword ?? "";
  }

  const settings = await prisma.emailSettings.upsert({
    where: { id: data.id || 0 },
    update: {
      smtpHost: data.smtpHost,
      smtpPort: data.smtpPort,
      smtpUser: data.smtpUser,
      smtpPassword,
      companyEmail: data.companyEmail,
      companyName: data.companyName,
      confirmationTemplate: data.confirmationTemplate,
      notificationTemplate: data.notificationTemplate,
    },
    create: {
      smtpHost: data.smtpHost,
      smtpPort: data.smtpPort,
      smtpUser: data.smtpUser,
      smtpPassword,
      companyEmail: data.companyEmail,
      companyName: data.companyName,
      confirmationTemplate: data.confirmationTemplate,
      notificationTemplate: data.notificationTemplate,
    },
    select: {
      id: true,
      smtpHost: true,
      smtpPort: true,
      smtpUser: true,
      companyEmail: true,
      companyName: true,
      confirmationTemplate: true,
      notificationTemplate: true,
    },
  });

  // Return the masked version (never leak the password on save either).
  return ok({ ...settings, smtpPassword: PASSWORD_MASK });
});
