import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import * as Minio from 'minio';
import { loadEnv } from '../config/env';
import type { FileStorage } from './file-storage';

/** Seul fichier du dépôt autorisé à importer le SDK MinIO (règle ESLint). */
@Injectable()
export class MinioStorageService implements FileStorage, OnModuleInit {
  private readonly logger = new Logger(MinioStorageService.name);
  private readonly client: Minio.Client;
  private readonly bucket: string;

  constructor() {
    const env = loadEnv();
    this.bucket = env.MINIO_BUCKET;
    this.client = new Minio.Client({
      endPoint: env.MINIO_ENDPOINT,
      port: env.MINIO_PORT,
      useSSL: env.MINIO_USE_SSL === 'true',
      accessKey: env.MINIO_ACCESS_KEY,
      secretKey: env.MINIO_SECRET_KEY,
    });
  }

  /** Le bucket est créé au démarrage — aucune étape manuelle au déploiement. */
  async onModuleInit(): Promise<void> {
    try {
      if (!(await this.client.bucketExists(this.bucket))) {
        await this.client.makeBucket(this.bucket);
        this.logger.log(`Bucket « ${this.bucket} » créé.`);
      }
    } catch (e) {
      // Le stockage peut être en retard au boot : /health le signalera.
      this.logger.warn(`Stockage indisponible au démarrage : ${String(e)}`);
    }
  }

  async healthCheck(): Promise<void> {
    await this.client.listBuckets();
  }

  async putObject(key: string, body: Buffer, contentType: string): Promise<void> {
    await this.client.putObject(this.bucket, key, body, body.length, {
      'Content-Type': contentType,
    });
  }

  async getObjectStream(key: string): Promise<NodeJS.ReadableStream> {
    return this.client.getObject(this.bucket, key);
  }

  async removeObject(key: string): Promise<void> {
    await this.client.removeObject(this.bucket, key);
  }
}
