const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const multer = require("multer");

const {
  privateUploadDirectory
} = require(
  "../config/storage"
);

const maximumFileSize =
  (
    Number(
      process.env.MAX_FILE_SIZE_MB
    ) || 10
  ) *
  1024 *
  1024;

const extensionByMimeType = {
  "application/pdf": ".pdf",
  "image/jpeg": ".jpg",
  "image/png": ".png"
};

const allowedMimeTypes =
  new Set(
    Object.keys(
      extensionByMimeType
    )
  );

const storage =
  multer.diskStorage({
    destination: (
      request,
      file,
      callback
    ) => {
      const submissionId =
        request.staffSubmission
          ?.submission_id;

      if (!submissionId) {
        return callback(
          new Error(
            "A valid submission session is required before uploading a document."
          )
        );
      }

      const submissionDirectory =
        path.join(
          privateUploadDirectory,
          `submission_${submissionId}`
        );

      try {
        fs.mkdirSync(
          submissionDirectory,
          {
            recursive: true
          }
        );

        return callback(
          null,
          submissionDirectory
        );
      } catch (error) {
        return callback(error);
      }
    },

    filename: (
      request,
      file,
      callback
    ) => {
      const extension =
        extensionByMimeType[
          file.mimetype
        ];

      const generatedFileName =
        `${Date.now()}-${crypto.randomUUID()}${extension}`;

      return callback(
        null,
        generatedFileName
      );
    }
  });

const documentUpload =
  multer({
    storage,

    limits: {
      fileSize:
        maximumFileSize,

      files: 1
    },

    fileFilter: (
      request,
      file,
      callback
    ) => {
      if (
        !allowedMimeTypes.has(
          file.mimetype
        )
      ) {
        return callback(
          new Error(
            "Only PDF, JPG, JPEG and PNG files are permitted."
          )
        );
      }

      return callback(
        null,
        true
      );
    }
  });

const uploadSingleDocument = (
  request,
  response,
  next
) => {
  documentUpload.single(
    "document"
  )(
    request,
    response,
    (error) => {
      if (!error) {
        return next();
      }

      if (
        error instanceof
          multer.MulterError &&
        error.code ===
          "LIMIT_FILE_SIZE"
      ) {
        return response.status(413).json({
          success: false,

          message:
            `The selected file exceeds the ${
              Number(
                process.env
                  .MAX_FILE_SIZE_MB
              ) || 10
            } MB limit.`,

          errors: {
            document:
              "Select a smaller file."
          }
        });
      }

      console.error(
        "Document upload middleware error:",
        error
      );

      return response.status(400).json({
        success: false,

        message:
          error.message ||
          "The document could not be uploaded.",

        errors: {
          document:
            error.message ||
            "Select a valid document."
        }
      });
    }
  );
};

module.exports = {
  uploadSingleDocument
};