import { v2 as cloudinary } from "cloudinary";
import { UploadedFile } from "express-fileupload";

// Configure cloudinary
cloudinary.config({
  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
  secure: true,
});

export interface UploadResult {
  url: string;
  public_id: string;
  format: string;
  size: number;
  width?: number;
  height?: number;
}

export const uploadFile = async (
  file: UploadedFile,
  folder: string,
  userId: string,
): Promise<UploadResult> => {
  return new Promise((resolve, reject) => {
    const uploadStream = cloudinary.uploader.upload_stream(
      {
        folder: `toolffy/${folder}`,
        public_id: `${userId}_${Date.now()}`,
        resource_type: "auto",
        transformation: [
          { width: 500, height: 500, crop: "limit" }, // Resize if larger
          { quality: "auto" }, // Auto optimize quality
          { fetch_format: "auto" } // Auto convert to best format
        ],
      },
      (error, result) => {
        if (error) {
          reject(error);
        } else if (result) {
          resolve({
            url: result.secure_url,
            public_id: result.public_id,
            format: result.format,
            size: result.bytes,
            width: result.width,
            height: result.height,
          });
        } else {
          reject(new Error("Upload failed"));
        }
      },
    );

    if (file.data) {
      uploadStream.end(file.data);
    } else if (file.tempFilePath) {
      const fs = require("fs");
      uploadStream.end(fs.createReadStream(file.tempFilePath));
    } else {
      reject(new Error("No file data available"));
    }
  });
};

export const deleteFile = async (url: string): Promise<void> => {
  // Extract public_id from URL
  const matches = url.match(/\/([^/]+)\/([^/]+)\/([^/]+)\.([^/.]+)$/);
  if (!matches) {
    throw new Error("Invalid Cloudinary URL");
  }

  const publicId = matches.slice(2, 4).join("/");

  return new Promise((resolve, reject) => {
    cloudinary.uploader.destroy(publicId, (error, result) => {
      if (error) {
        reject(error);
      } else {
        resolve();
      }
    });
  });
};

export default {
  uploadFile,
  deleteFile
};