(function () {
  'use strict';

  var cfg = window.CUSTAUSU_ADMIN_SAVE_STATE || {};

  function serializeForm(form) {
    if (!form) return '[]';

    if (window.tinymce && typeof window.tinymce.triggerSave === 'function') {
      window.tinymce.triggerSave();
    }

    var fd = new FormData(form);
    return JSON.stringify(Array.from(fd.entries()));
  }

  function initFloatingSave() {
    var floatWrap = document.getElementById('custausu-save-settings-float');
    if (!floatWrap) return;

    var floatBtn = floatWrap.querySelector('.custausu-save-settings-btn--floating');
    var realBtn = document.querySelector('form[action="options.php"] .custausu-save-settings-btn:not(.custausu-save-settings-btn--floating)');
    var form = realBtn ? realBtn.closest('form') : null;

    if (!floatBtn || !realBtn || !form) return;

    var cleanLabel = cfg.clean_label || 'Save settings';
    var dirtyLabel = cfg.dirty_label || 'Save changes';

    var initialState = serializeForm(form);
    var dirtyWatchTimer = null;
    var firstSavableAnchor = null;
    var floatingSyncQueued = false;

    function setDirtyState(isDirty) {
      [realBtn, floatBtn].forEach(function (btn) {
        if (!btn) return;
        btn.classList.toggle('is-dirty', !!isDirty);
        btn.disabled = !isDirty;
        btn.textContent = isDirty ? dirtyLabel : cleanLabel;
      });
    }

    function syncDirtyState() {
      var currentState = serializeForm(form);
      setDirtyState(currentState !== initialState);
    }

    function findFirstSavableAnchor() {
      if (firstSavableAnchor && document.body.contains(firstSavableAnchor)) {
        return firstSavableAnchor;
      }

      firstSavableAnchor = document.getElementById('custausu-section-polylang') ||
        document.querySelector('[id*="polylang" i]') ||
        document.querySelector('.custausu-settings-page form input, .custausu-settings-page form select, .custausu-settings-page form textarea');

      return firstSavableAnchor;
    }

    function requestFloatingSaveSync() {
      if (floatingSyncQueued) return;

      floatingSyncQueued = true;

      window.requestAnimationFrame(function () {
        floatingSyncQueued = false;
        syncFloatingSave();
      });
    }

    function syncFloatingSave() {
      var realRect = realBtn.getBoundingClientRect();

      /*
       * CAS communications and privacy now contains persisted opt-ins and is
       * the first real savable settings area. Keep the existing lookup as a
       * compatibility fallback when that section is not rendered.
       */
      var communicationsSavable = document.getElementById('custausu-section-custausu-communications');
      var firstSavable = communicationsSavable || findFirstSavableAnchor();
      var firstRect = firstSavable ? firstSavable.getBoundingClientRect() : null;

      /*
       * Floating save appears only after the first real editable settings area.
       * Wizard / Doctor / Health Check stay free from the mobile floating button.
       */
      var hasReachedSavableSettings = firstRect ? firstRect.top <= window.innerHeight * 0.50 : true;

      /*
       * Hide again when the original bottom save button is visible/reachable.
       * Also keep it hidden once the user has scrolled past the settings form:
       * below the original Save settings button there are immediate-action tools
       * such as export/import/log/reset, not options.php settings to save.
       */
      var originalSaveIsVisible = realRect.top < window.innerHeight && realRect.bottom > 0;
      var hasPassedOriginalSave = realRect.bottom < 0;

      var shouldShowFloat = hasReachedSavableSettings && !originalSaveIsVisible && !hasPassedOriginalSave;
      floatWrap.classList.toggle('is-visible', shouldShowFloat);
    }

    function startDirtyWatch() {
      if (dirtyWatchTimer) return;

      dirtyWatchTimer = window.setInterval(function () {
        if (document.hidden) return;
        syncDirtyState();
      }, 700);
    }

    function stopDirtyWatch() {
      if (!dirtyWatchTimer) return;
      window.clearInterval(dirtyWatchTimer);
      dirtyWatchTimer = null;
    }

    floatBtn.addEventListener('click', function (ev) {
      ev.preventDefault();
      if (floatBtn.disabled) return;

      if (typeof form.requestSubmit === 'function') {
        form.requestSubmit();
      } else {
        realBtn.click();
      }
    });

    form.addEventListener('submit', function () {
      stopDirtyWatch();
      setDirtyState(false);
      floatWrap.classList.remove('is-visible');
    });

    document.addEventListener('input', function (ev) {
      if (form.contains(ev.target)) {
        syncDirtyState();
      }
    });

    document.addEventListener('change', function (ev) {
      if (form.contains(ev.target)) {
        syncDirtyState();
      }
    });

    document.addEventListener('click', function (ev) {
      var btn = ev.target && ev.target.closest
        ? ev.target.closest('.custausu-insert-var, .quicktags-toolbar input, .quicktags-toolbar button')
        : null;

      if (!btn) return;
      if (!form.contains(btn)) return;

      [0, 120, 300, 600].forEach(function (delay) {
        setTimeout(function () {
          syncDirtyState();
        }, delay);
      });
    });

    if (window.jQuery) {
      window.jQuery(document).on('change input', '.custausu-color', function () {
        syncDirtyState();
      });
    }

    document.addEventListener('tinymce-editor-init', function (e) {
      var ed = e.detail && e.detail.editor;
      if (!ed) return;

      ed.on('Change KeyUp SetContent Undo Redo', function () {
        syncDirtyState();
      });
    });

    window.addEventListener('scroll', requestFloatingSaveSync, { passive: true });
    window.addEventListener('resize', requestFloatingSaveSync);

    window.addEventListener('load', function () {
      initialState = serializeForm(form);
      syncFloatingSave();
      syncDirtyState();
      startDirtyWatch();
    });

    syncFloatingSave();
    syncDirtyState();
    startDirtyWatch();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initFloatingSave);
  } else {
    initFloatingSave();
  }
})();