import { buildApiUrl, buildAuthHeaders, readJsonResponse, throwResponseError } from "./serverConnection";

export interface UploadProgressOptions {
  onProgress?: (percent: number) => void;
  signal?: AbortSignal;
}

export async function uploadAssetWithProgress(
  input: { dataUrl: string; name?: string; mimeType?: string; scope?: string },
  options?: UploadProgressOptions,
): Promise<{ url: string; signedUrl?: string; ossKey?: string }> {
  const { onProgress, signal } = options || {};

  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    const url = buildApiUrl("oss/upload");
    const headers = buildAuthHeaders();

    xhr.open("POST", url);
    Object.entries(headers).forEach(([k, v]) => xhr.setRequestHeader(k, v));

    xhr.upload.addEventListener("progress", (e) => {
      if (e.lengthComputable && onProgress) {
        onProgress(Math.round((e.loaded / e.total) * 100));
      }
    });

    xhr.addEventListener("load", async () => {
      const fakeResponse = new Response(xhr.responseText, {
        status: xhr.status,
        statusText: xhr.statusText,
        headers: { "Content-Type": "application/json" },
      });
      try {
        if (!fakeResponse.ok) {
          await throwResponseError(fakeResponse, "Asset upload failed");
        }
        const result = await readJsonResponse<{ url: string; ossKey?: string }>(
          fakeResponse.clone(),
          "Asset upload response failed",
        );
        resolve(result);
      } catch (e) {
        reject(e);
      }
    });

    xhr.addEventListener("error", () => reject(new Error("上传失败，请检查网络连接")));
    xhr.addEventListener("abort", () => reject(new Error("上传已取消")));

    if (signal) {
      signal.addEventListener("abort", () => xhr.abort());
    }

    xhr.send(JSON.stringify(input));
  });
}
