import {
  S3Client,
  PutObjectCommand,
  DeleteObjectCommand,
  GetObjectCommand,
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

let cachedClient: S3Client | null = null;
let cachedBucket: string | null = null;

function getClient() {
  if (cachedClient && cachedBucket) {
    return { s3: cachedClient, bucket: cachedBucket };
  }

  const {
    R2_ENDPOINT,
    R2_REGION = "auto",
    R2_ACCESS_KEY_ID,
    R2_SECRET_ACCESS_KEY,
    R2_BUCKET,
  } = process.env;

  if (!R2_ENDPOINT || !R2_ACCESS_KEY_ID || !R2_SECRET_ACCESS_KEY || !R2_BUCKET) {
    throw new Error("R2 configuration is missing. Check env variables.");
  }

  cachedBucket = R2_BUCKET;
  cachedClient = new S3Client({
    endpoint: R2_ENDPOINT,
    region: R2_REGION,
    credentials: {
      accessKeyId: R2_ACCESS_KEY_ID,
      secretAccessKey: R2_SECRET_ACCESS_KEY,
    },
  });

  return { s3: cachedClient, bucket: cachedBucket };
}

export async function uploadToR2(params: {
  key: string;
  contentType: string;
  body: Buffer;
}) {
  const { s3, bucket } = getClient();
  const command = new PutObjectCommand({
    Bucket: bucket,
    Key: params.key,
    Body: params.body,
    ContentType: params.contentType,
  });
  await s3.send(command);
}

export async function getSignedDownloadUrl(key: string, expiresInSeconds = 300) {
  const { s3, bucket } = getClient();
  const command = new GetObjectCommand({
    Bucket: bucket,
    Key: key,
  });
  return getSignedUrl(s3, command, { expiresIn: expiresInSeconds });
}

export async function deleteFromR2(key: string) {
  const { s3, bucket } = getClient();
  const command = new DeleteObjectCommand({
    Bucket: bucket,
    Key: key,
  });
  await s3.send(command);
}

