(() => {
  const BOUND_FLAG = "__nodedcWheelOverrideBound";
  const GLOBAL_SLIDER_BOUND_FLAG = "__nodedcGlobalSliderWheelOverrideBound";
  const SYNTHETIC_WHEEL_FLAG = "__nodedcSyntheticWheel";
  const SLIDER_WHEEL_MULTIPLIER = 3;
  const SLIDER_BASE_COOLDOWN = 220;
  const MAIL_BASE_COOLDOWN = 280;
  const MIN_SCROLL_SPEED = 0.2;
  const MAX_SCROLL_SPEED = 2;
  const DEFAULT_SCROLL_SPEED = 0.55;

  function isDesktopPointer() {
    return window.matchMedia?.("(pointer: fine)").matches ?? true;
  }

  function shouldIgnoreWheel(event) {
    return event.ctrlKey || !isDesktopPointer();
  }

  function createSyntheticWheel(event, deltaX, deltaY) {
    if (typeof WheelEvent !== "function") return null;

    const syntheticEvent = new WheelEvent("wheel", {
      bubbles: true,
      cancelable: true,
      view: window,
      deltaX,
      deltaY,
      deltaZ: event.deltaZ || 0,
      deltaMode: event.deltaMode,
      altKey: event.altKey,
      metaKey: event.metaKey,
      shiftKey: event.shiftKey,
    });

    Object.defineProperty(syntheticEvent, SYNTHETIC_WHEEL_FLAG, { value: true });
    return syntheticEvent;
  }

  function createSyntheticHorizontalWheel(event) {
    return createSyntheticWheel(event, event.deltaY * SLIDER_WHEEL_MULTIPLIER, 0);
  }

  function getPrimaryWheelDelta(event) {
    return Math.abs(event.deltaX) > Math.abs(event.deltaY) ? event.deltaX : event.deltaY;
  }

  function clamp(value, min, max) {
    return Math.min(max, Math.max(min, value));
  }

  function getScrollSpeed(surface) {
    const rawValue = surface?.dataset?.scrollSpeed ?? surface?.closest?.("[data-scroll-speed]")?.dataset?.scrollSpeed;
    const value = Number.parseFloat(rawValue);

    if (!Number.isFinite(value)) return DEFAULT_SCROLL_SPEED;
    return clamp(value, MIN_SCROLL_SPEED, MAX_SCROLL_SPEED);
  }

  function getStepCooldown(baseCooldown, surface) {
    return Math.round(baseCooldown / getScrollSpeed(surface));
  }

  function dispatchPointerStep(item) {
    if (typeof PointerEvent !== "function") return false;

    const rect = item.getBoundingClientRect();
    const eventInit = {
      bubbles: true,
      cancelable: true,
      clientX: rect.left + rect.width / 2,
      clientY: rect.top + rect.height / 2,
      pointerId: 1,
      pointerType: "mouse",
      isPrimary: true,
    };

    item.dispatchEvent(new PointerEvent("pointerdown", eventInit));
    document.dispatchEvent(new PointerEvent("pointerup", eventInit));
    return true;
  }

  function stepMailList(surface, event) {
    const now = Date.now();
    const lastStep = Number(surface.__nodedcMailWheelLastStep || 0);
    if (now - lastStep < getStepCooldown(MAIL_BASE_COOLDOWN, surface)) return;

    const items = Array.from(surface.children);
    if (!items.length) return;

    const currentIndex = Math.max(
      0,
      items.findIndex((item) => item.classList.contains("current")),
    );
    const direction = event.deltaY > 0 ? 1 : -1;
    const nextIndex = Math.max(0, Math.min(items.length - 1, currentIndex + direction));

    if (nextIndex === currentIndex) return;

    if (dispatchPointerStep(items[nextIndex])) {
      surface.__nodedcMailWheelLastStep = now;
    }
  }

  function stepSlider(surface, event) {
    const delta = getPrimaryWheelDelta(event);
    if (Math.abs(delta) < 1) return;

    const now = Date.now();
    const lastStep = Number(surface.__nodedcSliderWheelLastStep || 0);
    if (now - lastStep < getStepCooldown(SLIDER_BASE_COOLDOWN, surface)) return;

    const slider = surface.__nodedcSlider;
    if (slider && typeof slider.goToNext === "function" && typeof slider.goToPrev === "function") {
      if (delta > 0) slider.goToNext();
      else slider.goToPrev();

      surface.__nodedcSliderWheelLastStep = now;
      return;
    }

    if (Math.abs(event.deltaY) >= Math.abs(event.deltaX)) {
      const syntheticEvent = createSyntheticHorizontalWheel(event);
      if (syntheticEvent) {
        surface.dispatchEvent(syntheticEvent);
        surface.__nodedcSliderWheelLastStep = now;
      }
    }
  }

  function findSliderAtPoint(event) {
    if (!Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) return null;

    return Array.from(document.querySelectorAll('[data-module="slider"]')).find((surface) => {
      const rect = surface.getBoundingClientRect();
      const left = Math.max(rect.left, 0);
      const right = Math.min(rect.right, window.innerWidth);

      return (
        event.clientX >= left &&
        event.clientX <= right &&
        event.clientY >= rect.top &&
        event.clientY <= rect.bottom
      );
    });
  }

  function bindGlobalSliderWheel() {
    if (document[GLOBAL_SLIDER_BOUND_FLAG]) return;
    document[GLOBAL_SLIDER_BOUND_FLAG] = true;

    document.addEventListener(
      "wheel",
      (event) => {
        if (shouldIgnoreWheel(event) || event[SYNTHETIC_WHEEL_FLAG]) return;
        if (event.target?.closest?.('[data-module="mail-list"]')) return;

        const slider = findSliderAtPoint(event);
        if (!slider) return;

        event.preventDefault();
        event.stopImmediatePropagation();
        stepSlider(slider, event);
      },
      { capture: true, passive: false },
    );
  }

  function bindSliderWheel(surface) {
    if (!surface || surface[BOUND_FLAG]) return;

    surface[BOUND_FLAG] = true;

    surface.addEventListener(
      "wheel",
      (event) => {
        if (shouldIgnoreWheel(event) || event[SYNTHETIC_WHEEL_FLAG]) return;

        event.preventDefault();
        event.stopImmediatePropagation();
        stepSlider(surface, event);
      },
      { capture: true, passive: false },
    );

    surface.addEventListener(
      "wheel",
      (event) => {
        if (shouldIgnoreWheel(event)) return;
        event.stopPropagation();
      },
      { passive: false },
    );
  }

  function bindMailListWheel(surface) {
    if (!surface || surface[BOUND_FLAG]) return;

    surface[BOUND_FLAG] = true;

    surface.addEventListener(
      "wheel",
      (event) => {
        if (shouldIgnoreWheel(event)) return;
        event.preventDefault();

        if (Math.abs(event.deltaY) >= Math.abs(event.deltaX)) {
          stepMailList(surface, event);
        }
      },
      { capture: true, passive: false },
    );

    surface.addEventListener(
      "wheel",
      (event) => {
        if (shouldIgnoreWheel(event)) return;
        event.stopPropagation();
      },
      { passive: false },
    );
  }

  function bindInteractiveScroll() {
    bindGlobalSliderWheel();
    document.querySelectorAll('[data-module="slider"]').forEach(bindSliderWheel);
    document.querySelectorAll('[data-module="mail-list"]').forEach(bindMailListWheel);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", bindInteractiveScroll, { once: true });
  } else {
    bindInteractiveScroll();
  }

  window.addEventListener("load", () => {
    bindInteractiveScroll();
    window.setTimeout(bindInteractiveScroll, 500);
  });
})();
