/**
 * Save button component: button with three states — default (Save), loading (spinner), saved (check).
 * Control via API for AJAX or any async flow: startLoading(), then setSaved() + reset(), or stopLoading() on error.
 *
 * Markup: button with .btn__state--default, .btn__state--loading (e.g. with .loader img),
 * .btn__state--saved. Use .btn--no-disabled-fade if you want no opacity change when disabled.
 *
 * @example
 * saveBtn.startLoading();
 * fetch('/api/save', { method: 'POST', body: data }).then(r => r.ok ? r.json() : Promise.reject())
 *   .then(() => { saveBtn.setSaved(); setTimeout(() => saveBtn.reset(), 2000); })
 *   .catch(() => saveBtn.stopLoading());
 */
function SaveButton(selectorOrElement) {
  const button = typeof selectorOrElement === 'string'
    ? document.querySelector(selectorOrElement)
    : selectorOrElement;
  if (!button) return null;

  const defaultState = button.querySelector('.btn__state--default');
  const loadingState = button.querySelector('.btn__state--loading');
  const savedState = button.querySelector('.btn__state--saved');
  if (!defaultState || !loadingState || !savedState) return null;

  function show(state) {
    defaultState[state === 'default' ? 'removeAttribute' : 'setAttribute']('hidden', '');
    loadingState[state === 'loading' ? 'removeAttribute' : 'setAttribute']('hidden', '');
    savedState[state === 'saved' ? 'removeAttribute' : 'setAttribute']('hidden', '');
  }

  return {
    button,
    defaultState,
    loadingState,
    savedState,

    /** Show loading state and disable the button. */
    startLoading() {
      button.disabled = true;
      show('loading');
    },

    /** Show saved state (button remains disabled). */
    setSaved() {
      show('saved');
    },

    /** Show default state and re-enable the button. Use after setSaved() or to leave "saved" state. */
    reset() {
      button.disabled = false;
      show('default');
    },

    /** Stop loading and return to default (e.g. on AJAX error). Same as reset() but clearer intent. */
    stopLoading() {
      button.disabled = false;
      show('default');
    }
  };
}

window.SaveButton = SaveButton;
