(function () {
  'use strict';

  if (window.MisticEasePopupManager) return;

  var CFG = window.misticeaseCfg || {};
  var L10N = CFG.i18n || {};

  function i18n(key, fallback) {
    var value = L10N[key];
    return (typeof value === 'string' && value) ? value : fallback;
  }

  function isFloatingUxOn() {
    var v = String(CFG.floatingUx || "on").trim().toLowerCase();
    return v !== "off";
  }

  var BASE = String(CFG.pluginUrl || '').trim();
  if (BASE && BASE.slice(-1) !== '/') BASE += '/';

  function now() { return Date.now ? Date.now() : +new Date(); }

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

  function viewport() {
    var doc = document.documentElement || {};
    var fallbackW = (window.innerWidth || doc.clientWidth || 0);
    var fallbackH = (window.innerHeight || doc.clientHeight || 0);
    var vv = window.visualViewport;

    if (vv && typeof vv.width === 'number' && typeof vv.height === 'number') {
      return {
        w: Math.round(vv.width) || fallbackW,
        h: Math.round(vv.height) || fallbackH,
        left: (typeof vv.offsetLeft === 'number') ? vv.offsetLeft : 0,
        top: (typeof vv.offsetTop === 'number') ? vv.offsetTop : 0
      };
    }

    return {
      w: fallbackW,
      h: fallbackH,
      left: 0,
      top: 0
    };
  }

  function isCoarsePointer() {
    try {
      // Use both pointer and any-pointer so hybrid devices behave consistently.
      if (!window.matchMedia) return false;
      return !!(
        window.matchMedia('(pointer: coarse)').matches ||
        window.matchMedia('(any-pointer: coarse)').matches
      );
    } catch (_e) {
      return false;
    }
  }

  function isIpadDevice() {
    try {
      return (navigator && navigator.platform === 'MacIntel' && navigator.maxTouchPoints && navigator.maxTouchPoints > 1);
    } catch (_e) {
      return false;
    }
  }

  function isAndroidTabletDevice() {
    try {
      var ua = (navigator && navigator.userAgent) ? navigator.userAgent : '';
      return (/Android/i.test(ua) && !/Mobile/i.test(ua));
    } catch (_e) {
      return false;
    }
  }

  function isTabletViewport() {
    // Tablet mode keeps Floating UX mode available while making controls visible without hover.
    // Width-based checks also let responsive preview exercise tablet UX in local/dev environments.
    var vp = viewport();
    if (vp.w <= 640) return false;
    if (vp.w <= 1024) return true;
    return isIpadDevice() || isAndroidTabletDevice() || isCoarsePointer();
  }

  function isPhoneViewport() {
    // Phone mode disables Floating UX mode controls because the viewport is too narrow.
    var vp = viewport();
    return vp.w <= 640;
  }

  function viewportMode() {
    if (isPhoneViewport()) return 'phone';
    if (isTabletViewport()) return 'tablet';
    return 'desktop';
  }

  function syncViewportClasses(win) {
    if (!win || !win.el || !win.el.classList) return;
    var mode = viewportMode();
    win.el.classList.remove('misticease-desktop');
    win.el.classList.remove('misticease-tablet');
    win.el.classList.remove('misticease-phone');
    win.el.classList.add('misticease-' + mode);
  }

  function isStaticOwner(owner) {
    owner = String(owner || '').trim();
    return owner === 'image' || owner === 'pdf' || owner === 'text' || owner === 'office';
  }


  function flashPin(win) {
    if (!win || !win.el || !win.el.classList) return;
    try {
      win.el.classList.remove('misticease-pin-flash');
      void win.el.offsetWidth;
      win.el.classList.add('misticease-pin-flash');
      window.setTimeout(function () {
        try { win.el.classList.remove('misticease-pin-flash'); } catch (_e) {}
      }, 650);
    } catch (_e) {}
  }

	function flashLimit(win) {
		if (!win || !win.el || !win.el.classList) return;
		try {
			win.el.classList.remove('misticease-limit-flash');
			void win.el.offsetWidth;
			win.el.classList.add('misticease-limit-flash');
			window.setTimeout(function () {
				try { win.el.classList.remove('misticease-limit-flash'); } catch (_e) {}
			}, 650);
		} catch (_e) {}
	}


  function ensureOverlay() {
    var el = document.getElementById('misticease-global-overlay');
    if (el) return el;
    el = document.createElement('div');
    el.id = 'misticease-global-overlay';
    el.className = 'misticease-global-overlay';
    el.style.display = 'none';
    document.body.appendChild(el);
    return el;
  }

  function lockScroll() {
    if (!document.body) return;
    if (document.body.dataset && document.body.dataset.misticeaseScrollLock === '1') return;
    if (typeof window.__misticeasePrevOverflow === 'undefined') window.__misticeasePrevOverflow = '';
    window.__misticeasePrevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    if (document.body.dataset) document.body.dataset.misticeaseScrollLock = '1';
  }

  function unlockScroll() {
    if (!document.body) return;
    if (document.body.dataset && document.body.dataset.misticeaseScrollLock === '1') {
      document.body.style.overflow = window.__misticeasePrevOverflow;
      delete document.body.dataset.misticeaseScrollLock;
    }
  }

  var _id = 0;

  var mgr = {
    _wins: [],
    _z: 1000000,
    _overlay: null,
    _isAdmin: false,

    init: function () {
      if (this._overlay) return;
      this._overlay = ensureOverlay();

      // Admin / embedded control panel mode: keep legacy modal behavior.
      this._isAdmin = (/\/wp-admin\//.test(location.pathname || '')) || (document.body && document.body.classList && document.body.classList.contains('wp-admin'));

      var self = this;
      this._overlay.addEventListener('click', function () {
        // When BOTH windows are pinned, the overlay is a deliberate focus lock.
        if (self._wins.length >= 2 && self.pinnedCount() === self._wins.length) {
          var list = self._wins.slice();
          for (var i = 0; i < list.length; i++) {
            if (list[i] && list[i].pinned) flashPin(list[i]);
          }
          return;
        }
        self.closeTop();
      });

      document.addEventListener('keydown', function (ev) {
        if (ev.key === 'Escape') {
          if (self._wins.length >= 2 && self.pinnedCount() === self._wins.length) {
            var list = self._wins.slice();
            for (var i = 0; i < list.length; i++) {
              if (list[i] && list[i].pinned) flashPin(list[i]);
            }
            return;
          }
          self.closeTop();
        }
      });

      var __misticeaseRaf = null;
      function __misticeaseOnViewportChange() {
        try {
          var raf = window.requestAnimationFrame || function (fn) { return window.setTimeout(fn, 16); };
          var caf = window.cancelAnimationFrame || window.clearTimeout;
          if (__misticeaseRaf) { caf(__misticeaseRaf); __misticeaseRaf = null; }
          __misticeaseRaf = raf(function () {
            __misticeaseRaf = null;
            self.handleViewportResize();
          });
        } catch (_e) {
          self.handleViewportResize();
        }
      }
      window.addEventListener('resize', __misticeaseOnViewportChange);
      window.addEventListener('orientationchange', __misticeaseOnViewportChange);

      try {
        if (window.visualViewport && window.visualViewport.addEventListener) {
          window.visualViewport.addEventListener('resize', __misticeaseOnViewportChange);
          window.visualViewport.addEventListener('scroll', __misticeaseOnViewportChange);
        }
      } catch (_e) {}

    },

    getWindows: function () {
      return this._wins.slice();
    },

    pinnedCount: function () {
      var c = 0;
      for (var i = 0; i < this._wins.length; i++) {
        if (this._wins[i].pinned) c++;
      }
      return c;
    },

    shouldOverlay: function () {
      var n = this._wins.length;
      if (n === 0) return false;

      var pc = this.pinnedCount();

      // Modal: overlay only for the classic modal experience.
      // Floating (even pinned) keeps the page interactive unless BOTH windows are pinned.
      if (n === 1) {
        var w = this._wins[0];
        return (w.mode === 'modal');
      }
      if (n >= 2) {
        return pc === n;
      }
      return false;
    },

    updateOverlay: function () {
      this.init();
      var want = this.shouldOverlay();
      this._overlay.style.display = want ? 'block' : 'none';
      if (want) lockScroll(); else unlockScroll();
    },

    handleViewportResize: function () {
      var vp = viewport();
      var phoneMode = isPhoneViewport();

      if (phoneMode) {
        this.enforcePhoneMode();
        this.updateOverlay();
        return;
      }

      for (var i = 0; i < this._wins.length; i++) {
        var win = this._wins[i];
        if (!win || !win.el) continue;

        syncViewportClasses(win);

        if (win._misticeaseFloatingControlsRequested && !win.el.__misticeaseFloatingControlsAttached) {
          this.attachFloatingControls(win);
        }

        if (win.mode !== 'floating') continue;

        var r = win.el.getBoundingClientRect();
        var w = r.width || 0;
        var h = r.height || 0;
        var left = r.left || 0;
        var top = r.top || 0;

        var minL = Math.max(8, (vp.left || 0) + 8);
        var minT = Math.max(8, (vp.top || 0) + 8);
        var maxL = Math.max(minL, (vp.left || 0) + vp.w - w - 8);
        var maxT = Math.max(minT, (vp.top || 0) + vp.h - h - 8);
        var newL = clamp(left, minL, maxL);
        var newT = clamp(top, minT, maxT);

        if (Math.abs(newL - left) > 0.5) win.el.style.left = newL + 'px';
        if (Math.abs(newT - top) > 0.5) win.el.style.top = newT + 'px';
      }

      this.updateOverlay();
    },

    enforcePhoneMode: function () {
      if (!this._wins.length) return;

      var keep = this.topWindow();
      var list = this._wins.slice();
      for (var i = 0; i < list.length; i++) {
        var win = list[i];
        if (!win || win === keep) continue;
        this.close(win);
      }

      if (!keep || !keep.el) return;
      keep.pinned = false;
      keep.el.classList.remove('misticease-pinned');
      keep.el.classList.remove('misticease-show-pin');
      syncViewportClasses(keep);
      this.normalizeModal(keep);
      this.bringToFront(keep);
    },

    bringToFront: function (win) {
      if (!win || !win.el) return;
      win._z = ++this._z;
      win.el.style.zIndex = String(win._z);
    },

    topWindow: function () {
      if (!this._wins.length) return null;
      var top = this._wins[0];
      for (var i = 1; i < this._wins.length; i++) {
        if ((this._wins[i]._z || 0) > (top._z || 0)) top = this._wins[i];
      }
      return top;
    },

    closeTop: function () {
      if (!this._wins.length) return;
      var top = this.topWindow();
      if (top && top.pinned) {
        flashPin(top);
        return;
      }
      this.close(top);
    },

    close: function (win) {
      if (!win) return;
      this._wins = this._wins.filter(function (w) { return w !== win; });
      try { win.close(); } catch (_e) {}
      this.updateOverlay();
    },

    closeAll: function () {
      var list = this._wins.slice();
      this._wins = [];
      for (var i = 0; i < list.length; i++) {
        try { list[i].close(); } catch (_e) {}
      }
      this.updateOverlay();
    },

    closeByOwner: function (owner) {
      var list = this._wins.slice();
      for (var i = 0; i < list.length; i++) {
        if (list[i].owner === owner) {
          if (list[i].pinned) continue;
          this.close(list[i]);
        }
      }
    },

    closeByGroup: function (group) {
      var list = this._wins.slice();
      for (var i = 0; i < list.length; i++) {
        if (list[i].group === group) {
          if (list[i].pinned) continue;
          this.close(list[i]);
        }
      }
    },

    normalizeModal: function (win) {
      if (!win || !win.el) return;
      win.mode = 'modal';
      win.el.classList.remove('misticease-floating');
      win.el.classList.add('misticease-modal');
      win.el.style.left = '50%';
      win.el.style.top = '50%';
      win.el.style.transform = 'translate(-50%, -50%)';
    },

    normalizeFloating: function (win) {
      if (!win || !win.el) return;
      win.mode = 'floating';
      win.el.classList.remove('misticease-modal');
      win.el.classList.add('misticease-floating');
      var r = win.el.getBoundingClientRect();
      win.el.style.left = r.left + 'px';
      win.el.style.top = r.top + 'px';
      win.el.style.transform = 'none';
    },

    attachFloatingControls: function (win) {
      if (!win || !win.el) return;
      if (this._isAdmin) return;
      if (!isFloatingUxOn()) return;

      win._misticeaseFloatingControlsRequested = true;
      syncViewportClasses(win);

      if (isPhoneViewport()) return;
      if (win.el.__misticeaseFloatingControlsAttached) return;
      win.el.__misticeaseFloatingControlsAttached = true;

      win.el.classList.add('misticease-floating-controls-enabled');

      var dragBtn = document.createElement('button');
      dragBtn.type = 'button';
      dragBtn.className = 'misticease-drag-handle';
      dragBtn.setAttribute('aria-label', i18n('drag', 'Drag'));
      dragBtn.setAttribute('title', i18n('drag', 'Drag'));

      var dragImg = document.createElement('img');
      dragImg.alt = '';
      dragImg.setAttribute('aria-hidden', 'true');
      dragImg.src = BASE ? (BASE + 'img/drag-handle.png') : '';
      dragBtn.appendChild(dragImg);

      dragBtn.addEventListener('click', function (ev) {
        ev.preventDefault();
        ev.stopPropagation();
      });

      win.el.appendChild(dragBtn);

      var pinBtn = document.createElement('button');
      pinBtn.type = 'button';
      pinBtn.className = 'misticease-pin-btn';
      pinBtn.setAttribute('aria-label', i18n('pin', 'Pin'));
      pinBtn.setAttribute('title', i18n('pin', 'Pin'));

      var pinImg = document.createElement('img');
      pinImg.alt = '';
      pinImg.setAttribute('aria-hidden', 'true');
      pinImg.src = BASE ? (BASE + 'img/pin.png') : '';
      pinBtn.appendChild(pinImg);

      win.el.appendChild(pinBtn);

      var edges = ['top', 'right', 'bottom', 'left'];
      for (var ei = 0; ei < edges.length; ei++) {
        var ed = document.createElement('div');
        ed.className = 'misticease-edge-grab misticease-edge-' + edges[ei];
        ed.setAttribute('role', 'button');
        ed.setAttribute('aria-label', i18n('drag', 'Drag'));
        ed.setAttribute('title', i18n('drag', 'Drag'));
        win.el.appendChild(ed);
      }

      var self = this;
      var dragging = false;
      var startX = 0, startY = 0, offX = 0, offY = 0;
      var __misticeasePtrId = null;
      var __misticeaseCaptureEl = null;

      function embeddedPointer(enable) {
        var els = win.el.querySelectorAll('iframe, video');
        for (var i = 0; i < els.length; i++) {
          els[i].style.pointerEvents = enable ? '' : 'none';
        }
      }

      function onMove(ev) {
        if (!dragging) return;
        try { ev.preventDefault(); } catch (_e) {}
        var vp = viewport();
        var w = win.el.getBoundingClientRect().width;
        var h = win.el.getBoundingClientRect().height;

        var left = ev.clientX - offX;
        var top = ev.clientY - offY;

        var minL = Math.max(8, (vp.left || 0) + 8);
        var minT = Math.max(8, (vp.top || 0) + 8);
        var maxL = Math.max(minL, (vp.left || 0) + vp.w - w - 8);
        var maxT = Math.max(minT, (vp.top || 0) + vp.h - h - 8);
        left = clamp(left, minL, maxL);
        top = clamp(top, minT, maxT);

        win.el.style.left = left + 'px';
        win.el.style.top = top + 'px';
      }

      function onUp() {
        if (!dragging) return;
        dragging = false;
        try { win.el.classList.remove('misticease-dragging'); } catch (_e) {}
        try { if (__misticeaseCaptureEl && __misticeaseCaptureEl.releasePointerCapture) __misticeaseCaptureEl.releasePointerCapture(__misticeasePtrId); } catch (_e) {}
        embeddedPointer(true);
        document.removeEventListener('pointermove', onMove);
        document.removeEventListener('pointerup', onUp);
        if (!isTabletViewport()) win.el.classList.add('misticease-show-pin');
      }

      function startDrag(ev, captureEl) {
        if (isPhoneViewport()) return;
        if (ev.button !== undefined && ev.button !== 0) return;
        ev.preventDefault();
        ev.stopPropagation();
        if (ev.stopImmediatePropagation) ev.stopImmediatePropagation();

        __misticeasePtrId = (ev && ev.pointerId !== undefined) ? ev.pointerId : null;
        __misticeaseCaptureEl = captureEl || dragBtn;
        try { if (__misticeasePtrId !== null && __misticeaseCaptureEl && __misticeaseCaptureEl.setPointerCapture) __misticeaseCaptureEl.setPointerCapture(__misticeasePtrId); } catch (_e) {}

        self.bringToFront(win);

        if (win.mode !== 'floating') {
          self.normalizeFloating(win);
        }

        try { win.el.classList.add('misticease-dragging'); } catch (_e) {}
        dragging = true;
        startX = ev.clientX;
        startY = ev.clientY;
        var r = win.el.getBoundingClientRect();
        offX = startX - r.left;
        offY = startY - r.top;

        if (!isTabletViewport()) win.el.classList.remove('misticease-show-pin');

        embeddedPointer(false);
        self.updateOverlay();

        document.addEventListener('pointermove', onMove);
        document.addEventListener('pointerup', onUp);
      }

      dragBtn.addEventListener('pointerdown', function (ev) {
        startDrag(ev, dragBtn);
      });

      var edgeEls = win.el.querySelectorAll('.misticease-edge-grab');
      for (var i = 0; i < edgeEls.length; i++) {
        (function (el) {
          el.addEventListener('pointerdown', function (ev) {
            startDrag(ev, el);
          });
        })(edgeEls[i]);
      }

      win.el.addEventListener('mouseleave', function () {
        if (!win.pinned) win.el.classList.remove('misticease-show-pin');
      });

      pinBtn.addEventListener('click', function (ev) {
        ev.preventDefault();
        ev.stopPropagation();

        if (isPhoneViewport()) return;

        self.bringToFront(win);
        if (win.mode !== 'floating') {
          self.normalizeFloating(win);
        }

        if (win.pinned) {
          win.pinned = false;
          win.el.classList.remove('misticease-pinned');
        } else {
          win.pinned = true;
          win.el.classList.add('misticease-pinned');
        }

        win.el.classList.remove('misticease-show-pin');
        flashPin(win);
        self.updateOverlay();
      });
    },

    requestOpen: function (spec) {
      this.init();
      if (!spec || typeof spec.create !== 'function') return null;

      var owner = String(spec.owner || '').trim();
      var group = String(spec.group || '').trim();
      var maxWindows = 2;
      var phoneMode = isPhoneViewport();
      var floatingOn = isFloatingUxOn();

      if (phoneMode || !floatingOn) {
        if (this._wins.length) this.closeAll();
      } else {
        if (maxWindows <= 1) {
          if (this._wins.length) {
            for (var _pi = 0; _pi < this._wins.length; _pi++) {
              var _w = this._wins[_pi];
              if (!_w || !_w.el || !_w.el.classList) continue;
              if (_w.pinned || _w.el.classList.contains('misticease-pinned')) {
                _w.pinned = true;
                flashPin(_w);
                return null;
              }
            }
            this.closeAll();
          }
        } else {
          if (this._wins.length >= 2 && this.pinnedCount() === this._wins.length) {
            for (var li = 0; li < this._wins.length; li++) {
              if (this._wins[li] && this._wins[li].pinned) flashPin(this._wins[li]);
            }
            return null;
          }

          var match = null;
          if (owner || group) {
            for (var mi = 0; mi < this._wins.length; mi++) {
              var mw = this._wins[mi];
              if (!mw) continue;
              if ((owner && mw.owner === owner) || (group && group !== '' && mw.group === group)) {
                match = mw;
                break;
              }
            }
          }

          if (match) {
            if (match.pinned) {
              flashPin(match);
              return null;
            }
            this.close(match);
          }

          if (this._wins.length >= maxWindows) {
            for (var fi = 0; fi < this._wins.length; fi++) {
              flashLimit(this._wins[fi]);
            }
            return null;
          }
        }

        if (owner || group) {
          for (var pi = 0; pi < this._wins.length; pi++) {
            var w = this._wins[pi];
            if (!w || !w.pinned) continue;
            if ((owner && w.owner === owner) || (group && w.group === group && group !== '')) {
              flashPin(w);
              return null;
            }
          }
        }

        if (owner) this.closeByOwner(owner);
        if (group) this.closeByGroup(group);
      }

      var win = spec.create();
      if (!win || !win.el || typeof win.close !== 'function') return null;

      win._id = (++_id);
      win.owner = owner;
      win.group = group;
      win.pinned = false;
      win.mode = 'modal';

      win.el.classList.add('misticease-window');
      this.normalizeModal(win);
      this.bringToFront(win);

      win._misticeaseFloatingControlsRequested = !!spec.floatingControls;
      if (win._misticeaseFloatingControlsRequested && !this._isAdmin) {
        this.attachFloatingControls(win);
      } else {
        syncViewportClasses(win);
      }

      var self = this;

      win.el.addEventListener('pointerdown', function () {
        self.bringToFront(win);
      });

      if (win.closeBtn) {
        win.closeBtn.addEventListener('click', function (ev) {
          ev.preventDefault();
          ev.stopPropagation();
          if (win.pinned) {
            flashPin(win);
            return;
          }
          self.close(win);
        });
      }

      this._wins.push(win);
      this.updateOverlay();

      return win;
    }
  };


  // =========================================================
  // IMPORTANT: We only block *MisticEase media triggers*.
  // Regular page links remain clickable while pinned.
  // =========================================================
  function _closest(el, selector) {
    try {
      return el && el.closest ? el.closest(selector) : null;
    } catch (_e) {
      return null;
    }
  }
  function _closestAnchor(el) {
    while (el && el !== document) {
      if (el.tagName && String(el.tagName).toLowerCase() === 'a') return el;
      el = el.parentNode;
    }
    return null;
  }
  function _isImageHref(href) {
    href = String(href || '');
    return /\.(?:jpe?g|png|gif|webp|avif)(?:[?#].*)?$/i.test(href);
  }
  function _misticEaseMediaTriggerOwner(target) {
    if (!target) return '';

    var trig = _closest(target, '.misticease-thumbnail, .misticease-n-link');
    if (trig) return 'video';

    var a = _closest(target, 'a') || _closestAnchor(target);
    if (!a) return '';
    if (a.classList && a.classList.contains('misticease-img-popup')) return 'image';

    var href = a.getAttribute ? (a.getAttribute('href') || '') : '';
    if (!href) return '';

    var img = null;
    try { img = a.querySelector ? a.querySelector('img') : null; } catch (_e) { img = null; }
    if (img) {
      var cls = String(img.className || '');
      if (/\bwp-image-\d+\b/.test(cls)) return 'image';
      if (_isImageHref(href)) return 'image';
      if (/\/wp-content\//i.test(href) && _isImageHref(href)) return 'image';
    }

    return '';
  }

  function _guardPinnedOpen(ev) {
    try {
      if (!isFloatingUxOn()) return;
      if (!mgr || !mgr._wins || !mgr._wins.length) return;

      var t = ev.target || ev.srcElement;
      var owner = _misticEaseMediaTriggerOwner(t);
      if (!owner) return;

      for (var i = 0; i < mgr._wins.length; i++) {
        var w = mgr._wins[i];
        if (!w || !w.pinned || w.owner !== owner) continue;

        if (ev.preventDefault) ev.preventDefault();
        if (ev.stopPropagation) ev.stopPropagation();
        if (ev.stopImmediatePropagation) ev.stopImmediatePropagation();

        mgr.bringToFront(w);
        flashPin(w);
        return false;
      }
    } catch (_e) {
      return;
    }
  }

  try {
    window.addEventListener('click', _guardPinnedOpen, true);
  } catch (_e) {}

  window.MisticEasePopupManager = mgr;
})();