import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
import { diskStorage } from 'multer';
import * as fs from 'fs';
import { generateSlug } from '../slug/slug-url';
import { BadRequestException } from '@nestjs/common';

const createFolderIfNotExist = (path) => {
  if (!fs.existsSync(path)) {
    fs.mkdirSync(path, { recursive: true, mode: 0o775 });
  }
};

export const profilePictureConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const uploadPath = './public/uploads/profile-picture';
      createFolderIfNotExist(uploadPath);
      cb(null, uploadPath);
    },
    filename: (req, file, cb) => {
      const timestamp = Date.now();
      const originalFilename = file.originalname;
      const fileExtension = originalFilename.split('.').pop();
      const fileNameWithoutExtension = originalFilename.replace(
        `.${fileExtension}`,
        '',
      );
      const slugifyFilename = generateSlug(fileNameWithoutExtension);
      const newFilename = `${slugifyFilename}-${timestamp}.${fileExtension}`;
      return cb(null, newFilename);
    },
  }),
  limits: {
    fileSize: 20 * 1024 * 1024,
  },
  fileFilter: (req, file, cb) => {
    if (!file.originalname.match(/\.(jpg|jpeg|png|webp)$/)) {
      return cb(
        new BadRequestException({
          statusCode: 400,
          message:
            'Only following file formats are allowed... (jpg, jpeg, png, webp) are allowed.',
        }),
        false,
      );
    }
    cb(null, true);
  },
};

export const sponsorImageConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const uploadPath = './public/uploads/sponsor-image';
      createFolderIfNotExist(uploadPath);
      cb(null, uploadPath);
    },
    filename: (req, file, cb) => {
      const timestamp = Date.now();
      const originalFilename = file.originalname;
      const fileExtension = originalFilename.split('.').pop();
      const fileNameWithoutExtension = originalFilename.replace(
        `.${fileExtension}`,
        '',
      );
      const slugifyFilename = generateSlug(fileNameWithoutExtension);
      const newFilename = `${slugifyFilename}-${timestamp}.${fileExtension}`;
      return cb(null, newFilename);
    },
  }),
  limits: {
    fileSize: 20 * 1024 * 1024,
  },
  fileFilter: (req, file, cb) => {
    if (!file.originalname.match(/\.(jpg|jpeg|png|webp)$/)) {
      return cb(
        new BadRequestException({
          statusCode: 400,
          message:
            'Only following file formats are allowed... (jpg, jpeg, png, webp) are allowed.',
        }),
        false,
      );
    }
    cb(null, true);
  },
};

export const excelFileConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const uploadPath = './public/uploads/excel-files';
      createFolderIfNotExist(uploadPath);
      cb(null, uploadPath);
    },
    filename: (req, file, cb) => {
      const timestamp = Date.now();
      const originalFilename = file.originalname;
      const fileExtension = originalFilename.split('.').pop();
      const fileNameWithoutExtension = originalFilename.replace(
        `.${fileExtension}`,
        '',
      );
      const slugifyFilename = generateSlug(fileNameWithoutExtension);
      const newFilename = `${slugifyFilename}-${timestamp}.${fileExtension}`;
      cb(null, newFilename);
    },
  }),
  fileFilter: (req, file, cb) => {
    try {
      const allowedExcelExtensions = ['xls', 'xlsx', '*'];

      const fileExtension = file.originalname.split('.').pop().toLowerCase();
      const fileType = allowedExcelExtensions.includes(fileExtension)
        ? 'excel'
        : null;

      if (!fileType) {
        return cb(
          new BadRequestException({
            status: false,
            code: 400,
            message: 'Only Excel (xls, xlsx) file formats are allowed.',
            data: [],
          }),
          false,
        );
      }

      cb(null, true);
    } catch (error) {
      cb(
        new BadRequestException({
          status: false,
          code: 400,
          message: 'Error processing the file.',
          data: [],
        }),
        false,
      );
    }
  },
  limits: {
    fileSize: 50 * 1024 * 1024, // 20MB limit
  },
};
