<template>
    <div :class="['flex flex-col', wrapperClass]">
        <label
            v-if="label"
            :for="id"
            class="font-bold uppercase text-xl text-primary-700"
            :class="labelClass"
        >
            {{ label }}
        </label>
        <input
            :id="id"
            v-maska="'##/##/####'"
            type="text"
            inputmode="numeric"
            :value="displayValue"
            :placeholder="placeholder"
            :disabled="disabled"
            v-bind="attrs"
            class="w-full min-w-0 border-b border-primary-700 bg-transparent"
            :class="[
                sizeClass,
                isEmpty ? 'text-neutral-400' : 'text-primary-700',
                disabled ? 'cursor-not-allowed' : 'cursor-text',
                inputClass
            ]"
            @input="onInput"
        />
    </div>
</template>

<script setup lang="ts">
import { vMaska } from 'maska/vue'
import { computed, ref, useAttrs, watch } from 'vue'

defineOptions({ inheritAttrs: false })

const props = withDefaults(
    defineProps<{
        id?: string
        label?: string
        modelValue: string | null | undefined
        placeholder?: string
        disabled?: boolean
        size?: 'default' | 'compact'
        wrapperClass?: string
        labelClass?: string
        inputClass?: string
    }>(),
    {
        placeholder: 'JJ/MM/AAAA',
        disabled: false,
        size: 'default',
        wrapperClass: '',
        labelClass: '',
        inputClass: ''
    }
)

const emit = defineEmits<{
    (event: 'update:modelValue', value: string): void
}>()

const attrs = useAttrs()

const toDisplay = (iso: string | null | undefined): string => {
    if (!iso) return ''
    const parts = iso.split('-')
    if (parts.length !== 3) return ''
    const [year, month, day] = parts
    if (year.length !== 4 || month.length !== 2 || day.length !== 2) return ''
    return `${day}/${month}/${year}`
}

const toIso = (display: string): string | null => {
    const match = display.match(/^(\d{2})\/(\d{2})\/(\d{4})$/)
    if (!match) return null
    const [, day, month, year] = match
    return `${year}-${month}-${day}`
}

const displayValue = ref(toDisplay(props.modelValue))

watch(() => props.modelValue, (newIso) => {
    const expected = toDisplay(newIso)
    if (expected !== displayValue.value) {
        displayValue.value = expected
    }
})

const isEmpty = computed(() => !displayValue.value)
const sizeClass = computed(() =>
    props.size === 'compact'
        ? 'text-sm h-8 font-normal normal-case tracking-normal'
        : 'text-xl py-[6px]'
)

const onInput = (event: Event) => {
    const target = event.target as HTMLInputElement
    displayValue.value = target.value
    if (target.value === '') {
        emit('update:modelValue', '')
        return
    }
    const iso = toIso(target.value)
    emit('update:modelValue', iso ?? '')
}
</script>
