"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = useTarget;
var _vue = require("vue");
var _util = require("../util");
var _useState = _interopRequireDefault(require("../../_util/hooks/useState"));
function useTarget(target, open, gap, scrollIntoViewOptions) {
  // ========================= Target =========================
  // We trade `undefined` as not get target by function yet.
  // `null` as empty target.
  const [targetElement, setTargetElement] = (0, _useState.default)(undefined);
  (0, _vue.watchEffect)(() => {
    const nextElement = typeof target.value === 'function' ? target.value() : target.value;
    setTargetElement(nextElement || null);
  }, {
    flush: 'post'
  });
  // ========================= Align ==========================
  const [posInfo, setPosInfo] = (0, _useState.default)(null);
  const updatePos = () => {
    if (!open.value) {
      setPosInfo(null);
      return;
    }
    if (targetElement.value) {
      // Exist target element. We should scroll and get target position
      if (!(0, _util.isInViewPort)(targetElement.value) && open.value) {
        targetElement.value.scrollIntoView(scrollIntoViewOptions.value);
      }
      const {
        left,
        top,
        width,
        height
      } = targetElement.value.getBoundingClientRect();
      const nextPosInfo = {
        left,
        top,
        width,
        height,
        radius: 0
      };
      if (JSON.stringify(posInfo.value) !== JSON.stringify(nextPosInfo)) {
        setPosInfo(nextPosInfo);
      }
    } else {
      // Not exist target which means we just show in center
      setPosInfo(null);
    }
  };
  (0, _vue.onMounted)(() => {
    (0, _vue.watch)([open, targetElement], () => {
      updatePos();
    }, {
      flush: 'post',
      immediate: true
    });
    // update when window resize
    window.addEventListener('resize', updatePos);
    // update when `document.body.style.overflow` is set to visible
    // by default, it will be set to hidden
    window.addEventListener('scroll', updatePos);
  });
  (0, _vue.onBeforeUnmount)(() => {
    window.removeEventListener('resize', updatePos);
    window.removeEventListener('scroll', updatePos);
  });
  const getGapOffset = index => {
    var _a, _b, _c, _d;
    return (_d = Array.isArray((_a = gap.value) === null || _a === void 0 ? void 0 : _a.offset) ? (_b = gap.value) === null || _b === void 0 ? void 0 : _b.offset[index] : (_c = gap.value) === null || _c === void 0 ? void 0 : _c.offset) !== null && _d !== void 0 ? _d : 6;
  };
  // ======================== PosInfo =========================
  const mergedPosInfo = (0, _vue.computed)(() => {
    var _a;
    if (!posInfo.value) {
      return posInfo.value;
    }
    const gapOffsetX = getGapOffset(0);
    const gapOffsetY = getGapOffset(1);
    const gapRadius = ((_a = gap.value) === null || _a === void 0 ? void 0 : _a.radius) || 2;
    return {
      left: posInfo.value.left - gapOffsetX,
      top: posInfo.value.top - gapOffsetY,
      width: posInfo.value.width + gapOffsetX * 2,
      height: posInfo.value.height + gapOffsetY * 2,
      radius: gapRadius
    };
  });
  return [mergedPosInfo, targetElement];
}