"use server";

import { unlink } from "fs/promises";
import { revalidatePath } from "next/cache";
import { isAdminSession, hasPermission } from "@/lib/adminAuth";
import { getSessionClientId } from "@/lib/auth";
import { connectDB } from "@/lib/db";
import { QmSubmission, QM_STATUSES, QM_TARGETS, type QmStatus, type QmTarget } from "@/models/QmSubmission";
import { saveQmAttachment, qmAttachmentUploadPath } from "@/lib/uploads";
import { notifyStaffWithPermission } from "@/lib/notifications";

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

// Jeder Mitarbeiter darf einreichen (nicht nur wer die "qm"- oder
// "hr"-Berechtigung hat) — das Prüfen/Freigeben ist der Teil, der
// eingeschränkt ist. Ziel (QM oder Personalabteilung) wählt der/die
// Mitarbeiter/in selbst beim Einreichen.
export async function createQmSubmissionAction(_prev: FormState, formData: FormData): Promise<FormState> {
  if (!(await isAdminSession())) return { error: "Nicht eingeloggt." };
  const submittedBy = await getSessionClientId();
  if (!submittedBy) return { error: "Nicht eingeloggt." };

  const title = String(formData.get("title") || "").trim();
  const description = String(formData.get("description") || "").trim();
  const targetRaw = String(formData.get("target") || "qm");
  const target = (QM_TARGETS.includes(targetRaw as QmTarget) ? targetRaw : "qm") as QmTarget;
  // Anonym nur bei "hr" wirksam — bei QM-Vorgängen ist Nachvollziehbarkeit
  // (z. B. für Rückfragen zu einem Vorfall) wichtiger als Anonymität.
  const anonymous = target === "hr" && formData.get("anonymous") === "on";
  if (!title) return { error: "Bitte einen Titel eingeben." };

  await connectDB();
  const submission = await QmSubmission.create({ title, description, target, submittedBy, anonymous });

  const file = formData.get("attachment");
  if (file instanceof File && file.size > 0) {
    try {
      const { storedName } = await saveQmAttachment(String(submission._id), file);
      submission.attachmentFilename = file.name.slice(0, 200);
      submission.attachmentStoredName = storedName;
      await submission.save();
    } catch (err) {
      return { error: err instanceof Error ? err.message : "Upload fehlgeschlagen." };
    }
  }

  await notifyStaffWithPermission(target, {
    type: "qm_submission",
    title: target === "hr" ? "Neues Personal-Anliegen" : "Neuer QM-Vorgang",
    body: title,
    link: "/de/admin/qm",
  });

  revalidatePath("/de/account/qm");
  revalidatePath("/de/admin/qm");
  return { success: true };
}

export async function reviewQmSubmissionAction(submissionId: string, status: QmStatus, note: string) {
  if (!QM_STATUSES.includes(status)) return;
  await connectDB();
  const submission = await QmSubmission.findById(submissionId).select("target").lean();
  if (!submission) return;
  if (!(await hasPermission(submission.target))) return;
  const reviewedBy = await getSessionClientId();

  await QmSubmission.findByIdAndUpdate(submissionId, {
    status,
    reviewNote: note.trim(),
    reviewedBy,
    reviewedAt: new Date(),
  });
  revalidatePath("/de/admin/qm");
  revalidatePath("/de/account/qm");
}

export async function deleteQmSubmissionAction(submissionId: string) {
  await connectDB();
  const submission = await QmSubmission.findById(submissionId);
  if (!submission) return;
  if (!(await hasPermission(submission.target))) return;
  if (submission.attachmentStoredName) {
    try {
      await unlink(qmAttachmentUploadPath(String(submission._id), submission.attachmentStoredName));
    } catch {
      // Datei war schon weg — nicht schlimm.
    }
  }
  await submission.deleteOne();
  revalidatePath("/de/admin/qm");
  revalidatePath("/de/account/qm");
}
