<template>
  <component
    :is="tagType"
    :class="[{
      'mm-button': true,
      'mm-button__circle': circle,
      'mm-button__ghost': ghost,
      [`mm-button__${type}`]: type,
      'mm-button--icon': isIconButton,
      'mm-button--block': block,
      'mm-button--loading': loading,
    }, themeClasses]"
    :disabled="disabled"
    v-bind="attrProps"
    v-on="listeners">
    <ui-icon
      v-if="icon && iconType === 'left'"
      :class="isIconButton ? '' : 'mm-button-icon__left'"
      :name="icon"
      :size="iconSize"></ui-icon>

    <div
      v-if="loading"
      class="mm-button-loading">
      <ui-loading :stroke-width="4"></ui-loading>
    </div>

    <slot></slot>

    <ui-icon
      v-if="icon && iconType === 'right'"
      :class="isIconButton ? '' : 'mm-button-icon__right'"
      :name="icon"
      :size="iconSize"></ui-icon>
  </component>
</template>

<script>
import Icon from "../icon"
import Loading from "../loading"
import themeSize from "../../mixins/theme-size"
import config from "../../managers/config"

config.defaults({
  "Button.type": "",
  "Button.iconType": "left",
  "Button.iconSize": "14px",
})

export default {
  name: "mm-button",
  components: {
    "ui-icon": Icon,
    "ui-loading": Loading,
  },
  mixins: [themeSize],
  inject: {
    buttonGroup: {
      from: "mm-button-group",
      default: null,
    },
  },
  props: {
    type: {
      type: String,
      validator(value) {
        return ["", "primary", "danger", "text"].includes(value)
      },
      default() {
        return this.buttonGroup ? this.buttonGroup.type : config.get("Button.type")
      },
    },
    ghost: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default() {
        return this.buttonGroup ? this.buttonGroup.disabled : false
      },
    },
    loading: {
      type: Boolean,
      default: false,
    },
    nativeType: {
      type: String,
      default: "button",
    },
    circle: {
      type: Boolean,
      default: false,
    },
    icon: {
      type: String,
      default: "",
    },
    iconType: {
      type: String,
      default: () => config.get("Button.iconType"),
    },
    iconSize: {
      type: String,
      default: () => config.get("Button.iconSize"),
    },
    block: {
      type: Boolean,
      default: false,
    },
    to: {
      type: [String, Object],
      default: "",
    },
    href: {
      type: String,
      default: "",
    },
  },
  computed: {
    attrProps() {
      let attrs = {
        ...this.$attrs,
      }
      if (this.to) {
        attrs.to = this.to
      } else if (this.href) {
        attrs.href = this.href
      } else if (this.nativeType) {
        attrs.type = this.nativeType
      }
      return attrs
    },
    tagType() {
      if (this.href) {
        return "a"
      }
      if (this.to) {
        return "router-link"
      }

      return "button"
    },
    isIconButton() {
      return !this.$slots.default
    },
    listeners() {
      const vm = this
      return Object.assign({}, this.$listeners, {
        click: function(event) {
          if (vm.loading) {
            return
          }
          vm.$emit("click", event)
        },
      })
    },
  },
}
</script>
