<template>
  <transition
    name="mm-message-fade"
    @before-leave="setHeight">
    <div
      v-show="visible"
      :class="['mm-message', `mm-message--${type}`]"
      style="zoom: 1"
      @mouseenter="cancelAutoClose"
      @mouseleave="setUpAutoClose">
      <ui-loading
        v-if="type === 'loading'"
        :stroke-width="4"
        size="12px"></ui-loading>
      <ui-icon
        v-else
        :name="icon"
        size="12px"
        class="mm-message-icon"></ui-icon>
      <slot>
        <div
          v-if="messageIsHtml"
          class="mm-message-content"
          v-html="message"></div>
        <div
          v-else
          class="mm-message-content">
          {{ message }}
        </div>
      </slot>
    </div>
  </transition>
</template>

<script>
import Icon from "../icon"
import Loading from "../loading"
import config from "../../managers/config"

config.defaults({
  "Message.type": "info",
  "Message.duration": 3,
})

const TYPES = ["info", "success", "warning", "error", "loading"]

export default {
  name: "mm-message",
  components: {
    "ui-icon": Icon,
    "ui-loading": Loading,
  },
  props: {
    message: {
      type: [String, Object],
    },
    messageIsHtml: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: () => config.get("Message.type"),
      validator: function(value) {
        return TYPES.includes(value)
      },
    },
    iconName: {
      type: String,
      default: "",
    },
    duration: {
      type: Number,
      default: () => config.get("Message.duration"),
    },
    onClose: {
      type: Function,
    },
  },
  data() {
    return {
      visible: false,
      timer: null,
    }
  },
  computed: {
    icon() {
      return this.iconName || this.type
    },
  },
  mounted() {
    this.setUpAutoClose()
  },
  methods: {
    destroy() {
      if (typeof this.onClose === "function") {
        this.onClose()
      }

      // ready for animate
      this.$el.style.height = `${this.$el.offsetHeight}px`

      this.visible = false
      this.$el.addEventListener("transitionend", this.destroyElement)
    },
    destroyElement() {
      this.$el.removeEventListener("transitionend", this.destroyElement)
      this.$el.remove()
      this.$destroy()
    },
    setUpAutoClose() {
      if (this.duration > 0) {
        this.timer = setTimeout(this.destroy, this.duration * 1000)
      }
    },
    cancelAutoClose() {
      if (this.timer) {
        clearTimeout(this.timer)
      }
    },
    close() {
      this.cancelAutoClose()
      this.destroy()
    },
    setHeight() {
      this.$el.style.height = "0px"
    },
  },
}
</script>
