import { request } from "../utils/request";
import { getTenantCode } from "../utils/tenant";

export const commonApi = {
  getOptions: () => request("/common/options"),
  checkHash: (hash) => request(`/upload/check?hash=${hash}`),
  deleteMedia: (id) => request(`/media-assets/${id}`, { method: "DELETE" }),
  upload: (file, type) => {
    const formData = new FormData();
    formData.append("file", file);
    formData.append("type", type);
    return request("/upload", { method: "POST", body: formData });
  },
  uploadMultipart: (file, hash, type, onProgress) => {
    const controller = new AbortController();
    const signal = controller.signal;

    const promise = (async () => {
      // 1. Check Hash
      try {
        const res = await commonApi.checkHash(hash);
        if (res) {
          if (onProgress) onProgress(100);
          return res;
        }
      } catch (e) {
        // Ignore hash check errors
      }

      if (signal.aborted) throw new Error("Aborted");

      // 2. Init
      const initRes = await request("/upload/init", {
        method: "POST",
        body: {
          filename: file.name,
          size: file.size,
          mime_type: file.type,
          hash: hash,
          type: type,
        },
        signal,
      });

      const { upload_id, chunk_size } = initRes;
      const totalChunks = Math.ceil(file.size / chunk_size);

      // 3. Upload Parts
      for (let i = 0; i < totalChunks; i++) {
        if (signal.aborted) throw new Error("Aborted");

        const start = i * chunk_size;
        const end = Math.min(start + chunk_size, file.size);
        const chunk = file.slice(start, end);

        const formData = new FormData();
        formData.append("file", chunk);
        formData.append("upload_id", upload_id);
        formData.append("part_number", i + 1);

        // request helper with FormData handles content-type, but we need signal
        await request("/upload/part", {
          method: "POST",
          body: formData,
          signal,
        });

        if (onProgress) {
          const percent = Math.round(((i + 1) / totalChunks) * 100);
          onProgress(percent);
        }
      }

      // 4. Complete
      return request("/upload/complete", {
        method: "POST",
        body: { upload_id },
        signal,
      });
    })();

    return { promise, abort: () => controller.abort() };
  },
  uploadWithProgress: (file, type, onProgress) => {
    let xhr;
    const promise = new Promise((resolve, reject) => {
      const formData = new FormData();
      formData.append("file", file);
      formData.append("type", type);

      xhr = new XMLHttpRequest();
      const tenantCode = getTenantCode();
      if (!tenantCode) {
        reject(new Error("Tenant code missing in URL"));
        return;
      }
      xhr.open("POST", `/t/${tenantCode}/v1/upload`);

      const token = localStorage.getItem("token");
      if (token) {
        xhr.setRequestHeader("Authorization", `Bearer ${token}`);
      }

      xhr.upload.onprogress = (event) => {
        if (event.lengthComputable && onProgress) {
          const percentComplete = (event.loaded / event.total) * 100;
          onProgress(percentComplete);
        }
      };

      xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const response = JSON.parse(xhr.responseText);
            resolve(response);
          } catch (e) {
            reject(e);
          }
        } else {
          reject(new Error(xhr.statusText || "Upload failed"));
        }
      };

      xhr.onerror = () => reject(new Error("Network Error"));
      xhr.onabort = () => reject(new Error("Aborted"));
      xhr.send(formData);
    });

    return { promise, abort: () => xhr.abort() };
  },
};
