<template>
  <view
    v-if="pageShow"
    class="u-loading-page"
    :style="{
      zIndex: uZIndex,
    }"
    @touchmove.stop.prevent="() => {}"
  >
    <u-transition
      :show="show"
      :name="transitionName"
      :in-name="transitionInName"
      :out-name="transitionOutName"
      :duration="transitionDuration"
      width="100%"
      height="100%"
      @after="hidePage"
    >
      <view
        class="u-page-content u-flex-col u-col-center"
        :style="{
          backgroundColor: bgColor,
          paddingTop: boxPaddingTop + 'px',
        }"
        @touchmove.stop.prevent="() => {}"
      >
        <u-loading
          v-if="!$slots.loading"
          :mode="loadingMode"
          :color="loadingColor"
          :size="loadingSize"
        ></u-loading>
        <slot v-else name="loading" />

        <view v-if="tips" class="u-page-tips">{{ tips }}</view>

        <view v-if="!$slots.actions" class="u-flex u-row-center">
          <view
            v-if="useRetry && showRetry"
            class="u-retry"
            :hover-stay-time="150"
            @tap="handleRetry"
            hover-class="u-retry-hover"
          >
            重试
          </view>
        </view>
        <slot v-else name="actions" />
      </view>
    </u-transition>
  </view>
</template>

<script>
const sysInfo = uni.getSystemInfoSync()

export default {
  name: 'u-loading-page',
  props: {
    // 是否显示页面盒子组件
    show: {
      type: Boolean,
      default: false,
    },
    // 页面文字提示
    tips: {
      type: String,
      default: '加载中...',
    },
    // 一个z-index值，用于设置页面盒子这个组件的层次，因为页面可能会有其他定位的元素层级过高，导致此组件被覆盖
    zIndex: {
      type: [Number, String],
      default: '',
    },
    // 是否使用重试按钮
    useRetry: {
      type: Boolean,
      default: true,
    },
    // 重试按钮显示的延长时间
    retryDelay: {
      type: [Number, String],
      default: 5000,
    },
    // 背景颜色
    bgColor: {
      type: String,
      default: '#ffffff',
    },
		// 动画名称（inName/outName的合体）
    transitionName: {
      type: String,
      default: 'fade',
    },
		// 入场动画
    transitionInName: {
      type: String,
      default: '',
    },
		// 出场动画
    transitionOutName: {
      type: String,
      default: '',
    },
		// 动画执行时长
    transitionDuration: {
      type: [Number, String],
      default: 400,
    },
		// loading显示模式
    loadingMode: {
      type: String,
      default: 'sk-chase',
    },
		// loading颜色
    loadingColor: {
      type: String,
      default: '#2979ff',
    },
		// loading尺寸
    loadingSize: {
      type: [Number, String],
      default: 100,
    },
  },
  data() {
    return {
      pageShow: false, // 是否显示（避免show直接关掉，出场动画无法播放的问题）
      boxPaddingTop: parseInt(sysInfo.windowHeight * 0.3), // 内容距离顶部的间距
      showRetry: false, // 显示重试按钮
    }
  },

  computed: {
    uZIndex() {
      return this.zIndex ? this.zIndex : this.$u.zIndex.pageContainer
    },
    showRetryReady() {
      return this.useRetry && this.show
    },
  },

  watch: {
    show: {
      immediate: true,
      handler(newVal, oldVal) {
				// 关闭由动画结束控制，此处只做显示
        newVal && (this.pageShow = newVal)

        // 页面盒子显示后，关闭页面盒子组件时，使用重试按钮且还未显示重试按钮时，清除定时器
        if (
          !newVal &&
          oldVal &&
          this.useRetry &&
          !this.showRetry &&
          this.retryTimer
        ) {
          clearTimeout(this.retryTimer)
        }
      },
    },

		showRetryReady: {
      immediate: true,
      handler(val) {
				// 只有在显示时，开始定时显示 重试 按钮
        if (val) {
          this.retryTimer = setTimeout(() => {
            this.showRetry = true
          }, this.retryDelay)
        }
      },
    },
  },

  methods: {
    // 点击重试按钮，向父级传递事件
    handleRetry() {
      this.$emit('retry')
    },

    // 出场动画结束后关闭页面盒子
    hidePage() {
      this.pageShow = false
      this.showRetry = false
    },
  },
}
</script>

<style lang="scss" scoped>
.u-loading-page {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.u-page-content {
  background-color: #fff;
  width: 100%;
  height: 100%;
}
.u-page-tips {
  font-size: 28rpx;
  color: $u-main-color;
  line-height: 2;
  margin-top: 50rpx;
  margin-bottom: 100rpx;
}
.u-retry {
  border: 1px solid $u-tips-color;
  color: $u-tips-color;
  font-size: 28rpx;
  padding: 6rpx 30rpx;
  border-radius: 3px;
}
.u-retry-hover {
  color: #fff;
  background-color: $u-tips-color;
}
</style>
