<template>
  <form @submit.prevent="$emit('submit')">
    <div class="mb-6 relative">
      <label
        for="code"
        class="block text-sm font-medium mb-2"
        :class="[isDarkMode ? 'text-gray-300' : 'text-gray-800']"
        >{{ t('retrieve.codeInput.label') }}</label
      >
      <div class="relative">
        <input
          id="code"
          v-model="code"
          type="text"
          inputmode="text"
          autocomplete="one-time-code"
          ref="codeInput"
          class="w-full px-4 py-3 rounded-lg placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition duration-300 pr-10"
          :class="[
            isDarkMode ? 'bg-gray-700 bg-opacity-50' : 'bg-gray-100',
            { 'ring-2 ring-red-500': error },
            isDarkMode ? 'text-gray-300' : 'text-gray-800'
          ]"
          :placeholder="t('retrieve.codeInput.placeholder')"
          required
          :aria-invalid="error"
          :readonly="inputStatus.readonly"
          maxlength="5"
          @focus="isInputFocused = true"
          @blur="isInputFocused = false"
        />
        <div
          v-if="inputStatus.loading"
          class="absolute inset-y-0 right-0 flex items-center pr-3"
        >
          <span
            class="animate-spin rounded-full h-5 w-5 border-b-2 border-indigo-500"
          ></span>
        </div>
      </div>
      <div
        class="absolute -bottom-0.5 left-2 h-0.5 bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 transition-all duration-300 ease-in-out"
        :class="{ 'w-97-100': isInputFocused, 'w-0': !isInputFocused }"
      ></div>
    </div>
    <button
      type="submit"
      class="group relative w-full overflow-hidden rounded-lg bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 px-4 py-3 font-bold text-white transition duration-300 hover:from-indigo-600 hover:via-purple-600 hover:to-pink-600 hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-opacity-50 disabled:cursor-not-allowed disabled:opacity-50 motion-safe:hover:scale-[1.02] disabled:hover:scale-100"
      :disabled="inputStatus.loading || code.trim().length !== 5"
    >
      <span class="flex items-center justify-center relative z-10">
        <span>{{ inputStatus.loading ? t('common.loading') : t('retrieve.submit') }}</span>
        <ArrowRightIcon
          class="w-5 h-5 ml-2 transition-transform duration-300 transform group-hover:translate-x-1"
        />
      </span>
      <span
        class="absolute top-0 left-0 w-full h-full bg-gradient-to-r from-pink-500 via-purple-500 to-indigo-500 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
      ></span>
    </button>
  </form>
</template>

<script setup lang="ts">
import { ref, inject, computed } from 'vue'
import { ArrowRightIcon } from 'lucide-vue-next'
import { useI18n } from 'vue-i18n'

const { t } = useI18n()

interface InputStatus {
  readonly: boolean
  loading: boolean
}

interface Props {
  inputStatus: InputStatus
  error?: boolean
  modelValue: string
}

interface Emits {
  submit: []
  'update:modelValue': [value: string]
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const isDarkMode = inject('isDarkMode')
const code = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})
const isInputFocused = ref(false)
const codeInput = ref<HTMLInputElement>()

defineExpose({
  focus: () => codeInput.value?.focus()
})
</script>

<style scoped>
.w-97-100 {
  width: calc(100% - 1rem);
}
</style>