(function(){
  // Global modal controller. Initializes once and configures any modal markup on demand.
  // Exposes: window.MBModal with minimal API (initDialog, applyFromTrigger)
  if(window.MBModal) return;

  function getIds(modalId){
    return {
      dialogId: modalId,
      wrapperId: modalId + '-wrapper',
      panelId: modalId + '-panel',
      headerId: modalId + '-header',
      titleId: modalId + '-title',
      headerCloseId: modalId + '-header-close',
      floatingCloseId: modalId + '-floating-close',
      bodyId: modalId + '-body',
      iframeId: modalId + '-iframe',
      footerId: modalId + '-footer',
      loadingId: modalId + '-loading',
    };
  }

  function getById(id){ return id ? document.getElementById(id) : null; }
  function getAttr(el, /*names*/){
    for(var i=1;i<arguments.length;i++){
      var n = arguments[i];
      try{ var v = el.getAttribute(n); if(v !== null) return v; }catch(e){}
    }
    return null;
  }

  var sizeClassMap = {
    sm: ['max-w-sm'],
    md: ['max-w-md'],
    lg: ['max-w-lg'],
    xl: ['max-w-xl'],
    '2xl': ['max-w-2xl'],
    '3xl': ['max-w-3xl'],
    '4xl': ['max-w-4xl'],
    '5xl': ['max-w-5xl'],
    '6xl': ['max-w-6xl'],
    full: ['max-w-none','w-screen'],
    'full-margin': ['max-w-none','w-screen']
  };

  function applySize(modalId, size, width, height){
    var ids = getIds(modalId);
    var panel = getById(ids.panelId);
    if(!panel) return;
    var wrapper = getById(ids.wrapperId);
    var bodyEl = getById(ids.bodyId);
    var iframe = getById(ids.iframeId);
    var bodyContainer = bodyEl ? bodyEl.parentElement : null;

    var all = new Set([]);
    Object.keys(sizeClassMap).forEach(function(k){ sizeClassMap[k].forEach(function(c){ all.add(c); }); });
    all.forEach(function(c){ panel.classList.remove(c); });
    panel.classList.remove('rounded-none');
    panel.classList.add('rounded-lg');
    panel.style.removeProperty('width');
    panel.style.removeProperty('maxWidth');
    panel.style.removeProperty('height');
    panel.style.removeProperty('maxHeight');

    if(wrapper){
      wrapper.classList.remove('p-0');
      if(!wrapper.classList.contains('p-4')) wrapper.classList.add('p-4');
    }
    if(bodyContainer){
      bodyContainer.classList.add('max-h-[80vh]');
      bodyContainer.classList.remove('flex-1','h-full','min-h-0');
    }
    if(iframe){
      iframe.classList.remove('h-full');
      if(!iframe.classList.contains('h-[70vh]')) iframe.classList.add('h-[70vh]');
    }

    if(width){ panel.style.width = width; }
    if(height){ panel.style.height = height; }

    if(height){
      if(bodyContainer){
        bodyContainer.classList.remove('max-h-[80vh]');
        bodyContainer.classList.add('flex-1','min-h-0');
      }
      if(iframe){
        iframe.classList.remove('h-[70vh]');
        iframe.classList.add('h-full');
      }
    }

    if(!size || !sizeClassMap[size]){
      panel.classList.add('max-w-2xl');
      if(!height) panel.style.height = 'h-[70vh]';
      return;
    }
    sizeClassMap[size].forEach(function(c){ panel.classList.add(c); });

    if(size === 'full'){
      if(wrapper){
        wrapper.classList.remove('p-4');
        wrapper.classList.add('p-0');
        wrapper.classList.add('sm:p-0');
      }
      if(!height){ panel.style.height = '100vh'; }
      panel.classList.add('rounded-none');
      if(bodyContainer){
        bodyContainer.classList.remove('max-h-[80vh]');
        bodyContainer.classList.add('flex-1','min-h-0');
      }
      if(iframe){
        iframe.classList.remove('h-[70vh]');
        iframe.classList.add('h-full');
      }
    }

    if(size === 'full-margin'){
      if(wrapper){
        wrapper.classList.remove('p-0');
        if(!wrapper.classList.contains('p-4')) wrapper.classList.add('p-4');
        wrapper.classList.remove('sm:p-0');
      }
      if(!height){
        panel.style.height = '100vh';
        panel.style.maxHeight = 'calc(100vh - 2rem)';
      }
      if(bodyContainer){
        bodyContainer.classList.remove('max-h-[80vh]');
        bodyContainer.classList.add('flex-1','min-h-0');
      }
      if(iframe){
        iframe.classList.remove('h-[70vh]');
        iframe.classList.add('h-full');
      }
    }
  }

  // After HTMX content is loaded into the modal body, adopt the height to content again
  // This clears any preset fixed height so the panel can size naturally to its content,
  // while keeping a reasonable max height cap via the body container.
  function adoptHeightToContent(modalId){
    try{
      var ids = getIds(modalId);
      var dlg = getById(ids.dialogId);
      var panel = getById(ids.panelId);
      var bodyEl = getById(ids.bodyId);
      var iframe = getById(ids.iframeId);
      var bodyContainer = bodyEl ? bodyEl.parentElement : null;

      // If in iframe mode, do nothing here
      if(iframe && !iframe.classList.contains('hidden')) return;
      // Keep full-screen modals as-is
      var size = dlg ? (dlg.getAttribute('data-size') || '') : '';
      if(size === 'full') return;

      if(panel){
        panel.style.removeProperty('height');
        panel.style.removeProperty('maxHeight');
      }
      if(bodyContainer){
        bodyContainer.classList.add('max-h-[80vh]');
        bodyContainer.classList.remove('flex-1','min-h-0');
      }
      if(iframe){
        iframe.classList.remove('h-full');
        if(!iframe.classList.contains('h-[70vh]')) iframe.classList.add('h-[70vh]');
      }
    }catch(e){}
  }

  function toggleHeaderAndClose(modalId, title, closeEnabled){
    var ids = getIds(modalId);
    var header = getById(ids.headerId);
    var floating = getById(ids.floatingCloseId);
    var headerClose = getById(ids.headerCloseId);
    var titleEl = getById(ids.titleId);
    var hasTitle = !!(title && String(title).trim());

    if(titleEl){ titleEl.textContent = hasTitle ? title : ''; }

    if(hasTitle){
      if(header){ header.classList.remove('hidden'); }
      if(floating){ floating.classList.add('hidden'); }
      if(headerClose){ closeEnabled ? headerClose.classList.remove('hidden') : headerClose.classList.add('hidden'); }
    } else {
      if(header){ header.classList.add('hidden'); }
      if(floating){ closeEnabled ? floating.classList.remove('hidden') : floating.classList.add('hidden'); }
    }
  }

    function dispatchDialogEvent(modalId, name, detail) {
        var dlg = getById(modalId);
        if (!dlg) return;
        console.log('dispatchDialogEvent', name, detail);
        try {
            dlg.dispatchEvent(new CustomEvent(name, {detail: detail || {}, bubbles: true}));
        } catch (e) {
            // Fallback for older browsers without CustomEvent options
            var evt;
            try {
                evt = document.createEvent('CustomEvent');
                evt.initCustomEvent(name, true, false, detail || {});
            } catch (e2) {
                try {
                    evt = new Event(name, {bubbles: true});
                    evt.detail = detail || {};
                } catch (e3) {
                    evt = null;
                }
            }
            if (evt) dlg.dispatchEvent(evt);
        }
    }

    function showLoading(modalId, show) {
        var overlay = getById(getIds(modalId).loadingId);
        if (!overlay) return;
        if (show) {
            MBLoader && MBLoader.show(overlay);
            dispatchDialogEvent(modalId, 'mb:loading:show');
        } else {
            MBLoader && MBLoader.hide(overlay);
            dispatchDialogEvent(modalId, 'mb:loading:hide');
        }
    }

  function showIframe(modalId, url){
    var ids = getIds(modalId);
    var iframe = getById(ids.iframeId);
    var body = getById(ids.bodyId);
    var overlay = getById(ids.loadingId);
    if(iframe){
      if(url){
        if(overlay && window.MBLoader){ MBLoader.scheduleShow(overlay, 350); }
        try{ iframe.src = 'about:blank'; }catch(e){}
        iframe.onload = function(){
          try{
            var isBlank = iframe.contentWindow && iframe.contentWindow.location && iframe.contentWindow.location.href === 'about:blank';
            if(overlay && window.MBLoader){ MBLoader.clearTimer(overlay, '_showTimer'); }
              if (!isBlank) {
                  if (overlay && !overlay.classList.contains('hidden') && window.MBLoader) {
                      MBLoader.hide(overlay);
                  }
                  dispatchDialogEvent(modalId, 'mb:iframe:loaded', {url: url});
              }
          } catch (e) {
              if (overlay && window.MBLoader) {
                  MBLoader.clearTimer(overlay, '_showTimer');
              }
              if (overlay && !overlay.classList.contains('hidden') && window.MBLoader) {
                  MBLoader.hide(overlay);
              }
          }
        };
          iframe.src = url;
          dispatchDialogEvent(modalId, 'mb:iframe:loading', {url: url});
      }
      iframe.classList.remove('hidden');
    }
    if(body){ body.classList.add('hidden'); body.innerHTML = ''; }
  }

  function showBody(modalId){
    var ids = getIds(modalId);
    var iframe = getById(ids.iframeId);
    var body = getById(ids.bodyId);
    if(iframe){ iframe.classList.add('hidden'); try{ iframe.src = 'about:blank'; }catch(e){} }
    if(body){ body.classList.remove('hidden'); }
    // Do not hide loading overlay here; leave it to MBLoader/iframe handlers to avoid flashing old content
    //   showLoading(modalId, false); // re-added
    dispatchDialogEvent(modalId, 'mb:body:show');
  }

  function configureContentMode(modalId, url){
    var ids = getIds(modalId);
    var dlg = getById(ids.dialogId);
    var style = dlg ? (dlg.getAttribute('data-style') || '') : '';

    // Special handling for embedded email previewer style
    if(style === 'email_preview'){
      // Always use body mode; forward url to page component via custom event
      showBody(modalId);
      try{
        var body = getById(ids.bodyId);
        var root = body ? body.querySelector('[data-email-preview-root]') : null;
        if(root && url){
          var ev;
          try{ ev = new CustomEvent('mb:email-preview:set-url', { detail: { url: url }, bubbles: false }); }
          catch(e1){
            try{ ev = document.createEvent('CustomEvent'); ev.initCustomEvent('mb:email-preview:set-url', false, false, { url: url }); }
            catch(e2){ ev = null; }
          }
          if(ev) root.dispatchEvent(ev);
        }
      }catch(e){}
      return;
    }

    if(url){
      showIframe(modalId, url);
    } else {
      // HTMX mode: clear any previous body content and show a light overlay to avoid flashing stale DOM
      var body = getById(ids.bodyId);
      if(body){ body.innerHTML = ''; }
      var overlay = getById(ids.loadingId);
      if(overlay && window.MBLoader){ MBLoader.show(overlay); }
      showBody(modalId);

      // When HTMX swaps in new content for the target, adopt height to the content
      try{
        if(body && window.htmx){
          var once = function(){
            try{
              body.removeEventListener('htmx:afterSwap', once);
              body.removeEventListener('htmx:afterSettle', once);
            }catch(e){}
            // Use a micro delay to let layout settle
            setTimeout(function(){ adoptHeightToContent(modalId); }, 0);
          };
          body.addEventListener('htmx:afterSwap', once);
          body.addEventListener('htmx:afterSettle', once);
        }
      }catch(e){}
    }
  }

  function bindHtmxOverlayOnce(modalId){
    try{
      var ids = getIds(modalId);
      if(window.MBLoader){ MBLoader.bindHtmxOverlay(ids.bodyId, ids.loadingId, 350); }
    }catch(e){}
  }

  function initDialog(modalId){
    if(!modalId) return;
    window.__MBModalInited = window.__MBModalInited || {};
    if(window.__MBModalInited[modalId]) return;
    var ids = getIds(modalId);
    var dlg = getById(ids.dialogId);
    if(!dlg) return;
    window.__MBModalInited[modalId] = true;

    // Observe attribute changes for programmatic control
    try{
      var obs = new MutationObserver(function(list){
        for(var i=0;i<list.length;i++){
          var m = list[i];
          if(m.type !== 'attributes') continue;
          var attr = m.attributeName;
          if(attr === 'data-size' || attr === 'data-width' || attr === 'data-heigth' || attr === 'data-height'){
            var size = getAttr(dlg,'data-size') || '';
            var width = getAttr(dlg,'data-width') || '';
            var height = getAttr(dlg,'data-height','data-heigth') || '';
            applySize(modalId, size, width, height);
          } else if(attr === 'data-url'){
            var url = getAttr(dlg,'data-url') || '';
            configureContentMode(modalId, url);
          } else if(attr === 'data-title' || attr === 'data-close-button'){
            var title = getAttr(dlg,'data-title') || '';
            var closeAttr = getAttr(dlg,'data-close-button');
            var closeEnabled = (closeAttr === null || closeAttr === '' || closeAttr === 'true');
            toggleHeaderAndClose(modalId, title, closeEnabled);
          }
        }
      });
      obs.observe(dlg, { attributes: true });
    }catch(e){}

    // Initialize default header/close state
    try{ toggleHeaderAndClose(modalId, dlg.getAttribute('data-title') || '', true); }catch(e){}

    // Bind HTMX overlay for the modal
    bindHtmxOverlayOnce(modalId);

    // Cleanup on close
    dlg.addEventListener('close', function(){
      try{ dlg.removeAttribute('data-url'); }catch(e){}
      var ids = getIds(modalId);
      var body = getById(ids.bodyId);
      var style = dlg ? (dlg.getAttribute('data-style') || '') : '';
      // Preserve embedded email preview component across closes; other styles clear content
      if(body && style !== 'email_preview'){ body.innerHTML = ''; }
      showBody(modalId);
      // Ensure any loading overlay is hidden when the dialog is closed
      showLoading(modalId, false);
    });
  }

  // Configure modal before opening when clicking a trigger
  document.addEventListener('click', function(ev){
    // Guard: ignore clicks originating from elements marked to skip modal handling
    var t = ev.target;
    try{
      if(t && t.closest && (t.closest('[data-no-modal]') || t.closest('[data-modal-ignore]'))){ return; }
    }catch(e){}
    var btn = ev.target && ev.target.closest ? ev.target.closest('[command="show-modal"][commandfor]') : null;
    if(!btn) return;
    var modalId = getAttr(btn, 'commandfor');
    if(!modalId) return;
    initDialog(modalId);
    var dlg = getById(modalId);
    if(!dlg) return;

    var url = getAttr(btn,'data-url') || '';
    var title = getAttr(btn,'data-title') || '';
    var size = (getAttr(btn,'data-size') || '').trim();
    var width = (getAttr(btn,'data-width') || '').trim();
    var height = (getAttr(btn,'data-height','data-heigth') || '').trim();
    var closeAttr = getAttr(btn,'data-close-button');
    var closeEnabled = (closeAttr === null || closeAttr === '' || closeAttr === 'true');

    toggleHeaderAndClose(modalId, title, closeEnabled);
    applySize(modalId, size, width, height);
    configureContentMode(modalId, url);
  }, true);

  window.MBModal = {
    initDialog: initDialog,
    applyFromTrigger: function(btn){
      if(!btn) return;
      var modalId = getAttr(btn, 'commandfor');
      if(!modalId) return;
      initDialog(modalId);
      var url = getAttr(btn,'data-url') || '';
      var title = getAttr(btn,'data-title') || '';
      var size = (getAttr(btn,'data-size') || '').trim();
      var width = (getAttr(btn,'data-width') || '').trim();
      var height = (getAttr(btn,'data-height','data-heigth') || '').trim();
      var closeAttr = getAttr(btn,'data-close-button');
      var closeEnabled = (closeAttr === null || closeAttr === '' || closeAttr === 'true');
      toggleHeaderAndClose(modalId, title, closeEnabled);
      applySize(modalId, size, width, height);
      configureContentMode(modalId, url);
    }
  };
})();