"use server";

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { isRedirectError } from "next/dist/client/components/redirect-error";

import { getAdminAppPath, toInternalAdminPath } from "@/lib/admin-routing";
import { clearAdminSessionCookie, isAdminAuthenticated } from "@/lib/admin-auth";
import { isCheckedFormValue } from "@/lib/form-data";
import {
  getMailSettings,
  updateMailSettings,
} from "@/lib/app-config";
import { sendTestEmail } from "@/lib/mail";
import type { MailSettings } from "@/lib/mail-settings";

async function ensureAdmin() {
  if (!(await isAdminAuthenticated())) {
    await clearAdminSessionCookie();
    redirect(getAdminAppPath("/"));
  }
}

function withMessage(pathname: string, type: "success" | "error", message: string) {
  const params = new URLSearchParams();
  params.set(type, message);

  return `${pathname}?${params.toString()}`;
}

function parsePort(value: string) {
  const port = Number.parseInt(value, 10);

  if (!Number.isInteger(port) || port <= 0) {
    throw new Error("SMTP port must be a positive number.");
  }

  return port;
}

function parseMailSettingsFormData(
  formData: FormData,
  existingSettings: MailSettings,
): MailSettings {
  const host = String(formData.get("smtpHost") ?? "").trim();
  const portValue = String(formData.get("smtpPort") ?? "").trim();
  const username = String(formData.get("smtpUsername") ?? "").trim();
  const password = String(formData.get("smtpPassword") ?? "");
  const fromEmail = String(formData.get("mailFromEmail") ?? "").trim();
  const fromName = String(formData.get("mailFromName") ?? "").trim();
  const contactRecipient = String(formData.get("mailContactRecipient") ?? "").trim();
  const testRecipient = String(formData.get("mailTestRecipient") ?? "").trim();

  return {
    smtp: {
      host,
      port: parsePort(portValue || String(existingSettings.smtp.port)),
      secure: isCheckedFormValue(formData.get("smtpSecure")),
      username,
      password: password.trim() ? password : existingSettings.smtp.password,
    },
    sender: {
      email: fromEmail,
      name: fromName,
    },
    recipients: {
      contact: contactRecipient,
      test: testRecipient,
    },
  };
}

export async function saveMailSettingsAction(formData: FormData) {
  await ensureAdmin();

  try {
    const existingMailSettings = await getMailSettings();
    const nextMailSettings = parseMailSettingsFormData(formData, existingMailSettings);

    await updateMailSettings(nextMailSettings);
    revalidatePath(toInternalAdminPath("/smtp"));
    redirect(withMessage(getAdminAppPath("/smtp"), "success", "SMTP Einstellungen gespeichert."));
  } catch (error) {
    if (isRedirectError(error)) {
      throw error;
    }

    const message =
      error instanceof Error
        ? error.message
        : "SMTP Einstellungen konnten nicht gespeichert werden.";

    redirect(withMessage(getAdminAppPath("/smtp"), "error", message));
  }
}

export async function sendTestEmailAction() {
  await ensureAdmin();

  try {
    await sendTestEmail();
    redirect(withMessage(getAdminAppPath("/smtp"), "success", "Test-E-Mail gesendet."));
  } catch (error) {
    if (isRedirectError(error)) {
      throw error;
    }

    const message =
      error instanceof Error
        ? error.message
        : "Test-E-Mail konnte nicht gesendet werden.";

    redirect(withMessage(getAdminAppPath("/smtp"), "error", message));
  }
}
