(function () {
  const fileBrowser = document.querySelector("[data-file-browser]");
  const viewButtons = document.querySelectorAll("[data-view-button]");
  const previewActions = document.querySelectorAll("[data-preview-action]");
  const fileContextMenu = document.querySelector("[data-file-context-menu]");
  const fileBrowserWindow = document.querySelector("[data-file-browser-window]");

  let ctrlCopyMode = false;
  let contextFile = null;
  const contextMenuCloseDistance = 80;
  const viewStorageKey = "warpbox.fileBrowser.view";

  if (fileBrowser) {
    applySavedFileBrowserPreferences();

    viewButtons.forEach((button) => {
      button.addEventListener("click", () => {
        const view = button.getAttribute("data-view-button");
        setFileBrowserView(view);
        savePreference(viewStorageKey, view);
      });
    });
  }

  if (fileBrowser && fileContextMenu) {
    document.body.appendChild(fileContextMenu);

    fileBrowser.addEventListener("click", (event) => {
      if (!fileBrowser.classList.contains("is-list")) {
        return;
      }
      if (event.target.closest("a, button, input, select, textarea")) {
        return;
      }
      const card = event.target.closest("[data-file-context]");
      const link = card ? card.querySelector(".file-open") : null;
      if (!link) {
        return;
      }
      event.preventDefault();
      if (link.target === "_blank") {
        window.Warpbox.openInNewTab(link.href);
        return;
      }
      window.location.href = link.href;
    });

    fileBrowser.addEventListener("contextmenu", (event) => {
      const card = event.target.closest("[data-file-context]");
      if (!card) {
        return;
      }

      event.preventDefault();
      contextFile = {
        previewURL: card.dataset.previewUrl,
        viewURL: card.dataset.viewUrl,
        downloadURL: card.dataset.downloadUrl,
        fileName: card.dataset.fileName,
      };
      showContextMenu(event.clientX, event.clientY);
    });

    fileContextMenu.addEventListener("click", async (event) => {
      const button = event.target.closest("[data-context-action]");
      if (!button || !contextFile) {
        return;
      }

      const shouldHide = await runContextAction(button.dataset.contextAction, contextFile);
      if (shouldHide !== false) {
        hideContextMenu();
      }
    });

    document.addEventListener("click", (event) => {
      if (!fileContextMenu.contains(event.target)) {
        hideContextMenu();
      }
    });

    document.addEventListener("keydown", (event) => {
      if (event.key === "Escape") {
        hideContextMenu();
      }
    });

    document.addEventListener("mousemove", (event) => {
      if (fileContextMenu.hidden || isPointerNearContextMenu(event.clientX, event.clientY)) {
        return;
      }
      hideContextMenu();
    });

    window.addEventListener("resize", hideContextMenu);
    window.addEventListener("scroll", hideContextMenu, true);
  }

  if (previewActions.length > 0) {
    previewActions.forEach((button) => {
      button.addEventListener("click", async (event) => {
        if (!event.ctrlKey && !ctrlCopyMode) {
          return;
        }

        event.preventDefault();
        await copyPreviewLink(button);
      });
    });

    window.addEventListener("keydown", (event) => {
      if (event.key === "Control") {
        setPreviewCopyMode(true);
      }
    });

    window.addEventListener("keyup", (event) => {
      if (event.key === "Control") {
        setPreviewCopyMode(false);
      }
    });

    window.addEventListener("blur", () => setPreviewCopyMode(false));
  }

  async function copyPreviewLink(button) {
    await window.Warpbox.writeClipboard(window.Warpbox.absoluteURL(button.href));
    const label = button.querySelector("[data-preview-label]");
    if (!label) {
      return;
    }

    label.textContent = "Copied";
    setTimeout(() => {
      label.textContent = ctrlCopyMode ? button.dataset.copyLabel || "Copy link" : button.dataset.viewLabel || "View";
    }, 1200);
  }

  function setPreviewCopyMode(enabled) {
    ctrlCopyMode = enabled;
    previewActions.forEach((button) => {
      const label = button.querySelector("[data-preview-label]");
      const viewIcon = button.querySelector("[data-preview-view-icon]");
      const copyIcon = button.querySelector("[data-preview-copy-icon]");
      if (label) {
        label.textContent = enabled ? button.dataset.copyLabel || "Copy link" : button.dataset.viewLabel || "View";
      }
      if (viewIcon) {
        viewIcon.hidden = enabled;
      }
      if (copyIcon) {
        copyIcon.hidden = !enabled;
      }
    });
  }

  async function runContextAction(action, file) {
    if (action === "preview") {
      window.Warpbox.openInNewTab(file.previewURL);
      return true;
    }
    if (action === "view") {
      window.Warpbox.openInNewTab(file.viewURL);
      return true;
    }
    if (action === "copy-preview") {
      await window.Warpbox.writeClipboard(window.Warpbox.absoluteURL(file.previewURL));
      return true;
    }
    if (action === "copy-download") {
      await window.Warpbox.writeClipboard(window.Warpbox.absoluteURL(file.downloadURL));
      return true;
    }
    if (action === "download") {
      window.Warpbox.openInNewTab(file.downloadURL);
    }
    return true;
  }

  function showContextMenu(x, y) {
    fileContextMenu.hidden = false;
    fileContextMenu.style.left = "0px";
    fileContextMenu.style.top = "0px";

    const rect = fileContextMenu.getBoundingClientRect();
    const margin = 8;
    const left = Math.min(x, window.innerWidth - rect.width - margin);
    const top = Math.min(y, window.innerHeight - rect.height - margin);
    fileContextMenu.style.left = `${Math.max(margin, left)}px`;
    fileContextMenu.style.top = `${Math.max(margin, top)}px`;
  }

  function hideContextMenu() {
    if (!fileContextMenu || fileContextMenu.hidden) {
      return;
    }
    fileContextMenu.hidden = true;
    contextFile = null;
  }

  function isPointerNearContextMenu(x, y) {
    const rect = fileContextMenu.getBoundingClientRect();
    return x >= rect.left - contextMenuCloseDistance &&
      x <= rect.right + contextMenuCloseDistance &&
      y >= rect.top - contextMenuCloseDistance &&
      y <= rect.bottom + contextMenuCloseDistance;
  }

  function applySavedFileBrowserPreferences() {
    const savedView = readPreference(viewStorageKey);
    setFileBrowserView(savedView === "list" ? "list" : "thumbs");
  }

  function setFileBrowserView(view) {
    const normalized = view === "thumbs" ? "thumbs" : "list";
    fileBrowser.classList.toggle("is-list", normalized === "list");
    fileBrowser.classList.toggle("is-thumbs", normalized === "thumbs");
    if (fileBrowserWindow) {
      fileBrowserWindow.classList.toggle("is-list-view", normalized === "list");
      fileBrowserWindow.classList.toggle("is-icon-view", normalized === "thumbs");
    }
    viewButtons.forEach((item) => {
      const active = item.getAttribute("data-view-button") === normalized;
      item.classList.toggle("is-active", active);
      item.setAttribute("aria-pressed", active ? "true" : "false");
    });
  }

  function readPreference(key) {
    try {
      return window.localStorage.getItem(key);
    } catch (_) {
      return "";
    }
  }

  function savePreference(key, value) {
    try {
      window.localStorage.setItem(key, value);
    } catch (_) {
      // LocalStorage can be unavailable in private or locked-down browsers.
    }
  }
})();
