<template>
  <button @click="clickHandler" :class="btnClass" :disabled="waiting || finished || hasError">
    <FontAwesomeIcon v-if="icon != null" :icon="icon" :spin="waiting" />
    <slot></slot>
  </button>
</template>
<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faSpinner, faExclamationTriangle, faCheck, faUserClock, faTrash } from '@fortawesome/free-solid-svg-icons'

import { mapState, mapGetters } from 'vuex'

export default {
  name: 'ApiCallButton',
  components: { FontAwesomeIcon },
  props: {
    outline: Boolean,
    small: Boolean,
    defaultCategory: {
      type: String,
      default: 'primary'
    },
    initialIcon: {
      type: String,
      validator(value) {
        return ['snooze', 'trash'].includes(value)
      }
    }
  },
  data () {
    return {
      waiting: false,
      finished: false
    }
  },
  computed: {
    ...mapState({
      hasError: state => !!state.apiError.status
    }),
    ...mapGetters(['loading']),
    semanticCategory () {
      if (this.hasError) return 'danger'
      else if (this.finished) return 'success'
      return this.defaultCategory
    },
    btnClass () {
      const semanticCategory = this.semanticCategory
      const category = `btn${this.outline ? '-outline' : ''}-${semanticCategory}`
      return {
        'btn': true,
        [category]: true,
        'btn-sm': this.small
      }
    },
    icon () {
      if (this.hasError) return faExclamationTriangle
      else if (this.waiting) return faSpinner
      else if (this.finished) return faCheck
      else if (this.initialIcon) {
        switch (this.initialIcon) {
          case 'snooze':
            return faUserClock
          case 'trash':
            return faTrash
          default:
            return null
        }
      }
      return null
    }
  },
  watch: {
    loading () {
      if (this.waiting && !this.loading) {
        this.waiting = false
        this.finished = true
        window.setTimeout(() => {
          this.finished = false
          this.$emit('complete')
        }, 2500)
      }
    }
  },
  methods: {
    clickHandler () {
      this.waiting = true
      this.$emit('click')
    }
  }
}
</script>
