"use server";

import { revalidatePath } from "next/cache";
import { hasPermission } from "@/lib/adminAuth";
import { connectDB } from "@/lib/db";
import { Testimonial } from "@/models/Testimonial";
import { saveTestimonialImage, deletePublicUploadImage } from "@/lib/uploads";

const TESTIMONIALS_ADMIN_PATH = "/de/admin/testimonials";

type FormState = { error?: string };

export async function createTestimonialAction(_prev: FormState, formData: FormData): Promise<FormState> {
  if (!(await hasPermission("testimonials_create"))) return { error: "Keine Berechtigung." };
  const authorName = String(formData.get("authorName") || "").trim();
  const quote = String(formData.get("quote") || "").trim();
  if (!authorName) return { error: "Bitte einen Namen eingeben." };
  if (!quote) return { error: "Bitte ein Zitat eingeben." };

  const source = formData.get("source") === "google" ? "google" : "manual";
  const rating = source === "google" ? Math.min(5, Math.max(0, Number(formData.get("rating")) || 0)) : 0;
  if (source === "google" && (rating < 1 || rating > 5)) return { error: "Bitte eine Sternebewertung von 1 bis 5 wählen." };

  let imagePath = "";
  const image = formData.get("image");
  if (image instanceof File && image.size > 0) {
    try {
      imagePath = await saveTestimonialImage(image);
    } catch (err) {
      return { error: err instanceof Error ? err.message : "Bild konnte nicht gespeichert werden." };
    }
  }

  await connectDB();
  await Testimonial.create({
    authorName,
    realName: String(formData.get("realName") || "").trim(),
    quote,
    quoteEn: String(formData.get("quoteEn") || "").trim(),
    context: String(formData.get("context") || "").trim(),
    contextEn: String(formData.get("contextEn") || "").trim(),
    imagePath,
    source,
    rating,
    reviewUrl: source === "google" ? String(formData.get("reviewUrl") || "").trim() : "",
    visible: formData.get("visible") === "on",
    sortOrder: Date.now(),
  });

  revalidatePath(TESTIMONIALS_ADMIN_PATH);
  revalidatePath("/de");
  revalidatePath("/en");
  return {};
}

export async function updateTestimonialAction(itemId: string, formData: FormData) {
  if (!(await hasPermission("testimonials_edit"))) return;
  const authorName = String(formData.get("authorName") || "").trim();
  const quote = String(formData.get("quote") || "").trim();
  if (!authorName || !quote) return;

  await connectDB();
  const existing = await Testimonial.findById(itemId).select("source imagePath").lean();
  if (!existing) return;

  // "visible" bewusst nicht Teil dieses Formulars — Sichtbarkeit läuft über
  // den separaten Schalter in der Zeilen-Übersicht (setTestimonialVisibleAction),
  // sonst würde jedes Speichern hier den Status unbeabsichtigt zurücksetzen.
  // "source" ist nach der Anlage nicht mehr änderbar — rating/reviewUrl daher
  // nur aktualisieren, wenn der bestehende Eintrag tatsächlich eine
  // Google-Bewertung ist (das Bearbeiten-Formular zeigt diese Felder sonst
  // gar nicht an).
  const update: Record<string, unknown> = {
    authorName,
    realName: String(formData.get("realName") || "").trim(),
    quote,
    quoteEn: String(formData.get("quoteEn") || "").trim(),
    context: String(formData.get("context") || "").trim(),
    contextEn: String(formData.get("contextEn") || "").trim(),
  };

  if (existing.source === "google") {
    const rating = Math.min(5, Math.max(1, Number(formData.get("rating")) || 1));
    update.rating = rating;
    update.reviewUrl = String(formData.get("reviewUrl") || "").trim();
  }

  const image = formData.get("image");
  if (image instanceof File && image.size > 0) {
    update.imagePath = await saveTestimonialImage(image);
    if (existing.imagePath) await deletePublicUploadImage(existing.imagePath);
  }

  await Testimonial.findByIdAndUpdate(itemId, update);

  revalidatePath(TESTIMONIALS_ADMIN_PATH);
  revalidatePath("/de");
  revalidatePath("/en");
}

export async function setTestimonialVisibleAction(itemId: string, visible: boolean) {
  if (!(await hasPermission("testimonials_edit"))) return;
  await connectDB();
  await Testimonial.findByIdAndUpdate(itemId, { visible });
  revalidatePath(TESTIMONIALS_ADMIN_PATH);
  revalidatePath("/de");
  revalidatePath("/en");
}

export async function moveTestimonialAction(itemId: string, direction: "up" | "down") {
  if (!(await hasPermission("testimonials_edit"))) return;
  await connectDB();
  const item = await Testimonial.findById(itemId).lean();
  if (!item) return;

  const neighbor = await Testimonial.findOne(
    direction === "up" ? { sortOrder: { $lt: item.sortOrder } } : { sortOrder: { $gt: item.sortOrder } }
  )
    .sort({ sortOrder: direction === "up" ? -1 : 1 })
    .lean();
  if (!neighbor) return;

  await Promise.all([
    Testimonial.findByIdAndUpdate(item._id, { sortOrder: neighbor.sortOrder }),
    Testimonial.findByIdAndUpdate(neighbor._id, { sortOrder: item.sortOrder }),
  ]);
  revalidatePath(TESTIMONIALS_ADMIN_PATH);
  revalidatePath("/de");
  revalidatePath("/en");
}

export async function deleteTestimonialAction(itemId: string) {
  if (!(await hasPermission("testimonials_delete"))) return;
  await connectDB();
  const item = await Testimonial.findByIdAndDelete(itemId).select("imagePath").lean();
  if (item?.imagePath) await deletePublicUploadImage(item.imagePath);
  revalidatePath(TESTIMONIALS_ADMIN_PATH);
  revalidatePath("/de");
  revalidatePath("/en");
}
