import cloudinary from "../config/cloudinary";
import { UploadedFile } from "express-fileupload";

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:
          folder === "avatars"
            ? [{ width: 300, height: 300, crop: "fill", gravity: "face" }]
            : folder === "cover-images"
              ? [{ width: 1200, height: 400, crop: "fill" }]
              : [],
      },
      (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"));
        }
      },
    );

    // Handle Buffer or tempFilePath
    if (file.data) {
      uploadStream.end(file.data);
    } else if (file.tempFilePath) {
      uploadStream.end(require("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();
      }
    });
  });
};

// Local storage alternative (for development)
export const uploadToLocal = async (
  file: UploadedFile,
  folder: string,
  userId: string,
): Promise<UploadResult> => {
  const fs = require("fs");
  const path = require("path");

  const uploadsDir = path.join(__dirname, "../../uploads", folder);

  // Ensure directory exists
  if (!fs.existsSync(uploadsDir)) {
    fs.mkdirSync(uploadsDir, { recursive: true });
  }

  const filename = `${userId}_${Date.now()}${path.extname(file.name)}`;
  const filepath = path.join(uploadsDir, filename);

  // Move file
  if (file.tempFilePath) {
    fs.copyFileSync(file.tempFilePath, filepath);
  } else if (file.data) {
    fs.writeFileSync(filepath, file.data);
  }

  const url = `/uploads/${folder}/${filename}`;

  return {
    url,
    public_id: filename,
    format: path.extname(file.name).substring(1),
    size: file.size,
  };
};

export const deleteFromLocal = async (url: string): Promise<void> => {
  const fs = require("fs");
  const path = require("path");

  const filepath = path.join(__dirname, "../..", url);

  if (fs.existsSync(filepath)) {
    fs.unlinkSync(filepath);
  }
};


// Existing imports and functions...
export const uploadWithTransformations = async (
  file: UploadedFile,
  folder: string,
  userId: string,
  transformations: any[] = [],
): 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: transformations,
      },
      (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) {
      uploadStream.end(require("fs").createReadStream(file.tempFilePath));
    } else {
      reject(new Error("No file data available"));
    }
  });
};

export const generateThumbnail = (
  url: string,
  width: number = 300,
  height: number = 300,
): string => {
  return url.replace("/upload/", `/upload/w_${width},h_${height},c_fill/`);
};

export const generateOptimizedImage = (
  url: string,
  quality: number = 80,
): string => {
  return url.replace("/upload/", `/upload/q_${quality},f_auto/`);
};
