/**
 * S3 / Cloudflare R2 driver.
 *
 * Intentionally left as a thin, clearly-marked stub so the swap is mechanical:
 *   1. npm i @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
 *   2. uncomment the marked blocks below
 *   3. set STORAGE_DRIVER=s3 plus the S3_* env vars
 * Nothing else in the codebase changes — everything talks to StorageDriver.
 */
import type { Readable } from 'node:stream';
import { env } from '../config/env.js';
import type { PutOptions, StorageDriver } from './driver.js';

// --- uncomment with the SDK installed -------------------------------------
// import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, HeadObjectCommand } from '@aws-sdk/client-s3';
// import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
//
// const s3 = new S3Client({
//   region: env.S3_REGION,
//   endpoint: env.S3_ENDPOINT || undefined,
//   forcePathStyle: Boolean(env.S3_ENDPOINT), // required by R2/MinIO
//   credentials: {
//     accessKeyId: env.S3_ACCESS_KEY_ID!,
//     secretAccessKey: env.S3_SECRET_ACCESS_KEY!,
//   },
// });
// ---------------------------------------------------------------------------

const NOT_WIRED = () =>
  new Error(
    'S3 driver is not wired up yet. Install @aws-sdk/client-s3 + @aws-sdk/s3-request-presigner ' +
      'and uncomment the marked blocks in src/storage/s3Driver.ts.',
  );

export class S3Driver implements StorageDriver {
  readonly name = 's3';

  constructor() {
    if (!env.S3_BUCKET) throw new Error('S3_BUCKET is required when STORAGE_DRIVER=s3');
  }

  async put(_stream: Readable, _opts: PutOptions): Promise<{ bytes: number }> {
    throw NOT_WIRED();
    // await s3.send(new PutObjectCommand({
    //   Bucket: env.S3_BUCKET!, Key: opts.key, Body: stream,
    //   ContentType: opts.contentType, ContentLength: opts.size,
    // }));
    // return { bytes: opts.size ?? 0 };
  }

  async get(_key: string): Promise<{ stream: Readable; size: number; contentType?: string }> {
    throw NOT_WIRED();
    // const res = await s3.send(new GetObjectCommand({ Bucket: env.S3_BUCKET!, Key: key }));
    // return { stream: res.Body as Readable, size: res.ContentLength ?? 0, contentType: res.ContentType };
  }

  async delete(_key: string): Promise<void> {
    throw NOT_WIRED();
    // await s3.send(new DeleteObjectCommand({ Bucket: env.S3_BUCKET!, Key: key }));
  }

  async exists(_key: string): Promise<boolean> {
    throw NOT_WIRED();
    // try { await s3.send(new HeadObjectCommand({ Bucket: env.S3_BUCKET!, Key: key })); return true; }
    // catch { return false; }
  }

  async downloadUrl(_key: string, _ttlSeconds: number, _filename?: string): Promise<string> {
    throw NOT_WIRED();
    // return getSignedUrl(s3, new GetObjectCommand({
    //   Bucket: env.S3_BUCKET!, Key: key,
    //   ResponseContentDisposition: filename ? `attachment; filename="${filename}"` : undefined,
    // }), { expiresIn: ttlSeconds });
  }
}
