import { normalizeClass } from "@vue/shared";
import { getScrollParents } from "../_util/Dom/getScrollParent";
import { monitorResize } from "../align/util";
let div;

function getContainer() {
  if (div) return div;
  const size = 160;
  div = document.createElement('div');
  div.className = 'borderLight-wrapper';
  div.style.webkitMaskSize = `${size}px ${size}px`;
  div.style.webkitMaskImage = `radial-gradient(circle at center, #fff 0, transparent ${size / 2}px)`;
  document.body.append(div);
  window.addEventListener('mousemove', e => {
    div.style.webkitMaskPosition = `${e.clientX - size / 2}px ${e.clientY - size / 2}px`;
  });
  return div;
}

function resize(cb) {
  window.addEventListener('resize', cb);
  return () => window.removeEventListener('resize', cb);
}

function scroll(el, cb) {
  let sccrollableNodes = getScrollParents(el);
  sccrollableNodes.forEach(e => e.addEventListener('scroll', cb));
  return () => {
    sccrollableNodes.forEach(e => e.removeEventListener('scroll', cb));
    sccrollableNodes = null;
  };
}

function align(el, {
  width,
  height,
  top,
  left
}) {
  el.style.width = width + 'px';
  el.style.height = height + 'px';
  el.style.top = top + 'px';
  el.style.left = left + 'px';
}

const weakMap = new WeakMap();

function add(el, binding) {
  var _binding$value, _binding$value2, _binding$value3, _binding$value4;

  const div = document.createElement('div');
  div.style.borderWidth = ((_binding$value = binding.value) === null || _binding$value === void 0 ? void 0 : _binding$value.size) + 'px';
  div.className = normalizeClass(['borderLight', (_binding$value2 = binding.value) === null || _binding$value2 === void 0 ? void 0 : _binding$value2.className, (_binding$value3 = binding.value) === null || _binding$value3 === void 0 ? void 0 : _binding$value3.class]);
  Object.assign(div.style, (_binding$value4 = binding.value) === null || _binding$value4 === void 0 ? void 0 : _binding$value4.style);
  weakMap.set(el, {
    el: div,
    resizeMonitor: monitorResize(el, rect => align(div, rect)),
    cancelContainerScroll: scroll(el, () => align(div, el.getBoundingClientRect())),
    cancelSize: resize(() => align(div, el.getBoundingClientRect()))
  });
  getContainer().append(div);
}

function del(el) {
  var _aaa$el;

  const aaa = weakMap.get(el);
  if (!aaa) return;
  aaa.cancelContainerScroll();
  aaa.resizeMonitor();
  aaa.cancelSize();
  (_aaa$el = aaa.el) === null || _aaa$el === void 0 ? void 0 : _aaa$el.parentNode.removeChild(aaa.el);
  weakMap.delete(el);
}

const name = 'borderLight';
const directive = {
  mounted(el, binding) {
    del(el);
    add(el, binding);
  },

  beforeUnmount(el) {
    del(el);
  }

};
export const directives = {
  [name]: directive
};
const BorderLight = {};

BorderLight.install = app => {
  app.directive(name, directive);
};

export default BorderLight;