<template>
  <slot 
    v-if="showState" 
    name="show" 
    :classNames="[
      className,
      animState ? `${name}-${animState}-active` : '',
    ]" 
  />
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref, watch } from 'vue';

/**
 * 简单过渡组件
 */
export interface TransitionProps {
  /**
   * 是否显示
   * @default false
   */
  show: boolean;
  /**
   * 是否启用动画
   * @default true
   */
  anim?: boolean;
  /**
   * 动画持续时间（毫秒）
   * @default 500
   */
  duration?: number,
  /**
   * 动画名称
   * @default 'v'
   */
  name?: string;
}

defineOptions({
  options: {
    virtualHost: true,
    styleIsolation: "shared",
  },
});

const props = withDefaults(defineProps<TransitionProps>(), {
  anim: true,
  name: 'v',
  duration: 500,
});

const className = ref('');
const showState = ref(false);
const animState = ref<'enter'|'leave'|''>('');

onMounted(() => {
  if (props.show)
    doAnim(true);
});
watch(() => props.show, (newState) => {
  doAnim(newState);
});

let timer = 0;

function clearTimer() {
  if (timer) {
    clearTimeout(timer);
    timer = 0;
  }
}
function doAnim(newState: boolean) {
  if (!props.anim || props.duration <= 10) {
    showState.value = newState;
    return;
  }
  clearTimer();
  if (newState) {
    showState.value = true;
    className.value = `${props.name}-enter-from`;
    animState.value = 'enter';
    setTimeout(() => {
      nextTick(() => {
        className.value = `${props.name}-enter-to`;
        timer = setTimeout(() => {
          animState.value = '';
          timer = 0;
        }, props.duration) as any;
      })
    }, 30);
  } else {
    showState.value = true;
    className.value = `${props.name}-leave-from`;
    animState.value = 'leave';
    nextTick(() => {
      className.value = `${props.name}-leave-to`;
      timer = setTimeout(() => {
        showState.value = false;
        animState.value = '';
        timer = 0;
      }, props.duration) as any;
    })
  }

}
</script>