import { FastifyReply, FastifyRequest } from "fastify";
import { v4 as uuid } from "uuid";
import { bucketName } from "../../utils/consts";
import { getPresignedUrl, minioClient } from "../../utils/minio";
import prisma from "../../utils/prisma";
import { IdParamsSchema } from "../../utils/schema";
import { MinioDocumentSchema } from "../minio/schema";
import { TrainingSchema } from "./schema";

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

export async function getTrainings(req: FastifyRequest, reply: FastifyReply) {
  const trainings = await prisma.training.findMany({
    orderBy: {
      date: "desc",
    },
    select: {
      id: true,
      title: true,
      type: true,
      date: true,
      place: true,
    },
  });

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

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

export async function getTraining(
  req: FastifyRequest<{
    Params: IdParamsSchema;
  }>,
  reply: FastifyReply
) {
  const id = req.params.id;

  const training = await prisma.training.findUnique({
    where: {
      id: id,
    },
  });

  if (!training) {
    return reply.code(404).send({
      message: "Cette formation n'existe pas",
    });
  }

  const finalTraining = {
    ...training,
    presignedDocument: training.document
      ? await getPresignedUrl(training.document)
      : null,
  };

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

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

export async function uploadTrainingDocument(
  req: FastifyRequest<{ Body: MinioDocumentSchema }>,
  reply: FastifyReply
) {
  const data = req.body;
  const buffer = await data.document.toBuffer();
  const ext = data.document.filename.split(".").pop();
  const mimetype = data.document.mimetype;
  const fileName = "trainings/" + uuid() + "." + ext;
  await minioClient.putObject(bucketName, fileName, buffer, undefined, {
    "Content-Type": mimetype,
  });
  return reply.code(200).send({ document: fileName });
}

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

export async function createTraining(
  req: FastifyRequest<{
    Body: TrainingSchema;
  }>,
  reply: FastifyReply
) {
  const data = req.body;

  const training = await prisma.training.create({
    data: {
      title: data.title,
      place: data.place,
      date: data.date,
      email: data.email.toLowerCase(),
      phoneNumber: data.phoneNumber,
      website: data.website,
      type: data.type,
      description: data.description,
      document: data.document,
    },
    select: {
      id: true,
      title: true,
      type: true,
      date: true,
      place: true,
    },
  });
  return reply.code(200).send(training);
}
// ------------------------------------------------------------------------------------

export async function editTraining(
  req: FastifyRequest<{
    Params: IdParamsSchema;
    Body: TrainingSchema;
  }>,
  reply: FastifyReply
) {
  const id = req.params.id;
  const data = req.body;

  const training = await prisma.training.findUnique({
    where: {
      id: id,
    },
  });

  if (!training) {
    return reply.code(404).send({
      message: "Cette formation n'existe pas",
    });
  }

  const newTraining = await prisma.training.update({
    where: { id: id },
    data: {
      title: data.title,
      place: data.place,
      date: data.date,
      email: data.email.toLowerCase(),
      phoneNumber: data.phoneNumber,
      website: data.website,
      type: data.type,
      description: data.description,
      document: data.document,
    },
    select: {
      id: true,
      title: true,
      type: true,
      date: true,
      place: true,
    },
  });
  return reply.code(200).send(newTraining);
}

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

export async function deleteTraining(
  req: FastifyRequest<{
    Params: IdParamsSchema;
  }>,
  reply: FastifyReply
) {
  const id = req.params.id;

  const training = await prisma.training.findUnique({
    where: {
      id: id,
    },
  });

  if (!training) {
    return reply.code(404).send({
      message: "Cette formation n'existe pas",
    });
  }

  training.document && minioClient.removeObject(bucketName, training.document);

  await prisma.training.delete({
    where: { id: id },
  });

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

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