<template>
  <div
    ref="outsideContainer"
    v-outside="options"
    class="mm-outside">
    <slot></slot>
  </div>
</template>

<script>
import outside from "../../directives/outside"
import config from "../../managers/config"

config.defaults({
  "Outside.delay": 300,
})

const EVENTS = ["hover", "click", "mousedown", "mouseup"]

export default {
  name: "mm-outside",
  directives: { outside },
  inheritAttrs: true,
  provide() {
    return {
      "mm-outside": this,
    }
  },
  inject: {
    popperParent: {
      from: "mm-outside",
      default: () => null,
    },
  },
  props: {
    trigger: String,
    refs: {
      type: Array,
      default: () => [],
    },
    handler: {
      type: Function,
      default: () => {},
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    delay: {
      type: Number,
      default: () => config.get("Outside.delay"),
    },
  },
  data() {
    const _this = this

    return {
      childRefs: [],
      get outsideContainer() {
        return _this.$refs.outsideContainer
      },
    }
  },
  computed: {
    realRefs() {
      return this.childRefs.concat(this.refs)
    },
    options() {
      return {
        disabled: this.disabled,
        trigger: EVENTS.includes(this.trigger) ? this.trigger : "click",
        refs: this.realRefs,
        handler: this.handler,
        delay: this.trigger === "hover" && this.delay,
      }
    },
  },
  mounted() {
    this.appendChildRefsToParent(this.outsideContainer)
  },
  destroyed() {
    this.removeChildRefsRefInParent(this.outsideContainer)
  },
  methods: {
    addRef(ref) {
      this.childRefs.push(ref)
      this.appendChildRefsToParent(ref)
    },
    removeRef(ref) {
      const index = this.childRefs.findIndex(item => item === ref)
      if (~index) {
        this.childRefs.splice(index, 1)
      }
      this.removeChildRefsRefInParent(ref)
    },
    appendChildRefsToParent(ref) {
      if (this.popperParent) {
        this.popperParent.addRef(ref)
      }
    },
    removeChildRefsRefInParent(ref) {
      if (this.popperParent) {
        this.popperParent.removeRef(ref)
      }
    },
  },
}
</script>
