import { useGraphQlOperation } from "./graphqlOperation.js";
const DATA_URL_RE = /^data:([^;]+);base64,(.+)$/i;
function parseDataUrl(input) {
  const match = input.match(DATA_URL_RE);
  if (!match) return null;
  const [, contentType, payload] = match;
  return { contentType, payload };
}
function base64ToBytes(base64Payload) {
  const normalized = base64Payload.replace(/-/g, "+").replace(/_/g, "/");
  const binaryStr = atob(normalized);
  const len = binaryStr.length;
  const bytes = new Uint8Array(len);
  const CHUNK = 32768;
  for (let i = 0; i < len; i += CHUNK) {
    const end = Math.min(i + CHUNK, len);
    for (let j = i; j < end; j++) {
      bytes[j] = binaryStr.charCodeAt(j);
    }
  }
  return bytes;
}
function bytesToFile(bytes, filename, contentType) {
  const arrayBuffer = new ArrayBuffer(bytes.byteLength);
  new Uint8Array(arrayBuffer).set(bytes);
  try {
    return new File([arrayBuffer], filename, { type: contentType });
  } catch {
    return new Blob([arrayBuffer], { type: contentType });
  }
}
function ensureDataUrl(base64Data, contentType = "application/octet-stream") {
  if (DATA_URL_RE.test(base64Data)) return base64Data;
  return `data:${contentType};base64,${base64Data}`;
}
function extensionFromMime(mime) {
  const map = {
    "image/png": "png",
    "image/jpeg": "jpg",
    "image/jpg": "jpg",
    "image/gif": "gif",
    "image/webp": "webp",
    "application/pdf": "pdf",
    "text/plain": "txt"
  };
  return map[mime];
}
export const useAssetFile = () => {
  async function hydrateAssetFile(assetFile) {
    if (!assetFile?.base64String && assetFile?.id != null) {
      const result = await useGraphQlOperation(
        "Query",
        "assetFileById",
        ["id", "base64String"],
        { id: assetFile.id },
        false
      );
      if (result?.base64String) assetFile.base64String = result.base64String;
    }
    return assetFile;
  }
  function base64ToFile(base64Data, filename, defaultContentType = "application/octet-stream") {
    try {
      const parsed = parseDataUrl(base64Data);
      const contentType = parsed?.contentType ?? defaultContentType;
      const payload = parsed?.payload ?? base64Data;
      const bytes = base64ToBytes(payload);
      return bytesToFile(bytes, filename, contentType);
    } catch (error) {
      console.error("Invalid base64 data", error);
      return void 0;
    }
  }
  function fileToBase64(file, maxFileSizeMB = 5) {
    const maxSize = maxFileSizeMB * 1048576;
    return new Promise((resolve, reject) => {
      if (file.size > maxSize) {
        reject(`File (${file.name}) size exceeds the ${maxFileSizeMB} MB limit.`);
        return;
      }
      const reader = new FileReader();
      reader.onload = (event) => {
        const dataUrl = event.target?.result;
        resolve({
          fileName: file.name,
          originalFileName: file.name,
          base64String: dataUrl,
          fileType: file.type || parseDataUrl(dataUrl)?.contentType
        });
      };
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  }
  async function fileToBase64String(file, maxFileSizeMB = 5) {
    const res = await fileToBase64(file, maxFileSizeMB);
    return { base64String: res.base64String };
  }
  function downloadBase64File(base64Data, filename) {
    const file = base64ToFile(base64Data, filename);
    if (!file) return;
    const url = URL.createObjectURL(file);
    const link = document.createElement("a");
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    setTimeout(() => URL.revokeObjectURL(url), 0);
  }
  function downloadAsset(input, filename, defaultContentType = "application/octet-stream") {
    let base64 = typeof input === "string" ? input : input.base64String;
    if (!base64) return;
    if (!filename) {
      const parsed2 = parseDataUrl(base64);
      const ext = parsed2 ? extensionFromMime(parsed2.contentType) : void 0;
      filename = typeof input !== "string" && input.fileName || `download${ext ? "." + ext : ""}`;
    }
    const parsed = parseDataUrl(base64);
    if (!parsed) {
      base64 = ensureDataUrl(base64, defaultContentType);
    }
    downloadBase64File(base64, filename);
  }
  return {
    // core
    hydrateAssetFile,
    base64ToFile,
    fileToBase64,
    fileToBase64String,
    downloadBase64File,
    downloadAsset,
    // helpers (exported in case you want them elsewhere)
    ensureDataUrl
  };
};
