"use server";

import { z } from "zod";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { auth } from "@/auth";

const userCreateSchema = z.object({
  nom: z.string().min(1, "Nom requis"),
  email: z.string().email("Email invalide"),
  password: z.string().min(6, "6 caractères minimum"),
  role: z.enum(["ADMIN", "MANAGER", "RECEPTIONIST"]),
});

const userUpdateSchema = z.object({
  nom: z.string().min(1, "Nom requis"),
  email: z.string().email("Email invalide"),
  role: z.enum(["ADMIN", "MANAGER", "RECEPTIONIST"]),
  actif: z.coerce.boolean(),
});

export async function createUser(formData: FormData) {
  const session = await auth();
  if (!session || session.user.role !== "ADMIN") return { error: "Accès refusé" };

  const raw = Object.fromEntries(formData.entries());
  const parsed = userCreateSchema.safeParse(raw);
  if (!parsed.success) return { error: parsed.error.issues[0].message };

  const existing = await prisma.user.findUnique({
    where: { email: parsed.data.email.toLowerCase() },
  });
  if (existing) return { error: "Cet email est déjà utilisé" };

  await prisma.user.create({
    data: {
      nom: parsed.data.nom,
      email: parsed.data.email.toLowerCase(),
      password: await bcrypt.hash(parsed.data.password, 10),
      role: parsed.data.role,
    },
  });

  revalidatePath("/utilisateurs");
  redirect("/utilisateurs");
}

export async function updateUser(id: string, formData: FormData) {
  const session = await auth();
  if (!session || session.user.role !== "ADMIN") return { error: "Accès refusé" };

  const raw = Object.fromEntries(formData.entries());
  // Pour les checkboxes, FormData.entries() ne renvoie la clé que si cochée
  if (!raw.actif) raw.actif = "false";

  const parsed = userUpdateSchema.safeParse(raw);
  if (!parsed.success) return { error: parsed.error.issues[0].message };

  // Empêcher de désactiver le seul admin
  if (!parsed.data.actif || parsed.data.role !== "ADMIN") {
    const otherActiveAdmins = await prisma.user.count({
      where: {
        role: "ADMIN",
        actif: true,
        NOT: { id },
      },
    });
    const current = await prisma.user.findUnique({ where: { id } });
    if (current?.role === "ADMIN" && otherActiveAdmins === 0) {
      return { error: "Vous ne pouvez pas désactiver le dernier administrateur actif" };
    }
  }

  await prisma.user.update({
    where: { id },
    data: {
      nom: parsed.data.nom,
      email: parsed.data.email.toLowerCase(),
      role: parsed.data.role,
      actif: parsed.data.actif,
    },
  });

  revalidatePath("/utilisateurs");
  revalidatePath(`/utilisateurs/${id}`);
  redirect("/utilisateurs");
}

export async function deleteUser(id: string) {
  const session = await auth();
  if (!session || session.user.role !== "ADMIN") return { error: "Accès refusé" };

  if (session.user.id === id) {
    return { error: "Vous ne pouvez pas supprimer votre propre compte" };
  }

  const user = await prisma.user.findUnique({ where: { id } });
  if (!user) return { error: "Utilisateur introuvable" };

  if (user.role === "ADMIN") {
    const admins = await prisma.user.count({
      where: { role: "ADMIN", NOT: { id } },
    });
    if (admins === 0) return { error: "Impossible de supprimer le dernier administrateur" };
  }

  await prisma.user.delete({ where: { id } });
  revalidatePath("/utilisateurs");
  return { success: true };
}

const passwordChangeSchema = z.object({
  oldPassword: z.string().min(1, "Ancien mot de passe requis"),
  newPassword: z.string().min(6, "6 caractères minimum"),
  confirmPassword: z.string(),
}).refine((d) => d.newPassword === d.confirmPassword, {
  message: "Les mots de passe ne correspondent pas",
  path: ["confirmPassword"],
});

export async function changeMyPassword(formData: FormData) {
  const session = await auth();
  if (!session) return { error: "Non authentifié" };

  const raw = Object.fromEntries(formData.entries());
  const parsed = passwordChangeSchema.safeParse(raw);
  if (!parsed.success) return { error: parsed.error.issues[0].message };

  const user = await prisma.user.findUnique({ where: { id: session.user.id } });
  if (!user) return { error: "Utilisateur introuvable" };

  const ok = await bcrypt.compare(parsed.data.oldPassword, user.password);
  if (!ok) return { error: "Ancien mot de passe incorrect" };

  await prisma.user.update({
    where: { id: user.id },
    data: { password: await bcrypt.hash(parsed.data.newPassword, 10) },
  });

  return { success: true };
}
