import { mkdir, readFile, writeFile } from "fs/promises";
import path from "path";
import { configDirectory } from "@/lib/runtime/config";
import type { SmtpSettings } from "@/lib/admin/types";
import type { PublicSmtpSettings } from "./types";

const smtpConfigFile = path.join(configDirectory, "smtp.json");

const defaultSmtpSettings: SmtpSettings = {
  host: "",
  port: "587",
  username: "",
  password: "",
  security: "starttls",
  fromAddress: "",
  replyToAddress: "",
  recipientAddress: "",
  bccAddress: "",
};

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

function normalizeSecurity(value: string): SmtpSettings["security"] {
  if (value === "tls" || value === "none") return value;
  return "starttls";
}

async function ensureConfigDirectory() {
  await mkdir(configDirectory, { recursive: true });
}

export async function getSmtpSettings(): Promise<SmtpSettings> {
  await ensureConfigDirectory();
  try {
    const file = await readFile(smtpConfigFile, "utf8");
    return { ...defaultSmtpSettings, ...JSON.parse(file) as SmtpSettings };
  } catch {
    return defaultSmtpSettings;
  }
}

export function toPublicSmtpSettings(settings: SmtpSettings): PublicSmtpSettings {
  return {
    host: settings.host,
    port: settings.port,
    username: settings.username,
    security: settings.security,
    fromAddress: settings.fromAddress,
    replyToAddress: settings.replyToAddress,
    recipientAddress: settings.recipientAddress,
    bccAddress: settings.bccAddress,
    lastTestAt: settings.lastTestAt,
    lastTestStatus: settings.lastTestStatus,
    lastError: settings.lastError,
    hasPassword: Boolean(settings.password),
  };
}

export function isSmtpConfigured(settings: SmtpSettings) {
  return Boolean(
    settings.host &&
    settings.port &&
    settings.username &&
    settings.password &&
    settings.fromAddress &&
    settings.recipientAddress,
  );
}

export async function saveSmtpSettings(form: FormData) {
  const current = await getSmtpSettings();
  const nextPassword = text(form.get("password"));
  const settings: SmtpSettings = {
    ...current,
    host: text(form.get("host")),
    port: text(form.get("port")) || "587",
    username: text(form.get("username")),
    password: nextPassword || current.password || "",
    security: normalizeSecurity(text(form.get("security"))),
    fromAddress: text(form.get("fromAddress")),
    replyToAddress: text(form.get("replyToAddress")),
    recipientAddress: text(form.get("recipientAddress")),
    bccAddress: text(form.get("bccAddress")),
  };

  await ensureConfigDirectory();
  await writeFile(smtpConfigFile, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
  return settings;
}

export async function updateSmtpTestStatus(status: Pick<SmtpSettings, "lastTestAt" | "lastTestStatus" | "lastError">) {
  const current = await getSmtpSettings();
  const settings: SmtpSettings = { ...current, ...status };
  await ensureConfigDirectory();
  await writeFile(smtpConfigFile, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
  return settings;
}

export async function updateSmtpDeliveryStatus(status: Pick<SmtpSettings, "lastDeliveryAt" | "lastDeliveryStatus" | "lastError">) {
  const current = await getSmtpSettings();
  const settings: SmtpSettings = { ...current, ...status };
  await ensureConfigDirectory();
  await writeFile(smtpConfigFile, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
  return settings;
}

export { smtpConfigFile };
