"use client";

/**
 * PUT a file to a presigned URL, reporting real byte-level progress.
 *
 * Deliberately XHR and not fetch: fetch has no upload-progress event at all (request streams are
 * still not usable for this in browsers), so a fetch-based upload can only ever show a spinner or a
 * made-up percentage. XHR's `upload.onprogress` gives the true figure, which is what the picker's
 * progress bar renders.
 */
export async function putWithProgress(
  url: string,
  file: File,
  mime: string,
  onProgress?: (fraction: number) => void,
): Promise<void> {
  await new Promise<void>((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("PUT", url, true);
    xhr.setRequestHeader("Content-Type", mime);

    xhr.upload.onprogress = (e) => {
      // Not every server/proxy reports a total; without one a fraction would be a guess, so we
      // stay silent and the UI shows its indeterminate bar instead.
      if (e.lengthComputable && e.total > 0) onProgress?.(e.loaded / e.total);
    };
    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        onProgress?.(1);
        resolve();
      } else {
        reject(new Error(`Upload failed (${xhr.status}).`));
      }
    };
    xhr.onerror = () => reject(new Error("Upload failed — check your connection and try again."));
    xhr.onabort = () => reject(new Error("Upload cancelled."));
    xhr.send(file);
  });
}
