import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { Role } from "@/prisma/generated/prisma/client";

export async function PUT(
  request: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await auth();

    if (!session?.user || session.user.role !== Role.ADMIN) {
      return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
    }

    const { id } = await params;
    const body = await request.json();
    const { hpDelta, xpDelta, score, level, role } = body;

    // Récupérer l'utilisateur actuel
    const user = await prisma.user.findUnique({
      where: { id },
    });

    if (!user) {
      return NextResponse.json(
        { error: "Utilisateur non trouvé" },
        { status: 404 }
      );
    }

    // Calculer les nouvelles valeurs
    let newHp = user.hp;
    let newXp = user.xp;
    let newLevel = user.level;
    let newMaxXp = user.maxXp;

    // Appliquer les changements de HP
    if (hpDelta !== undefined) {
      newHp = Math.max(0, Math.min(user.maxHp, user.hp + hpDelta));
    }

    // Appliquer les changements de XP
    if (xpDelta !== undefined) {
      newXp = user.xp + xpDelta;
      newLevel = user.level;
      newMaxXp = user.maxXp;

      // Gérer le niveau up si nécessaire (quand on ajoute de l'XP)
      if (newXp >= newMaxXp && newXp > 0) {
        while (newXp >= newMaxXp) {
          newXp -= newMaxXp;
          newLevel += 1;
          // Augmenter le maxXp pour le prochain niveau (formule simple)
          newMaxXp = Math.floor(newMaxXp * 1.2);
        }
      }

      // Gérer le niveau down si nécessaire (quand on enlève de l'XP)
      if (newXp < 0 && newLevel > 1) {
        while (newXp < 0 && newLevel > 1) {
          newLevel -= 1;
          // Calculer le maxXp du niveau précédent
          newMaxXp = Math.floor(newMaxXp / 1.2);
          newXp += newMaxXp;
        }
        // S'assurer que l'XP ne peut pas être négative
        newXp = Math.max(0, newXp);
      }

      // S'assurer que le niveau minimum est 1
      if (newLevel < 1) {
        newLevel = 1;
        newXp = 0;
      }
    }

    // Appliquer les changements directs (score, level, role)
    const updateData: {
      hp: number;
      xp: number;
      level: number;
      maxXp: number;
      score?: number;
      role?: Role;
    } = {
      hp: newHp,
      xp: newXp,
      level: newLevel,
      maxXp: newMaxXp,
    };

    if (score !== undefined) {
      updateData.score = Math.max(0, score);
    }

    if (level !== undefined) {
      // Si le niveau est modifié directement, utiliser cette valeur
      const targetLevel = Math.max(1, level);
      updateData.level = targetLevel;
      
      // Recalculer le maxXp pour le nouveau niveau
      // Formule: maxXp = 5000 * (1.2 ^ (level - 1))
      let calculatedMaxXp = 5000;
      for (let i = 1; i < targetLevel; i++) {
        calculatedMaxXp = Math.floor(calculatedMaxXp * 1.2);
      }
      updateData.maxXp = calculatedMaxXp;
      
      // Réinitialiser l'XP si le niveau change directement (sauf si on modifie aussi l'XP)
      if (targetLevel !== user.level && xpDelta === undefined) {
        updateData.xp = 0;
      }
    }

    if (role !== undefined) {
      if (role === "ADMIN" || role === "USER") {
        updateData.role = role as Role;
      }
    }

    // Mettre à jour l'utilisateur
    const updatedUser = await prisma.user.update({
      where: { id },
      data: updateData,
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        score: true,
        level: true,
        hp: true,
        maxHp: true,
        xp: true,
        maxXp: true,
        avatar: true,
      },
    });

    return NextResponse.json(updatedUser);
  } catch (error) {
    console.error("Error updating user:", error);
    return NextResponse.json(
      { error: "Erreur lors de la mise à jour de l'utilisateur" },
      { status: 500 }
    );
  }
}

