<template>
  <div class="x-loading" :style="outputStyle" :className="className">
    <div v-if="displayVisable" class="mask">
      <x-svg-icon class="x-loading-img" name="loading"></x-svg-icon>
    </div>
    <div v-else-if="networkError" class="x-loading-network-error">
      <x-svg-icon :name="svgName"></x-svg-icon>
      <span class="x-loading-error-text">
        {{ orderText }}
        <el-button
          class="x-loading-refresh-btn"
          type="text"
          :style="linkStyle"
          @click="handleRefresh"
          >{{ orderLink }}</el-button
        >
      </span>
    </div>
    <template v-if="isShow">
      <slot></slot>
    </template>
  </div>
</template>

<script>
export default {
  name: 'XLoading',
  props: {
    visible: {
      type: Boolean,
      default: function() {
        return false
      }
    },
    timer: {
      type: Number,
      default: function() {
        return 500
      }
    },
    networkError: {
      type: Boolean,
      default: function() {
        return false
      }
    },
    errorName: {
      type: String,
      default: function() {
        return ''
      }
    },
    setStyle: {
      type: String,
      default: 'parent'
    },
    orderText: {
      type: String,
      default: '网络不给力，请稍后'
    },
    orderLink: {
      type: String,
      default: '重试'
    },
    svgName: {
      type: String,
      default: 'x-lib-network-error'
    },
    width: {
      type: String,
      default: ''
    },
    height: {
      type: String,
      default: ''
    },
    className: {
      type: String,
      default: function() {
        return ''
      }
    },
    existOnly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      displayVisable: false,
      timestamp: 0
    }
  },
  computed: {
    outputStyle() {
      let style = {}
      if (this.width && this.height) {
        style.width = this.width
        style.height = this.height
      } else if (this.setStyle === 'small') {
        style.width = '200px'
        style.height = '150px'
      } else if (this.setStyle === 'large') {
        style.width = '800px'
        style.height = '600px'
      } else if (this.setStyle === 'parent') {
        style.width = '100%'
        style.height = '100%'
      } else if (this.setStyle === 'middle') {
        style.width = '400px'
        style.height = '300px'
      }
      return style
    },
    linkStyle() {
      return {
        border: 0,
        'font-size': '12px'
      }
    },
    isShow() {
      return (
        (!this.displayVisable && !this.networkError) || (this.displayVisable && !this.existOnly)
      )
    }
  },
  watch: {
    visible: {
      handler: function(newVal, oldVal) {
        if (newVal) {
          this.timestamp = new Date().getTime()
          this.displayVisable = true
        } else {
          const endTimestamp = new Date().getTime()
          const temp = endTimestamp - this.timestamp
          if (temp >= this.timer) {
            this.displayVisable = false
            if (this.networkError === false) {
              this.$emit('loading-done')
            }
          } else {
            const timeout = setTimeout(() => {
              this.displayVisable = false
              this.$forceUpdate()
              clearTimeout(timeout)
              if (this.networkError === false) {
                this.$emit('loading-done')
              }
            }, this.timer - temp)
          }
        }
      },
      immediate: true
    }
  },
  methods: {
    handleRefresh() {
      this.$emit('loading-refresh', this.errorName)
    }
  }
}
</script>
