// src/lib/analytics/r2-upload.ts — server-only PUT to Cloudflare R2 (S3 API).
import "server-only";
import { gzipSync } from "node:zlib";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { env } from "@/env";

// Lazily build a module-singleton S3 client so we don't reconstruct it (and
// re-read creds) on every request. Kept out of the request hot path.
let client: S3Client | null = null;

function getClient(): S3Client {
  if (client) return client;
  if (
    !env.R2_ACCOUNT_ID ||
    !env.R2_ACCESS_KEY_ID ||
    !env.R2_SECRET_ACCESS_KEY
  ) {
    throw new Error("R2 credentials are not configured");
  }
  client = new S3Client({
    region: "auto",
    endpoint: `https://${env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
    credentials: {
      accessKeyId: env.R2_ACCESS_KEY_ID,
      secretAccessKey: env.R2_SECRET_ACCESS_KEY,
    },
  });
  return client;
}

/**
 * Upload a CSV body to R2 under `key`, gzip-compressed (ELEVA-78). The key is
 * expected to end in `.csv.gz`. Gzipping cuts R2 transfer ~70-80% and DuckDB's
 * `read_csv()` decompresses `.csv.gz` natively (and faster than raw CSV). We do
 * NOT set `Content-Encoding: gzip` on purpose: that header makes S3/HTTP clients
 * transparently decompress on GET, which would defeat the extension-based gzip
 * detection on the DuckDB side. The bytes are stored gzipped as a `.csv.gz`
 * object. Throws if heavy import is disabled.
 */
export async function putCsvToR2(key: string, body: Buffer): Promise<void> {
  if (!env.analyticsEnabled) {
    throw new Error("Heavy CSV import is not configured");
  }
  await getClient().send(
    new PutObjectCommand({
      Bucket: env.R2_BUCKET,
      Key: key,
      Body: gzipSync(body),
      ContentType: "application/gzip",
    }),
  );
}
