import {
  Injectable,
  OnModuleInit,
  InternalServerErrorException,
} from '@nestjs/common';

import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { StorageFactory } from './storage.factory';
import { IStorageDriver } from './interface/storage.interface';
import { StorageProvider , StorageProviderSchema , StorageProviderDocument } from './storage.schema';
@Injectable()
export class StoragesService implements OnModuleInit {
  private driver: IStorageDriver | null = null;

  constructor(
    @InjectModel(StorageProvider.name)
    private readonly providerModel: Model<StorageProviderDocument>,
  ) {}

  /*
  =================================================
  Initialize when app starts
  =================================================
  */
  async onModuleInit() {
    await this.loadDriver();
  }

  /*
  =================================================
  Load active provider from DB
  =================================================
  */
  private async loadDriver() {
    const provider = await this.providerModel.findOne({ active: true }).lean();

    if (!provider) {
      throw new InternalServerErrorException(
        'No active storage provider configured',
      );
    }

    this.driver = StorageFactory.create(provider.name, provider.config);
  }

  /*
  =================================================
  Get driver (cached)
  =================================================
  */
  private async getDriver(): Promise<IStorageDriver> {
    if (!this.driver) {
      await this.loadDriver();
    }

    return this.driver!;
  }

  /*
  =================================================
  PUBLIC METHODS
  =================================================
  */

  /**
   * Upload file
   */
  async upload(
    file: Buffer,
    path: string,
    mimeType?: string,
  ): Promise<string> {
    const driver = await this.getDriver();
    return driver.upload(file, path, mimeType);
  }



  async getListFiles() {
    const driver = await this.getDriver();
    return driver.getAvailableImages();   
  }
  /**
   * Delete file
   */
  async delete(path: string): Promise<void> {
    const driver = await this.getDriver();
    return driver.delete(path);
  }
  // async delete(): Promise<void> {
  //   const driver = await this.getDriver();
  //   return driver.delete();
  // }

  /**
   * Get public URL
   */
  async getUrl(path: string): Promise<string> {
    const driver = await this.getDriver();
    return driver.getUrl(path);
  }

  /**
   * Reload driver if DB config changes
   */
  async refresh(): Promise<void> {
    await this.loadDriver();
  }
}
