import _ from 'lodash'
import Vue from 'vue'
import * as icons from '@mdi/js'
import { VIcon } from 'vuetify/lib'
import BindsAttrs from 'vuetify/lib/mixins/binds-attrs'
import Colorable from 'vuetify/lib/mixins/colorable'
import Themeable from '../../mixins/themeable'

export default Vue.extend({
  name: 'SntIcon',
  components: { VIcon },
  mixins: [BindsAttrs, Colorable, Themeable],
  props: {
    icon: {
      type: String,
      default: undefined
    },
    color: {
      type: String,
      default: undefined
    },
    href: {
      type: String,
      default: ''
    },
    target: {
      type: String,
      default: '_blank'
    },
    size: {
      type: [String, Number],
      default: '24px'
    },
    dense: Boolean,
    disabled: Boolean,
    left: Boolean,
    right: Boolean
  },
  computed: {
    hasClickListener () {
      return Boolean(this.listeners$.click || this.listeners$['!click'])
    },
    iconName () {
      let iconName = this.icon
      if (this.$slots.default) iconName = this.$slots.default[0].text.trim()
      return _.camelCase(iconName)
    },
    svgIcon () {
      return icons[this.iconName]
    }
  },
  methods: {
    convertToUnit (str, unit = 'px') {
      if (str == null || str === '') {
        return undefined
      } if (_.isNaN(+str)) {
        return String(str)
      }
      return `${Number(str)}${unit}`
    },
    getSize () {
      return this.convertToUnit(this.size)
    },
    getDefaultData () {
      return {
        staticClass: 'v-icon notranslate',
        class: {
          'v-icon--disabled': this.disabled,
          'v-icon--left': this.left,
          'v-icon--link': this.hasClickListener,
          'v-icon--right': this.right,
          'v-icon--dense': this.dense
        },
        attrs: {
          'aria-hidden': !this.hasClickListener,
          'disabled': this.hasClickListener && this.disabled,
          'type': this.hasClickListener ? 'button' : undefined,
          ...this.attrs$
        },
        on: this.listeners$
      }
    },
    applyColors (data) {
      // eslint-disable-next-line no-param-reassign
      data.class = { ...data.class,
        ...this.themeClasses
      }
      this.setTextColor(this.color, data)
    },
    getSvgWrapperData () {
      const fontSize = this.getSize()
      const wrapperData = { ...this.getDefaultData(),
        style: fontSize ? {
          fontSize,
          height: fontSize,
          width: fontSize
        } : undefined
      }
      this.applyColors(wrapperData)
      return wrapperData
    },
    renderSvgIcon (icon, h) {
      const svgData = {
        class: 'v-icon__svg',
        attrs: {
          'xmlns': 'http://www.w3.org/2000/svg',
          'viewBox': '0 0 24 24',
          'role': 'img',
          'aria-hidden': true
        }
      }
      const size = this.getSize()
      if (size) {
        svgData.style = {
          fontSize: size,
          height: size,
          width: size
        }
      }
      return h(this.hasClickListener ? 'button' : 'span', this.getSvgWrapperData(), [h('svg', svgData, [h('path', {
        attrs: {
          d: icon
        }
      })])])
    }
  },
  render (h) {
    return h('span', {
      staticClass: 'snt-icon'
    }, [this.renderSvgIcon(this.svgIcon, h)])
  }
})
