import sharp from 'sharp'
import { resolve } from 'path'
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import dotenv from 'dotenv'

dotenv.config({ path: resolve(process.cwd(), '.env') })

// Ensure required environment variables exist
if (!process.env.AWS_BUCKET || !process.env.CLOUDFRONT_DOMAIN) {
  throw new Error(
    'Missing required AWS environment variables [bucket name and cloudfront domain]',
  )
}

let s3Client: any

if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
  // Configure AWS SDK v3
  s3Client = new S3Client({
    region: process.env.AWS_REGION || 'us-east-1',
    credentials: {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    },
  })
} else {
  // Configure AWS SDK v3
  s3Client = new S3Client({
    region: process.env.AWS_REGION || 'us-east-1',
  })
}

/**
 * Resize an image (provided as a buffer) and upload it to S3.
 * @param {Buffer} fileBuffer - Image file as a buffer.
 * @param {number} width - Desired width.
 * @param {number} height - Desired height.
 * @param {string} outputKey - S3 object key (filename).
 * @returns {Promise<string>} - Returns the CloudFront URL of the uploaded file.
 */
export async function resizeAndUpload(
  fileBuffer: Buffer,
  width: number,
  height: number,
  outputKey: string,
): Promise<{ url: string; message: string }> {
  try {
    // Resize the image using sharp
    const resizedBuffer = await sharp(fileBuffer)
      .resize(width, height)
      .toBuffer()

    // Upload to S3 using AWS SDK v3
    const uploadParams = {
      Bucket: process.env.AWS_BUCKET,
      Key: outputKey,
      Body: resizedBuffer,
      ContentType: 'image/png',
    }

    const command = new PutObjectCommand(uploadParams)
    await s3Client.send(command)

    // Return the CloudFront URL
    return {
      url: `https://${process.env.CLOUDFRONT_DOMAIN}/${outputKey}`,
      message: 'File resized and uploaded successfully',
    }
  } catch (error) {
    console.error('Error processing image:', error)
    throw error
  }
}
