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 { MinioImageSchema } from "../minio/schema";
import { AlbumSchema } from "./schema";

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

export async function getAlbums(req: FastifyRequest, reply: FastifyReply) {
  const albums = await prisma.album.findMany({
    orderBy: {
      date: "desc",
    },
    select: {
      id: true,
      title: true,
      date: true,
    },
  });

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

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

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

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

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

  const presignedImages = await Promise.all(
    album.images.map(async (image) => await getPresignedUrl(image))
  );

  const finalAlbum = {
    ...album,
    presignedImages: presignedImages,
  };

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

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

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

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

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

  const album = await prisma.album.create({
    data: {
      title: data.title,
      date: data.date,
      images: data.images,
    },
  });
  return reply.code(200).send(album);
}
// ------------------------------------------------------------------------------------

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

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

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

  const newAlbum = await prisma.album.update({
    where: { id: id },
    data: {
      title: data.title,
      date: data.date,
      images: data.images,
    },
  });
  return reply.code(200).send(newAlbum);
}

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

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

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

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

  await Promise.all(
    album.images.map(
      async (image) => await minioClient.removeObject(bucketName, image)
    )
  );

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

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

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