<template>
  <span
    :class="{
      [`mm-avatar-${shape}`]: shape,
      'mm-avatar-image': src && isImgExist,
      'mm-avatar-icon': icon,
      'mm-avatar-lg': size === 'large',
      'mm-avatar-md': size === 'medium',
      'mm-avatar-sm': size === 'small',
    }"
    class="mm-avatar">
    <template v-if="src && isImgExist">
      <img
        :src="src"
        @error="handleImgLoadError" />
    </template>
    <template v-else-if="icon">
      <ui-icon
        :name="icon"
        :size="false"></ui-icon>
    </template>
    <template v-else>
      <span
        ref="text"
        :style="scaleStyle"
        class="mm-avatar-text">
        {{ text }}
      </span>
    </template>
  </span>
</template>
<script>
import Icon from "../icon"
import config from "../../managers/config"

config.defaults({
  "Avatar.size": "default",
  "Avatar.shape": "circle",
})

export default {
  name: "mm-avatar",
  components: {
    "ui-icon": Icon,
  },
  props: {
    size: {
      type: String,
      default: () => config.get("Avatar.size"),
      validator(value) {
        return ["large", "medium", "default", "small"].includes(value)
      },
    },
    icon: {
      type: String,
      default: "",
    },
    src: {
      type: String,
      default: "",
    },
    text: {
      type: String,
      default: "",
    },
    shape: {
      type: String,
      default: () => config.get("Avatar.shape"),
      validator(value) {
        return ["circle", "square"].includes(value)
      },
    },
  },
  data() {
    return {
      isImgExist: true,
      scale: 1,
    }
  },
  computed: {
    scaleStyle() {
      if (this.scale !== 1 && this.$refs.text) {
        return {
          transform: `scale(${this.scale})`,
          position: "absolute",
          display: "inline-block",
          left: `calc(50% - ${Math.round(this.$refs.text.offsetWidth / 2)}px)`,
        }
      }

      return {}
    },
  },
  watch: {
    text: {
      immediate: true,
      handler() {
        this.$nextTick(() => {
          this.setScale()
        })
      },
    },
  },
  methods: {
    handleImgLoadError() {
      this.isImgExist = false
    },
    setScale() {
      const textNode = this.$refs.text
      if (textNode) {
        const shadowElem = this.$el.cloneNode()

        shadowElem.style.position = "absolute"
        shadowElem.style.visibility = "hidden"
        document.body.appendChild(shadowElem)

        const textWidth = textNode.offsetWidth
        const avatarWidth = shadowElem.getBoundingClientRect().width

        if (avatarWidth - 8 < textWidth) {
          this.scale = (avatarWidth - 8) / textWidth
        } else {
          this.scale = 1
        }

        document.body.removeChild(shadowElem)
      }
    },
  },
}
</script>
