"use strict";

exports.__esModule = true;
exports["default"] = void 0;
var _react = require("react");
var _uuid = _interopRequireDefault(require("../../mixins/uuid"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var roots = new Map();
var observers = {};
var totalObservers = {};
var callbacks = new Map();
var getRootId = function getRootId(root) {
  if (roots.has(root)) return roots.get(root);
  var id = (0, _uuid["default"])();
  roots.set(root, id);
  return id;
};
var getId = function getId(_ref) {
  var root = _ref.root,
    rootMargin = _ref.rootMargin,
    threshold = _ref.threshold;
  return getRootId(root) + "|" + rootMargin + "|" + threshold;
};
var intersectionCallback = function intersectionCallback(entries) {
  entries.forEach(function (entry) {
    var target = entry.target,
      isIntersecting = entry.isIntersecting;
    var cb = callbacks.get(target);
    cb == null || cb(isIntersecting);
  });
};
var observe = function observe(callback, element, options) {
  var id = getId(options);
  if (!(id in observers)) {
    observers[id] = new IntersectionObserver(intersectionCallback, options);
    totalObservers[id] = 0;
  }
  var observer = observers[id];
  observer.observe(element);
  callbacks.set(element, callback);
  totalObservers[id] = totalObservers[id] + 1;
  return function () {
    callbacks["delete"](element);
    observer.unobserve(element);
    totalObservers[id] = totalObservers[id] - 1;
    if (totalObservers[id] > 0) return;
    observer.disconnect();
    callbacks["delete"](callback);
    delete observers[id];
    delete totalObservers[id];
  };
};
var _default = exports["default"] = function _default(_ref2) {
  var root = _ref2.root,
    rootMargin = _ref2.rootMargin,
    threshold = _ref2.threshold,
    onVisibility = _ref2.onVisibility,
    _ref2$defaultVisible = _ref2.defaultVisible,
    defaultVisible = _ref2$defaultVisible === void 0 ? false : _ref2$defaultVisible;
  var ref = (0, _react.useRef)();
  var unObserveRef = (0, _react.useRef)();
  var _useState = (0, _react.useState)(defaultVisible),
    visible = _useState[0],
    setVisible = _useState[1];
  var setRef = (0, _react.useCallback)(function (element) {
    ref.current = element;
    unObserveRef.current == null || unObserveRef.current();
    unObserveRef.current = null;
    if (!element) return;
    var options = {
      root: root,
      rootMargin: rootMargin,
      threshold: threshold
    };
    unObserveRef.current = observe(function (value) {
      if (onVisibility) onVisibility(value);
      setVisible(value);
    }, element, options);
  }, [root, rootMargin, threshold, onVisibility]);
  (0, _react.useEffect)(function () {
    return function () {
      unObserveRef.current == null || unObserveRef.current();
      unObserveRef.current = null;
    };
  }, []);
  return [setRef, ref, visible];
};