<template>
  <transition :name="transition">
    <div
      v-show="visible"
      class="mm-back-top"
      @click="scrollToTop">
      <slot>
        <div class="mm-back-top-inner">
          <ui-icon
            class="mm-back-top-inner-icon"
            name="switch"
            size="20px"
            fill="#fff"></ui-icon>
        </div>
      </slot>
    </div>
  </transition>
</template>

<script>
import Icon from "../icon"
import { scrollTop } from "../../utils/scroll"
import config from "../../managers/config"

config.defaults({
  "BackTop.visibilityHeight": 400,
  "BackTop.target": () => null,
  "BackTop.transition": "fade-in-linear",
  "BackTop.duration": 500,
})

export default {
  name: "mm-back-top",
  components: {
    "ui-icon": Icon,
  },
  props: {
    visibilityHeight: {
      type: Number,
      default: () => config.get("BackTop.visibilityHeight"),
    },
    target: {
      type: Function,
      default() {
        return config.get("BackTop.target").call(this)
      },
    },
    transition: {
      type: String,
      default: () => config.get("BackTop.transition"),
    },
    duration: {
      type: Number,
      default: () => config.get("BackTop.duration"),
    },
  },
  data() {
    return {
      visible: false,
    }
  },
  computed: {
    realTarget() {
      return this.target() || (typeof window !== "undefined" ? window : null)
    },
  },
  mounted() {
    this.realTarget.addEventListener("scroll", this.handleScroll)
  },
  beforeDestroy() {
    this.realTarget.removeEventListener("scroll", this.handleScroll)
  },
  methods: {
    handleScroll() {
      const scrollTop = this.getScroll(this.realTarget, true)

      this.visible = scrollTop > this.visibilityHeight
    },
    getScroll(target, top) {
      if (typeof window === "undefined") {
        return 0
      }
      const prop = top ? "pageYOffset" : "pageXOffset"
      const method = top ? "scrollTop" : "scrollLeft"
      const isWindow = target === window
      let ret = isWindow ? target[prop] : target[method]
      // ie6,7,8 standard mode
      if (isWindow && typeof ret !== "number") {
        ret = window.document.documentElement[method]
      }
      return ret
    },
    scrollToTop() {
      let currentTop = this.getScroll(this.realTarget, true)
      scrollTop(this.realTarget, currentTop, 0, this.duration)
      this.$emit("on-click")
    },
  },
}
</script>
