import { Injectable, PipeTransform, BadRequestException } from '@nestjs/common';
import { existsSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
import * as path from 'path';
import * as sharp from 'sharp';
import { ALLOWED_IMAGE_EXT } from '../utils/file-store';
import { Constant } from '../utils/constant';

@Injectable()
export class ImageCompressionPipe implements PipeTransform {
  constructor(
    private folder: string = Constant.WORK_IMAGES_FOLDER,
    private resize: { width?: number; height?: number },
    private options: {
      unique_name?: boolean;
      unique_image_folder?: boolean;
    } = { unique_name: true, unique_image_folder: false },
  ) {}

  async transform(file: Express.Multer.File) {
    if (!file) {
      throw new BadRequestException('No file provided');
    }

    const isVideo = file.mimetype === 'video/mp4';

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

    if (!isImage && !isVideo) {
      throw new BadRequestException(
        `File "${file.originalname}" is not a valid image or video.`,
      );
    }

    const uploadDir = `public/${this.folder}`;
    if (!existsSync(uploadDir)) {
      mkdirSync(uploadDir, { recursive: true });
    } else {
      if (this.options.unique_image_folder) {
        const files = readdirSync(uploadDir);
        files.forEach((file) => {
          const filePath = path.join(uploadDir, file);
          if (/\.(jpg|jpeg|png|webp|mp4)$/i.test(file)) {
            unlinkSync(filePath);
          }
        });
      }
    }

    let filename = null;

    if (isVideo) {
      filename = this.options.unique_name
        ? `${Date.now()}-${file.originalname}`
        : file.originalname;

      const filePath = path.join(uploadDir, filename);
      // Ghi trực tiếp buffer ra file
      await new Promise<void>((resolve, reject) => {
        const fs = require('fs');
        fs.writeFile(filePath, file.buffer, (err) => {
          if (err) reject(err);
          else resolve();
        });
      });

      return { filename };
    }

    filename = this.options.unique_name
      ? `${Date.now()}-${this.resize.width || Constant.DEFAULT_RESIZE}x${this.resize.height || Constant.DEFAULT_RESIZE}-${file.originalname.replace(ext, '.webp')}`
      : file.originalname.replace(ext, '.webp');

    const filePath = path.join(uploadDir, filename);

    try {
      await sharp(file.buffer)
        // .resize({
        //   width: this.resize?.width || Constant.DEFAULT_RESIZE,
        //   height: this.resize?.height || Constant.DEFAULT_RESIZE,
        // })
        .webp({ effort: 3 })
        .toFile(filePath);

      return { filename };
    } catch (error) {
      throw new BadRequestException(
        `Error compressing image: ${error.message}`,
      );
    }
  }
}
