<template>
  <span
    class="tw-flex tw-items-center tw-gap-[.33em] tw-text-xs tw-px-[.75em] tw-py-[0.33em] tw-leading-snug tw-rounded-full tw-shrink-[100] tw-min-w-[3em] tw-transition-opacity tw-ease-in-out tw-select-none"
    :class="[stateClasses, showIndicator ? 'tw-duration-300' : 'tw-duration-500 tw-opacity-0']"
    :style="{ visibility }"
    :role="showIndicator ? 'alert' : 'presentation'"
    :aria-hidden="!showIndicator"
    :aria-live="showIndicator ? 'polite' : undefined"
    @transitionstart="setVisibility"
    @transitionend="setVisibility"
  >
    <span
      class="tw-flex-none tw-w-fit tw-flex tw-items-center tw-justify-start *:tw-flex-none *:tw-size-[1.5em]"
    >
      <icon-fluent-spinner-ios-20-regular
        v-if="state === 'pending'"
        class="tw-animate-spin tw-opacity-75"
      />
      <icon-uis-check-circle v-else-if="state === 'success'" />
      <icon-uis-times-circle v-else-if="state === 'failure'" />
    </span>

    <span class="tw-truncate tw-min-w-0 tw-max-w-full tw-mr-[.25em]">
      {{ t(`saveIndicator.label.${state}`) }}
    </span>
  </span>
</template>

<script lang="ts" setup>
import { computed, ref, watchEffect } from 'vue'
import { useI18n } from '@/i18n'

defineOptions({
  compatConfig: { MODE: 3 },
})

const props = defineProps<{
  state: 'pending' | 'success' | 'failure'
}>()

const { t } = useI18n()

const showIndicator = ref(false)
const visibility = ref<'hidden' | 'visible'>('hidden')
let showIndicatorSetter: ReturnType<typeof setTimeout>

function setVisibility(event: TransitionEvent) {
  if (event.type === 'transitionstart' && showIndicator.value) visibility.value = 'visible'
  if (event.type === 'transitionend' && !showIndicator.value) visibility.value = 'hidden'
}

watchEffect(() => {
  clearTimeout(showIndicatorSetter)
  if (props.state === 'pending') showIndicator.value = true
  else if (props.state === 'failure') showIndicator.value = true
  else if (props.state === 'success')
    showIndicatorSetter = setTimeout(() => (showIndicator.value = false), 2 * 1000)
})

const stateClasses = computed(() => ({
  'tw-bg-gray-100 tw-text-gray-800': props.state === 'pending',
  'tw-bg-green-100 tw-text-green-800': props.state === 'success',
  'tw-bg-rose-100 tw-text-rose-800': props.state === 'failure',
}))
</script>