import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { S3File } from '../interfaces/s3-file.interface';

@Injectable()
export class S3Service {
  private readonly s3Client: S3Client;
  private readonly logger = new Logger(S3Service.name);

  constructor(private readonly configService: ConfigService) {
    this.s3Client = new S3Client({
      region: this.configService.get<string>('AWS_REGION'),
      credentials: {
        accessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
        secretAccessKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
      },
      endpoint: this.configService.get<string>('AWS_ENDPOINT_URL'),
      forcePathStyle: true, // Required for Contabo Object Storage
    });
  }

  async uploadFile(file: Express.Multer.File, folder: string): Promise<string> {
    try {
      const key = `${folder}/${Date.now()}-${file.originalname}`;
      
      const command = new PutObjectCommand({
        Bucket: this.configService.get<string>('AWS_S3_BUCKET_NAME'),
        Key: key,
        Body: file.buffer,
        ContentType: file.mimetype,
      });

      await this.s3Client.send(command);
      this.logger.debug(`File uploaded successfully: ${key}`);
      
      return key;
    } catch (error) {
      this.logger.error(`Error uploading file to S3: ${error.message}`);
      throw new InternalServerErrorException('Failed to upload file to storage');
    }
  }

  async getFile(key: string): Promise<S3File> {
    try {
      const command = new GetObjectCommand({
        Bucket: this.configService.get<string>('AWS_S3_BUCKET_NAME'),
        Key: key,
      });

      const response = await this.s3Client.send(command);
      
      const chunks = [];
      for await (const chunk of response.Body as any) {
        chunks.push(chunk);
      }
      const buffer = Buffer.concat(chunks);

      return {
        buffer,
        contentType: response.ContentType || 'application/octet-stream',
        contentLength: response.ContentLength || buffer.length,
        fileName: key.split('/').pop() || 'download',
      };
    } catch (error) {
      this.logger.error(`Error getting file from S3: ${error.message}`);
      throw new InternalServerErrorException('Failed to retrieve file from storage');
    }
  }
}

  