'use strict';

var vue = require('vue');
var FileSaver = require('file-saver');
var index = require('../../../components/src/plugins/notification/index.js');
var uuid = require('uuid');
var JSZip = require('jszip');
var index$1 = require('../../../components/src/plugins/message/index.js');
require('../../../utils/index.js');
var is = require('../../../utils/src/is.js');

const useDownload = () => {
  const downloadByUrl = async (url, options) => {
    const filename = options?.filename || getUrlFilename(url);
    const curId = uuid.v4();
    const modalInfo = index.GmNotification({
      title: "\u4E0B\u8F7D\u4E2D",
      message: vue.h("div", { className: curId }, [`\u5F53\u524D\u4E0B\u8F7D\u8FDB\u5EA6 0%`]),
      duration: 0
    });
    try {
      await createDownload({
        url,
        filename,
        uuid: curId
      });
    } finally {
      modalInfo.close();
    }
  };
  const downloadByRes = async (res, options) => {
    const filename = options?.filename || getFileNameFromContentDisposition(res?.headers?.["content-disposition"] || res?.headers?.["Content-Disposition"]);
    const resBlob = await res.data;
    const curId = uuid.v4();
    const modalInfo = index.GmNotification({
      title: "\u4E0B\u8F7D\u4E2D",
      message: vue.h("div", { className: curId }, [`\u5F53\u524D\u4E0B\u8F7D\u8FDB\u5EA6 0%`]),
      duration: 0
    });
    const blob = new Blob([resBlob]);
    const fileUrl = window.URL.createObjectURL(blob);
    try {
      await createDownload({
        url: fileUrl,
        filename,
        uuid: curId
      });
    } finally {
      modalInfo.close();
    }
  };
  const downloadToZip = async (fileList, filename) => {
    return new Promise((resolve, reject) => {
      const currentContentClass = `message${Date.now()}`;
      const downloadCount = vue.ref(0);
      const len = fileList.length;
      const modalInfo = index.GmNotification({
        title: "\u4E0B\u8F7D\u4E2D",
        message: vue.h("div", [vue.h("div", { className: currentContentClass }, [`\u603B\u4E0B\u8F7D\u6587\u4EF6\u6570\uFF1A${len}\uFF0C\u5DF2\u4E0B\u8F7D\u6587\u4EF6\u6570\uFF1A${downloadCount.value}`])]),
        duration: 0
      });
      const zipInstance = new JSZip();
      for (let i = 0; i < len; i++) {
        const currentItem = fileList[i];
        const downblobOptions = {
          url: currentItem.url,
          filename: ensureFilenameWithExtension(currentItem.filename, currentItem.url),
          isZip: true
        };
        createDownload(downblobOptions).then((res) => {
          zipInstance.file(downblobOptions.filename, res);
          downloadCount.value++;
          editElementContent(currentContentClass, `\u603B\u4E0B\u8F7D\u6587\u4EF6\u6570\uFF1A${len}\uFF0C\u5DF2\u4E0B\u8F7D\u6587\u4EF6\u6570\uFF1A${downloadCount.value}`);
          if (downloadCount.value == len) {
            editElementContent(currentContentClass, `\u6B63\u5728\u5408\u5E76...`);
            zipInstance.generateAsync({ type: "blob" }).then(async (res2) => {
              modalInfo.close();
              const fileUrl = window.URL.createObjectURL(res2);
              await downloadByUrl(fileUrl, { filename });
              resolve(true);
            }).catch((error) => {
              console.error("error", error);
              reject(error);
            });
          }
        }).catch((error) => {
          reject(error);
          modalInfo.close();
        });
      }
    });
  };
  const createDownload = (options) => {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open("GET", options.url, true);
      xhr.responseType = "blob";
      xhr.onprogress = function(event) {
        if (event.lengthComputable) {
          const percentComplete = Math.floor(event.loaded / event.total * 100);
          if (options.uuid) {
            editElementContent(options.uuid, `\u5F53\u524D\u4E0B\u8F7D\u8FDB\u5EA6 ${percentComplete}%`);
          }
        }
      };
      xhr.onload = function(e) {
        const eventTarget = e.target;
        if ([200, 304].includes(eventTarget.status)) {
          const blob = eventTarget.response;
          if (!options.isZip) {
            FileSaver.saveAs(blob, options.filename);
            index.GmNotification({
              type: "success",
              title: "\u6E29\u99A8\u63D0\u793A",
              message: "\u4E0B\u8F7D\u5B8C\u6210",
              duration: 3e3
            });
          }
          resolve(blob);
        } else if (eventTarget.status === 404) {
          index$1.GmMessage.error("\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u6216\u5DF2\u88AB\u5220\u9664");
          reject(e);
        } else {
          index$1.GmMessage.error("\u4E0B\u8F7D\u5F02\u5E38\uFF0C\u8BF7\u91CD\u8BD5\uFF01");
          reject(e);
        }
      };
      xhr.onerror = function(e) {
        index$1.GmMessage.error("\u4E0B\u8F7D\u5F02\u5E38\uFF0C\u8BF7\u91CD\u8BD5");
        reject(e);
      };
      xhr.send();
    });
  };
  const downloadFolderToZip = async (fileList, zipName) => {
    const finalZipName = zipName || `\u8D44\u6E90${Date.now()}`;
    const currentContentClass = `message${Date.now()}`;
    const downloadCount = vue.ref(0);
    const errorCount = vue.ref(0);
    const totalCount = fileList.length;
    const modalInfo = index.GmNotification({
      title: "\u4E0B\u8F7D\u4E2D",
      message: vue.h("div", [
        vue.h("div", { className: currentContentClass }, [`\u603B\u6587\u4EF6\u6570\uFF1A${totalCount}\uFF0C\u5DF2\u4E0B\u8F7D\uFF1A${downloadCount.value}\uFF0C\u5931\u8D25\uFF1A${errorCount.value}`])
      ]),
      duration: 0
    });
    const zipInstance = new JSZip();
    const concurrentLimit = 5;
    let currentIndex = 0;
    const downloadSingleFile = async (item) => {
      try {
        if (!item.url) {
          if (item.folder) {
            zipInstance.folder(item.folder);
          }
          downloadCount.value++;
          editElementContent(currentContentClass, `\u603B\u6587\u4EF6\u6570\uFF1A${totalCount}\uFF0C\u5DF2\u4E0B\u8F7D\uFF1A${downloadCount.value}\uFF0C\u5931\u8D25\uFF1A${errorCount.value}`);
          return;
        }
        const finalFilename = ensureFilenameWithExtension(item.filename, item.url);
        const blob = await createDownload({
          url: item.url,
          filename: finalFilename,
          isZip: true
        });
        const filePath = item.folder ? `${item.folder}/${finalFilename}` : finalFilename;
        zipInstance.file(filePath, blob);
        downloadCount.value++;
        editElementContent(currentContentClass, `\u603B\u6587\u4EF6\u6570\uFF1A${totalCount}\uFF0C\u5DF2\u4E0B\u8F7D\uFF1A${downloadCount.value}\uFF0C\u5931\u8D25\uFF1A${errorCount.value}`);
      } catch (error) {
        console.error(`\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25: ${item.filename}`, error);
        errorCount.value++;
        editElementContent(currentContentClass, `\u603B\u6587\u4EF6\u6570\uFF1A${totalCount}\uFF0C\u5DF2\u4E0B\u8F7D\uFF1A${downloadCount.value}\uFF0C\u5931\u8D25\uFF1A${errorCount.value}`);
      }
    };
    const processNextBatch = async () => {
      const batch = [];
      for (let i = 0; i < concurrentLimit && currentIndex < fileList.length; i++) {
        const item = fileList[currentIndex++];
        batch.push(downloadSingleFile(item));
      }
      if (batch.length > 0) {
        await Promise.all(batch);
        if (currentIndex < fileList.length) {
          await processNextBatch();
        }
      }
    };
    try {
      await processNextBatch();
      editElementContent(currentContentClass, `\u6B63\u5728\u6253\u5305zip\u6587\u4EF6...`);
      const zipBlob = await zipInstance.generateAsync({ type: "blob" });
      modalInfo.close();
      FileSaver.saveAs(zipBlob, `${finalZipName}.zip`);
      if (errorCount.value > 0) {
        index.GmNotification({
          type: "warning",
          title: "\u6E29\u99A8\u63D0\u793A",
          message: `\u6210\u529F\u4E0B\u8F7D ${downloadCount.value} \u4E2A\u6587\u4EF6\uFF0C${errorCount.value} \u4E2A\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25`,
          duration: 5e3
        });
      } else {
        index.GmNotification({
          type: "success",
          title: "\u6E29\u99A8\u63D0\u793A",
          message: `\u6210\u529F\u4E0B\u8F7D ${downloadCount.value} \u4E2A\u6587\u4EF6`,
          duration: 3e3
        });
      }
      return true;
    } catch (error) {
      modalInfo.close();
      index$1.GmMessage.error("\u6253\u5305\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
      throw error;
    }
  };
  return { downloadByUrl, downloadByRes, downloadToZip, downloadFolderToZip };
};
const editElementContent = (className, content) => {
  const currentEle = document.getElementsByClassName(className)[0];
  if (currentEle) {
    currentEle.innerHTML = content;
  }
};
const getFileNameFromContentDisposition = (disposition) => {
  if (!disposition || !is.isString(disposition)) {
    return "file";
  }
  const normalized = disposition.replace(/\s+/g, "");
  try {
    const rfc5987Match = normalized.match(/filename\*=UTF-8''([^;]+)/i);
    if (rfc5987Match) {
      return decodeURIComponent(rfc5987Match[1]);
    }
    const standardMatch = normalized.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i);
    if (standardMatch) {
      return decodeURIComponent(standardMatch[1].replace(/['"]/g, ""));
    }
    return "file";
  } catch (error) {
    console.error(error);
    return "filename-error";
  }
};
const getUrlFilename = (url) => {
  const urlWithoutQuery = url.split("?")[0];
  const filename = urlWithoutQuery.split("/").pop() || "file";
  return filename;
};
const getFileExtension = (filename) => {
  const match = filename.match(/\.[^./\\]+$/);
  return match ? match[0] : "";
};
const ensureFilenameWithExtension = (filename, url) => {
  if (!filename) {
    return getUrlFilename(url);
  }
  if (getFileExtension(filename)) {
    return filename;
  }
  const urlFilename = getUrlFilename(url);
  const extension = getFileExtension(urlFilename);
  return filename + extension;
};
const getUrlExtension = (url) => {
  const urlFilename = getUrlFilename(url);
  return getFileExtension(urlFilename);
};

exports.ensureFilenameWithExtension = ensureFilenameWithExtension;
exports.getFileExtension = getFileExtension;
exports.getUrlExtension = getUrlExtension;
exports.getUrlFilename = getUrlFilename;
exports.useDownload = useDownload;
//# sourceMappingURL=index.js.map
