/**
 * ذخیره در فضای ابری سازگار با S3 (ابرآروان، لیارا، MinIO، AWS و …).
 * سطل (bucket) باید خواندن عمومی داشته باشد، یا S3_PUBLIC_URL آدرس CDN جلوی آن باشد.
 */
import "server-only";
import { DeleteObjectsCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import type { FileStorage } from "./storage";

export function s3Storage(opts: { endpoint: string; region: string; bucket: string; accessKey: string; secretKey: string; publicUrl: string }): FileStorage {
  const client = new S3Client({
    endpoint: opts.endpoint,
    region: opts.region,
    credentials: { accessKeyId: opts.accessKey, secretAccessKey: opts.secretKey },
    forcePathStyle: true,
  });
  const base = opts.publicUrl.replace(/\/+$/, "") + "/";
  return {
    id: "s3",
    async put(key, body, contentType) {
      await client.send(
        new PutObjectCommand({
          Bucket: opts.bucket,
          Key: key,
          Body: body,
          ContentType: contentType,
          // نام فایل‌ها یکتا و تغییرناپذیرند، پس کش طولانی امن است
          CacheControl: "public, max-age=31536000, immutable",
          ACL: "public-read",
        }),
      );
    },
    async remove(keys) {
      if (!keys.length) return;
      await client.send(new DeleteObjectsCommand({ Bucket: opts.bucket, Delete: { Objects: keys.map((Key) => ({ Key })), Quiet: true } }));
    },
    publicUrl: (key) => base + key,
    keyFromUrl: (url) => (url.startsWith(base) ? url.slice(base.length) : undefined),
  };
}
