<script setup lang="ts">
import type { PropType } from 'vue'

type ModeOptions = 'in-out' | 'out-in' | 'default' | undefined
type RenderOptions =
  | 'never'
  | 'always'
  | 'xs'
  | 'sm'
  | 'sm-down'
  | 'sm-up'
  | 'md'
  | 'md-down'
  | 'md-up'
  | 'lg'
  | 'lg-down'
  | 'lg-up'
  | 'xl'
  | 'xl-down'
  | 'xl-up'
  | 'xxl'
  | undefined

const vdisp = ref(useVDisplay())
const props = defineProps({
  fallback: {
    type: String,
    default: '',
  },
  render: {
    type: String as PropType<RenderOptions>,
    default: 'always',
  },
  appear: {
    type: Boolean,
    default: false,
  },
  mode: {
    type: String as PropType<ModeOptions>,
    default: 'out-in',
  },
  enter: {
    type: String,
    default: 'animate__fadeIn',
  },
  leave: {
    type: String,
    default: 'animate__fadeOut',
  },
})

const render = computed(() => {
  switch (props.render) {
    case 'never':
      return false
    case 'always':
      return true
    case 'xs':
      return vdisp.value.xs
    case 'sm':
      return vdisp.value.sm
    case 'sm-down':
      return vdisp.value.smAndDown
    case 'sm-up':
      return vdisp.value.smAndUp
    case 'md':
      return vdisp.value.md
    case 'md-down':
      return vdisp.value.mdAndDown
    case 'md-up':
      return vdisp.value.mdAndUp
    case 'lg':
      return vdisp.value.lg
    case 'lg-down':
      return vdisp.value.lgAndDown
    case 'lg-up':
      return vdisp.value.lgAndUp
    case 'xl':
      return vdisp.value.xl
    case 'xl-down':
      return vdisp.value.xlAndDown
    case 'xl-up':
      return vdisp.value.xlAndUp
    case 'xxl':
      return vdisp.value.xxl
    default:
      return false
  }
})
</script>

<template>
  <ClientOnly>
    <template #fallback>{{ props.fallback }}</template>

    <Transition
      :appear="props.appear"
      :mode="props.mode"
      :enter-active-class="`animate__animated ${props.enter}`"
      :leave-active-class="`animate__animated ${props.leave}`"
    >
      <slot v-if="render" />
    </Transition>
  </ClientOnly>
</template>
