/* ============================================================
 * Copyright (c) 2026 RAVAPI Soluções. www.ravapi.com
 * Adapter S3-compatível — hoje mirado em Cloudflare R2
 *
 * O R2 fala a API do S3 para upload (endpoint por conta,
 * `https://<account_id>.r2.cloudflarestorage.com`), mas serve leitura
 * pública por um domínio customizado à parte — não é o mesmo host. Por
 * isso os dois campos, `endpoint` e `urlPublicaBase`, não podem ser
 * derivados um do outro.
 *
 * ATENÇÃO: sem teste automatizado — exige bucket de verdade. Ver
 * src/core/assets.ts (validação, essa sim testada) para a parte que não
 * precisa de rede.
 * ============================================================ */

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import type { StorageAdapter } from './storage.ts';

export interface ConfigS3 {
  endpoint: string;
  bucket: string;
  accessKeyId: string;
  secretAccessKey: string;
  /** ex.: https://recibos.ravapi.com — domínio customizado do bucket no R2 */
  urlPublicaBase: string;
  region?: string;
}

export class S3StorageAdapter implements StorageAdapter {
  private readonly cliente: S3Client;

  constructor(private readonly config: ConfigS3) {
    this.cliente = new S3Client({
      region: config.region ?? 'auto',
      endpoint: config.endpoint,
      credentials: {
        accessKeyId: config.accessKeyId,
        secretAccessKey: config.secretAccessKey,
      },
    });
  }

  async salvar(chave: string, bytes: Buffer, mime: string): Promise<void> {
    await this.cliente.send(new PutObjectCommand({
      Bucket: this.config.bucket,
      Key: chave,
      Body: bytes,
      ContentType: mime,
    }));
  }

  urlPublica(chave: string): string {
    return `${this.config.urlPublicaBase.replace(/\/$/, '')}/${chave}`;
  }
}
