import { toFileWithPath } from "./file.mjs";
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
const FILES_TO_IGNORE = [
  // Thumbnail cache files for macOS and Windows
  ".DS_Store",
  // macOs
  "Thumbs.db"
  // Windows
];
function fromEvent(evt) {
  return __async(this, null, function* () {
    if (isObject(evt) && isDataTransfer(evt.dataTransfer)) {
      return getDataTransferFiles(evt.dataTransfer, evt.type);
    } else if (isChangeEvt(evt)) {
      return getInputFiles(evt);
    } else if (Array.isArray(evt) && evt.every((item) => "getFile" in item && typeof item.getFile === "function")) {
      return getFsHandleFiles(evt);
    }
    return [];
  });
}
function isDataTransfer(value) {
  return isObject(value);
}
function isChangeEvt(value) {
  return isObject(value) && isObject(value.target);
}
function isObject(v) {
  return typeof v === "object" && v !== null;
}
function getInputFiles(evt) {
  return fromList(evt.target.files).map((file) => toFileWithPath(file));
}
function getFsHandleFiles(handles) {
  return __async(this, null, function* () {
    const files = yield Promise.all(handles.map((h) => h.getFile()));
    return files.map((file) => toFileWithPath(file));
  });
}
function getDataTransferFiles(dt, type) {
  return __async(this, null, function* () {
    if (dt.items) {
      const items = fromList(dt.items).filter((item) => item.kind === "file");
      if (type !== "drop") {
        return items;
      }
      const files = yield Promise.all(items.map(toFilePromises));
      return noIgnoredFiles(flatten(files));
    }
    return noIgnoredFiles(fromList(dt.files).map((file) => toFileWithPath(file)));
  });
}
function noIgnoredFiles(files) {
  return files.filter((file) => FILES_TO_IGNORE.indexOf(file.name) === -1);
}
function fromList(items) {
  if (items === null) {
    return [];
  }
  const files = [];
  for (let i = 0; i < items.length; i++) {
    const file = items[i];
    files.push(file);
  }
  return files;
}
function toFilePromises(item) {
  if (typeof item.webkitGetAsEntry !== "function") {
    return fromDataTransferItem(item);
  }
  const entry = item.webkitGetAsEntry();
  if (entry && entry.isDirectory) {
    return fromDirEntry(entry);
  }
  return fromDataTransferItem(item, entry);
}
function flatten(items) {
  return items.reduce(
    (acc, files) => [
      ...acc,
      ...Array.isArray(files) ? flatten(files) : [files]
    ],
    []
  );
}
function fromDataTransferItem(item, entry) {
  var _a;
  if (typeof item.getAsFileSystemHandle === "function") {
    return item.getAsFileSystemHandle().then((h) => __async(this, null, function* () {
      const file2 = yield h.getFile();
      file2.handle = h;
      return toFileWithPath(file2);
    }));
  }
  const file = item.getAsFile();
  if (!file) {
    return Promise.reject(`${item} is not a File`);
  }
  const fwp = toFileWithPath(file, (_a = entry == null ? void 0 : entry.fullPath) != null ? _a : void 0);
  return Promise.resolve(fwp);
}
function fromEntry(entry) {
  return __async(this, null, function* () {
    return entry.isDirectory ? fromDirEntry(entry) : fromFileEntry(entry);
  });
}
function fromDirEntry(entry) {
  const reader = entry.createReader();
  return new Promise((resolve, reject) => {
    const entries = [];
    function readEntries() {
      reader.readEntries(
        (batch) => __async(this, null, function* () {
          if (!batch.length) {
            try {
              const files = yield Promise.all(entries);
              resolve(files);
            } catch (err) {
              reject(err);
            }
          } else {
            const items = Promise.all(batch.map(fromEntry));
            entries.push(items);
            readEntries();
          }
        }),
        (err) => {
          reject(err);
        }
      );
    }
    readEntries();
  });
}
function fromFileEntry(entry) {
  return __async(this, null, function* () {
    return new Promise((resolve, reject) => {
      entry.file(
        (file) => {
          const fwp = toFileWithPath(file, entry.fullPath);
          resolve(fwp);
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
}
export {
  fromEvent
};
