import { FastifyReply, FastifyRequest } from "fastify";
import prisma from "../../utils/prisma";
import { $Enums } from "@prisma/client";
import { PasswordSchema, ProfileSchema } from "./schema";
import * as bcrypt from "bcrypt";
import { SALT_ROUNDS } from "../../utils/consts";

export async function currentUser(req: FastifyRequest, reply: FastifyReply) {
  const userId = req.user.id;
  const fullUser = await prisma.user.findUnique({
    where: { id: userId, active: true },
    include: {
      company: {
        include: {
          city: true,
          contactPosition: true,
          nEmployees: true,
          turnover: true,
        },
      },
      position: true,
      city: true,
    },
  });

  if (!fullUser || (fullUser.company && !fullUser.company.active)) {
    return reply.code(401).send({
      message: "Cet utilisateur n'existe pas",
    });
  }

  if (fullUser.role === $Enums.Role.User) {
    return reply.code(401).send({
      message: "Vous n'êtes pas un admin",
    });
  }

  await prisma.user.update({
    where: { id: userId },
    data: { loggedInAt: new Date() },
  });

  const { password, ...user } = fullUser;

  return reply.code(200).send(user);
}

//------------------------------------------------------------------------------------

export async function editProfile(
  req: FastifyRequest<{ Body: ProfileSchema }>,
  reply: FastifyReply
) {
  const userId = req.user.id;
  const user = await prisma.user.findUnique({
    where: { id: userId, active: true },
  });

  if (!user) {
    return reply.code(404).send({
      message: "Cet utilisateur n'existe pas",
    });
  }

  const data = req.body;

  const position = await prisma.position.findUnique({
    where: {
      id: data.positionId,
    },
  });

  if (!position) {
    return reply.code(400).send({
      message: "La fonction n'existe pas",
    });
  }

  const newUserFull = await prisma.user.update({
    where: { id: userId },
    data: {
      civility: data.civility,
      firstName: data.firstName,
      lastName: data.lastName,
      positionId: data.positionId,
      phoneNumber: data.phoneNumber,
    },
  });

  const { password, ...newUser } = newUserFull;
  return reply.code(200).send(newUser);
}

//------------------------------------------------------------------------------------

export async function editPassword(
  req: FastifyRequest<{ Body: PasswordSchema }>,
  reply: FastifyReply
) {
  const userId = req.user.id;
  const user = await prisma.user.findUnique({
    where: { id: userId, active: true },
  });

  if (!user) {
    return reply.code(404).send({
      message: "Cet utilisateur n'existe pas",
    });
  }

  const data = req.body;

  const isMatch = await bcrypt.compare(data.old_password, user.password);

  if (!isMatch) {
    return reply.code(400).send({
      message: "L'ancien mot de passe est incorrect",
    });
  }

  const hash = await bcrypt.hash(data.new_password, SALT_ROUNDS);

  await prisma.user.update({
    where: { id: userId },
    data: {
      password: hash,
    },
  });

  return reply.code(200).send({});
}

//------------------------------------------------------------------------------------
