import { Injectable, Logger } from '@nestjs/common';
import { v2 as cloudinary } from 'cloudinary';
import { ConfigService } from '@nestjs/config';
import * as streamifier from 'streamifier';

interface CloudinaryResponse {
  url: string;
  secure_url: string;
}

@Injectable()
export class CloudinaryService {
  private logger = new Logger(CloudinaryService.name);

  constructor(private configService: ConfigService) {
    cloudinary.config({
      cloud_name: this.configService.get<string>('CLOUDINARY_CLOUD_NAME'),
      api_key: this.configService.get<string>('CLOUDINARY_API_KEY'),
      api_secret: this.configService.get<string>('CLOUDINARY_API_SECRET'),
    });
  }

  async uploadFile(fileOrBuffer: Express.Multer.File | Buffer): Promise<CloudinaryResponse> {
    let buffer: Buffer;
    
    if (Buffer.isBuffer(fileOrBuffer)) {
      buffer = fileOrBuffer;
    } else if (fileOrBuffer && fileOrBuffer.buffer) {
      buffer = fileOrBuffer.buffer;
    } else {
      this.logger.error('No file or empty buffer provided');
      throw new Error('Invalid file provided');
    }
  
    return new Promise((resolve, reject) => {
      const uploadStream = cloudinary.uploader.upload_stream(
        { 
          folder: 'cyber-alert-nepal',
          resource_type: 'auto' 
        },
        (error, result) => {
          if (error) {
            this.logger.error(`Error uploading to Cloudinary: ${JSON.stringify(error)}`);
            return reject(new Error(`Cloudinary upload failed: ${error.message}`));
          }
          if (!result || !result.secure_url) {
            this.logger.error('Cloudinary returned empty result or missing URL');
            return reject(new Error('Failed to get upload URL'));
          }
          this.logger.log(`File uploaded successfully to: ${result.secure_url}`);
          return resolve({
            url: result.url,
            secure_url: result.secure_url
          });
        }
      );
  
      try {
        streamifier.createReadStream(buffer).pipe(uploadStream);
      } catch (err) {
        this.logger.error(`Error creating read stream: ${err.message}`);
        reject(new Error(`Stream creation failed: ${err.message}`));
      }
    });
  }
}