<script setup lang="ts">
/**
 * @author xxl 
 * @email xxl.nice@foxmail.com
 * @createDate 2022-9-4
 * @updateDate 2023-8-3
 */
import { computed, onDeactivated, ref } from 'vue'
const props = defineProps<{
  type?: 'success' | 'primary' | 'danger' | 'warning' | 'default' | undefined
  disabled?: boolean
  loading?: boolean
  size?: 'mini' | 'small' | 'default' | undefined
  plain?: boolean
  block?: boolean
  /* 背景颜色 */
  background?: string
  /* 文本颜色 */
  color?: string
  /* 内边距 */
  padding?: string
  fontSize?: string
  countDown?: number | boolean
}>()
enum type {
  disabled = 'disabled',
  click = 'click',
  hint = 'hint',
  default = 'default',
}
/* 定义class前缀 */
const root = 'xxl-button-'
/* 按钮是否可用控制 */
const isDisable = ref<boolean>(false)
const canUse = computed<string>(() => {
  if (!isDisable.value) {
    return root + (props.disabled ? type.disabled : type.click)
  } else {
    return root + type.disabled
  }
})
/* 按钮类型控制 */
const buttonType = computed(() => {
  return (
    root +
    (props.plain ? 'plain-' : '') +
    (props.type && props.type != type.default ? props.type : type.hint)
  )
})
/* 按钮尺寸控制 */
const buttonSize = computed(() => {
  return root + 'size-' + (props.size ? props.size : type.default)
})
/* 倒计时 */
const setTime = ref<string>('')
const showTime = ref<boolean>(false)
let startTime: number = 0
let interval: number = 0
const emit = defineEmits(['click', 'errClick', 'timeout'])
function batterClick(event: MouseEvent) {
  if (canUse.value != root + type.disabled) {
    /* 如果开启计时 */
    if (props.countDown) {
      /* 计时器默认的时间为30秒 */
      let time = 30
      if (typeof props.countDown == 'number') {
        time = props.countDown
      }
      setTime.value = time.toString()
      startTime = new Date().getTime()
      /* 禁止按钮交互 切换为时间显示 */
      isDisable.value = showTime.value = true
      interval = setInterval(() => {
        let now: number = new Date().getTime()
        let has: number = time - (now - startTime) / 1000
        if (has <= 1) {
          /* 清空定时器并恢复交互效果 */
          clearInterval(interval)
          isDisable.value = showTime.value = false
          /* 定时结束事件 */
          emit('timeout')
        } else {
          setTime.value = has.toFixed()
        }
      }, 500)
    }
    emit('click', event)
  } else {
    emit('errClick', event)
  }
}
/* 销毁清除定时器 */
onDeactivated(()=>{
    clearInterval(interval)
})
</script>
<template>
  <div
    class="xxl-button"
    :style="{
      width: block ? '100%' : 'auto',
    }">
    <div
      @click="batterClick($event)"
      class="xxl-button-ctx xxl-center-flex xxl-clear-def"
      :class="[canUse, buttonType, buttonSize]"
      :style="{
        background,
        color,
        padding,
        fontSize,
      }">
      <div
        class="xxl-button-loading xxl-iconfont xxl-iconround-loading"
        v-if="props.loading"></div>
      <div v-show="!showTime">
        <slot> </slot>
      </div>
      <div class="xxl-center-flex" v-show="showTime">
        <span>{{ setTime + 's' }}</span>
        <span><slot name="countDown"></slot></span>
      </div>
    </div>
  </div>
</template>
<style lang="scss">
.xxl-button {
  display: inline-block;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  font-size: 1em;
  .xxl-button-ctx {
    border-radius: 5px;
  }
  .xxl-button-size-default {
    padding: 10px 15px;
    font-size: 1em;
  }
  .xxl-button-size-small {
    padding: 7px 11px;
    font-size: 0.8em;
  }
  .xxl-button-size-mini {
    padding: 3px 5px;
    font-size: 0.3em;
  }
  .xxl-button-loading {
    animation-name: xxl-button-loading;
    animation-duration: 1.5s;
    margin-right: 5px;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
  // 定义不同按钮不同样式
  $xxl-button-type-list: 'success', 'hint', 'warning', 'danger', 'primary';
  @for $i from 1 through length($xxl-button-type-list) {
    /* 普通按钮 */
    .xxl-button-#{nth($xxl-button-type-list, $i)} {
      color: var(--xxl-color-white);
      background: var(--xxl-color-#{nth($xxl-button-type-list, $i)});
    }
    /* 边框按钮 */
    .xxl-button-plain-#{nth($xxl-button-type-list, $i)} {
      background: var(--xxl-back-color);
      color: var(--xxl-text-color);
      border: 1px var(--xxl-color-#{nth($xxl-button-type-list, $i)}) solid;
    }
  }
  /* 按钮禁用 */
  .xxl-button-disabled {
    filter: grayscale(50%);
    &:hover {
      cursor: not-allowed;
    }
  }
  /* 按钮可用 */
  .xxl-button-click {
    &:hover {
      cursor: pointer;
      filter: brightness(1.1);
    }
  }
}
/* loading 动画 */
@keyframes xxl-button-loading {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
