"use server";

import { unlink } from "fs/promises";
import { revalidatePath } from "next/cache";
import { connectDB } from "@/lib/db";
import { Client } from "@/models/Client";
import { getSessionClientId } from "@/lib/auth";
import { saveAvatar, avatarUploadPath } from "@/lib/uploads";
import { formatAddress } from "@/lib/orderConstants";

type ProfileFormState = { error?: string; success?: boolean };

export async function updateProfileAction(_prev: ProfileFormState, formData: FormData): Promise<ProfileFormState> {
  const clientId = await getSessionClientId();
  const locale = String(formData.get("locale") || "de");
  if (!clientId) return { error: locale === "en" ? "Please log in." : "Bitte logge dich ein." };

  const firstName = String(formData.get("firstName") || "").trim();
  const lastName = String(formData.get("lastName") || "").trim();
  const salutationRaw = String(formData.get("salutation") || "").trim();
  const salutation = salutationRaw === "herr" || salutationRaw === "frau" || salutationRaw === "divers" ? salutationRaw : "";
  const pronouns = salutation === "divers" ? String(formData.get("pronouns") || "").trim() : "";
  const nickname = String(formData.get("nickname") || "").trim();
  const birthDateRaw = String(formData.get("birthDate") || "");
  const phone = String(formData.get("phone") || "").trim();
  const billingStreet = String(formData.get("billingStreet") || "").trim();
  const billingPostCode = String(formData.get("billingPostCode") || "").trim();
  const billingCity = String(formData.get("billingCity") || "").trim();
  const billingCountryCode = String(formData.get("billingCountryCode") || "DE").trim();

  if (!firstName || !lastName) {
    return { error: locale === "en" ? "Please enter your first and last name." : "Bitte gib Vor- und Nachnamen ein." };
  }
  const birthDate = birthDateRaw ? new Date(birthDateRaw) : null;
  if (birthDateRaw && (Number.isNaN(birthDate!.getTime()) || birthDate!.getTime() > Date.now())) {
    return { error: locale === "en" ? "Please enter a valid date of birth." : "Bitte gib ein gültiges Geburtsdatum ein." };
  }

  await connectDB();
  const client = await Client.findById(clientId);
  if (!client) return { error: locale === "en" ? "Account not found." : "Konto nicht gefunden." };

  // Geburtsdatum, Telefonnummer & Anschrift sind seit der Registrierungspflicht
  // nur für Kundenkonten verpflichtend — Mitarbeiter-Profile (angelegt vom
  // Admin, nie durch die Registrierung gelaufen) sollen dadurch nicht
  // blockiert werden. Greift auch für Bestandskonten von vor der Pflicht,
  // sobald sie ihr Profil das nächste Mal speichern.
  if (client.role === "client") {
    if (!birthDate) {
      return { error: locale === "en" ? "Please enter your date of birth." : "Bitte gib dein Geburtsdatum ein." };
    }
    if (phone.replace(/\D/g, "").length < 5) {
      return { error: locale === "en" ? "Please enter a valid phone number." : "Bitte gib eine gültige Telefonnummer ein." };
    }
    if (!billingStreet || !billingPostCode || !billingCity) {
      return { error: locale === "en" ? "Please enter your address." : "Bitte gib deine Anschrift ein." };
    }
    if (!salutation) {
      return { error: locale === "en" ? "Please choose a salutation." : "Bitte wähle eine Anrede aus." };
    }
  }

  client.firstName = firstName;
  client.lastName = lastName;
  // Nur überschreiben, wenn im Formular ein Wert kam (Feld erscheint nur für
  // client-Rollen, siehe oben) - sonst würde ein Mitarbeiter-Speichern eine
  // vorhandene Anrede stillschweigend löschen, analog zu phone unten.
  if (salutation) {
    client.salutation = salutation;
    client.pronouns = pronouns;
  }
  client.nickname = nickname;
  client.name = `${firstName} ${lastName}`.trim();
  if (birthDate) client.birthDate = birthDate;
  // Wie bei birthDate: nur überschreiben, wenn ein Wert kam — das Feld wird
  // im Formular nur für Kundenkonten angezeigt, bei Mitarbeiter-Profilen
  // (z. B. ein zum Mitarbeiter beförderter Kunde) würde ein leerer Wert
  // sonst eine vorhandene Telefonnummer stillschweigend löschen.
  if (phone) client.phone = phone;
  client.billingStreet = billingStreet;
  client.billingPostCode = billingPostCode;
  client.billingCity = billingCity;
  client.billingCountryCode = billingCountryCode || "DE";
  // `address` ist das ältere Freitext-Feld, das PDFs/CSV-Export/Admin-Ansicht
  // weiterhin lesen — wird hier aus den strukturierten Feldern abgeleitet,
  // damit es nie wieder direkt im Formular gepflegt werden muss.
  client.address = formatAddress({
    street: billingStreet,
    postCode: billingPostCode,
    city: billingCity,
    countryCode: billingCountryCode,
  });

  const avatarFile = formData.get("avatar");
  if (avatarFile instanceof File && avatarFile.size > 0) {
    const previousAvatarPath = client.avatarPath;
    try {
      const { storedName } = await saveAvatar(clientId, avatarFile);
      client.avatarPath = storedName;
    } catch (err) {
      return { error: err instanceof Error ? err.message : "Bild-Upload fehlgeschlagen." };
    }
    // Jeder Upload bekommt einen neuen zufälligen Dateinamen (siehe
    // lib/uploads.ts saveAvatar) statt das alte Bild zu überschreiben —
    // ohne diesen Schritt bliebe das vorherige Avatarbild für immer
    // verwaist auf der Platte liegen.
    if (previousAvatarPath) {
      try {
        await unlink(avatarUploadPath(clientId, previousAvatarPath));
      } catch {
        // Datei war schon weg — nicht schlimm.
      }
    }
  }

  await client.save();
  revalidatePath("/[locale]/account", "page");
  revalidatePath("/[locale]/account/profile", "page");
  revalidatePath("/de/admin/orders");
  return { success: true };
}

export async function deleteAvatarAction() {
  const clientId = await getSessionClientId();
  if (!clientId) return;

  await connectDB();
  const client = await Client.findById(clientId);
  if (!client || !client.avatarPath) return;

  try {
    await unlink(avatarUploadPath(clientId, client.avatarPath));
  } catch {
    // Datei war schon weg — nicht schlimm, DB-Feld trotzdem leeren.
  }
  client.avatarPath = "";
  await client.save();

  revalidatePath("/[locale]/account", "page");
  revalidatePath("/[locale]/account/profile", "page");
  revalidatePath("/de/admin/orders");
}

// Blendet den "Anrede nachtragen?"-Hinweis auf dem Konto-Dashboard dauerhaft
// aus, OHNE salutation selbst zu setzen - ausdrücklich nicht erzwungen für
// Bestandskonten (siehe Client.ts salutationPromptDismissedAt).
export async function dismissSalutationPromptAction() {
  const clientId = await getSessionClientId();
  if (!clientId) return;

  await connectDB();
  await Client.findByIdAndUpdate(clientId, { salutationPromptDismissedAt: new Date() });
  revalidatePath("/[locale]/account", "page");
}

// Blendet das "Quick Tips"-Ersteinrichtungs-Modal dauerhaft aus (Onboarding-
// System, 25.09.2026), gleiches Muster wie dismissSalutationPromptAction.
export async function dismissOnboardingTipsAction() {
  const clientId = await getSessionClientId();
  if (!clientId) return;

  await connectDB();
  await Client.findByIdAndUpdate(clientId, { onboardingTipsSeenAt: new Date() });
  revalidatePath("/[locale]/account", "page");
}
