import multer from "multer";
import path from "path";

import CustomRequest from "../types/requestType";
import { NextFunction, Response } from "express";
import log from "../config/log";

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "./uploads/tmp/");
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
    const fileExtension = file.mimetype.split("/")[1];
    //cb(null, `image-${uniqueSuffix}.${file.mimetype.replace("image/", "")}`);
    cb(null, `image-${uniqueSuffix}.${fileExtension}`);
  },
});

// export const fileFilter = (req: any, file: any, cb: any) => {
//   //const allowedTypes = /jpeg|jpg|png|webp|gif|pdf/;
//   const allowedTypes = /jpeg|jpg|png|webp|gif|pdf|heic|heif/;
//   const extname = allowedTypes.test(
//     path.extname(file.originalname).toLowerCase()
//   );
//   const mimetype = allowedTypes.test(file.mimetype);
//   const ext = path.extname(file.originalname).toLowerCase();

//   if (extname && mimetype) {
//     return cb(null, true);
//   } else {
//      log.info(`[Middleware], [Upload Error], originalName [${file.originalname}], extension [${ext}], mimeType [${file.mimetype}], fieldName: [${file.fieldname}], EndPoint [${req.originalUrl}], Only Images and PDFs files are allowed`);
//     cb(new Error("Only Images and PDFs files are allowed"));
//   }
// };

export const fileFilter = (req: any, file: any, cb: any) => {
  const allowedExtensions = [
    ".jpeg",
    ".jpg",
    ".png",
    ".webp",
    ".gif",
    ".pdf",
    ".heic",
    ".heif",
    ".xlsx",
    ".xls",
  ];

  const allowedMimeTypes = [
    "image/jpeg",
    "image/png",
    "image/webp",
    "image/gif",
    "application/pdf",
    "image/heic",
    "image/heif",
    "application/octet-stream",
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  ];

  const ext = path.extname(file.originalname).toLowerCase();

  const extname = allowedExtensions.includes(ext);
  const mimetype = allowedMimeTypes.includes(file.mimetype);

  //allow if MIME is valid
  if (mimetype) {
    return cb(null, true);
  }

  log.info(
    `[Middleware], [Upload Error], originalName [${file.originalname}], extension [${ext}], mimeType [${file.mimetype}], fieldName [${file.fieldname}], EndPoint [${req.originalUrl}], Only Images and PDFs files are allowed`
  );

  return cb(new Error("Only Images and PDFs files are allowed"));
};

export const multerSingleFn = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction
) => {
  const upload = multer({ storage: storage, fileFilter: fileFilter }).single("file");

  upload(req, res, function (err) {
    if (err) {
      log.info(
        `[Middleware], [multerSingleFn], Multer Error : ${err?.message || err}`
      );

      return res.status(400).json({
        msg: "Please check the file format or try again later.",
        isSuccess: false,
      });
    }

    next();
  });
};

export const multerArrayFn = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction,
  limit: number
) => {
  const upload = multer({ storage: storage, fileFilter: fileFilter }).array("files", limit);

  upload(req, res, function (err) {
    if (err) {
      log.info(
        `[Middleware], [multerArrayFn], Multer Error : ${err?.message || err}`
      );

      return res.status(400).json({
        msg: "Please check the file format or try again later.",
        isSuccess: false,
      });
    }

    next();
  });
};

export const multerAnyFn = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction
) => {
  // Using .any() allows dynamic keys like item_0_image_0
  const upload = multer({ storage: storage, fileFilter: fileFilter }).any();

  upload(req, res, function (err) {
    if (err) {
      log.info(`[Middleware], [multerAnyFn], Multer Error : ${err?.message || err}`);
      return res.status(400).json({
        msg: "Please check the file format or try again later.",
        isSuccess: false,
      });
    }
    next();
  });
};
