import { nextTick, onBeforeUnmount, ref, watch } from 'vue';
import raf from '../../_util/raf';
/**
 * Popup should follow the steps for each component work correctly:
 * measure - check for the value stretch size
 * align - let component align the position
 * aligned - re-align again in case additional className changed the size
 * afterAlign - choice next step is trigger motion or finished
 * beforeMotion - should reset motion to invisible so that CSSMotion can do normal motion
 * motion - play the motion
 * stable - everything is done
 */

var StatusQueue = ['measure', 'align', null, 'motion'];
export default (function (visible, doMeasure) {
  var status = ref(null);
  var rafRef = ref();
  var destroyRef = ref(false);

  function setStatus(nextStatus) {
    if (!destroyRef.value) {
      status.value = nextStatus;
    }
  }

  function cancelRaf() {
    raf.cancel(rafRef.value);
  }

  function goNextStatus(callback) {
    cancelRaf();
    rafRef.value = raf(function () {
      // Only align should be manually trigger
      var newStatus = status.value;

      switch (status.value) {
        case 'align':
          newStatus = 'motion';
          break;

        case 'motion':
          newStatus = 'stable';
          break;

        default:
      }

      setStatus(newStatus);
      callback === null || callback === void 0 ? void 0 : callback();
    });
  }

  watch(visible, function () {
    setStatus('measure');
  }, {
    immediate: true,
    flush: 'post'
  }); // Go next status

  watch(status, function () {
    switch (status.value) {
      case 'measure':
        doMeasure();
        break;

      default:
    }

    if (status.value) {
      nextTick(function () {
        var index = StatusQueue.indexOf(status.value);
        var nextStatus = StatusQueue[index + 1];

        if (nextStatus && index !== -1) {
          setStatus(nextStatus);
        }
      });
    }
  }, {
    immediate: true,
    flush: 'post'
  });
  onBeforeUnmount(function () {
    destroyRef.value = true;
    cancelRaf();
  });
  return [status, goNextStatus];
});