<template>
    <div class="d-flex flex-column">
        <v-text-field v-bind="$attrs" ref="dateTimePickerRef" :model-value="dateTimeFormattedReadOnly" autocomplete="off"
            :placeholder="inputPlaceholder" :rules="rules" style="z-index: 10" @click="openDatePicker">
            <template #append-inner>
                <v-icon icon="mdi-calendar" @click.stop="openDatePicker" />
            </template>
        </v-text-field>
        <div class="w-100 d-flex align-end ga-3 hidden-input">
            <input ref="dateInput" :type="inputType" v-model="dateTime" :min="minValue" />
        </div>
    </div>
</template>

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

const prop = defineProps({
    rules: {
        type: Array as PropType<Array<any>>,
        default: () => []
    },
    placeholder: {
        type: String,
        default: 'DD/MM/YYYY, HH:MM AM/PM'
    },
    dateOnly: {
        type: Boolean,
        default: false
    },
    min: {
        type: String,
        default: undefined
    }
})

const { formatDateISO8601 } = useUtils()
const dateTime = defineModel<string | null>({ default: null }) //2025-10-10T13:09 format 
const dateTimeUTC = defineModel<string | null>('utc', { default: null }) // UTC format

const dateTimeFormattedReadOnly = ref<string | null>(null)
const inputType = computed(() => (prop.dateOnly ? 'date' : 'datetime-local'))


const minValue = computed(() => {
    if (!prop.min) return undefined
    if (/^\d{4}-\d{2}-\d{2}$/.test(prop.min)) {
        return prop.dateOnly ? prop.min : `${prop.min}T00:00`
    }
    return prop.min
})
const inputPlaceholder = computed(() => (
    prop.placeholder || (prop.dateOnly ? 'MM/DD/YYYY' : 'DD/MM/YYYY, HH:MM AM/PM')
))




const dateInput = ref<HTMLInputElement | null>(null)
const dateTimePickerRef = ref<HTMLInputElement | null>(null)

const isInitialLoad = ref(true)

function openDatePicker() {
    setTimeout(() => {
        dateInput.value?.showPicker?.()
    }, 0)
}

function validate() {
    (dateTimePickerRef.value as any)?.validate()
}

function convertToReadableFormat(dateStr: string): string {

    if (!dateStr) return "";

    const date = new Date(dateStr)
    if (Number.isNaN(date.getTime())) return "";

    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const year = date.getFullYear()

    if (prop.dateOnly) {
        return `${month}/${day}/${year}`
    }

    let hours = date.getHours()
    const minutes = String(date.getMinutes()).padStart(2, '0')

    const ampm = hours >= 12 ? 'PM' : 'AM'
    hours = hours % 12
    hours = hours ? hours : 12

    const formattedTime = `${String(hours).padStart(2, '0')}:${minutes} ${ampm}`

    return `${day}/${month}/${year}, ${formattedTime}`
}

function toDateOnlyInputValue(dateStr: string): string {
    if (!dateStr) return ''
    if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) return dateStr
    const date = new Date(dateStr)
    if (Number.isNaN(date.getTime())) return ''
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
}

function handleInitialDate(){
    const dateDefault = dateTime.value
    const dateUTC = dateTimeUTC.value
    if(dateDefault){
        dateTimeFormattedReadOnly.value = convertToReadableFormat(dateDefault)
        if (prop.dateOnly) {
            dateTimeUTC.value = toDateOnlyInputValue(dateDefault)
        } else {
            const localDate = new Date(dateDefault)
            dateTimeUTC.value = localDate.toISOString()
        }
    } else if (dateUTC){
        dateTimeFormattedReadOnly.value = convertToReadableFormat(dateUTC)
        if (prop.dateOnly) {
            dateTime.value = toDateOnlyInputValue(dateUTC)
        } else {
            const localDate = new Date(dateUTC)
            dateTime.value = formatDateISO8601(localDate)
        }
    } else {
        dateTimeFormattedReadOnly.value = null
    }
}


watch(dateTime, (dateVal) => {
    if (isInitialLoad.value) return // ignore the first run
    if (!dateVal) {
        dateTimeFormattedReadOnly.value = null;
        dateTimeUTC.value = null
        return
    }

    dateTimeFormattedReadOnly.value = convertToReadableFormat(dateVal)
    if (prop.dateOnly) {
        dateTimeUTC.value = toDateOnlyInputValue(dateVal)
    } else {
        const localDate = new Date(dateVal)
        dateTimeUTC.value = localDate.toISOString()
    }

}, { immediate: false })

  watch(dateTimeUTC, () => {
        handleInitialDate()
  }, { immediate: true})


onMounted(async () => {
    await nextTick()
    isInitialLoad.value = false
    // Wait until Vuetify renders its internal input
    const nativeInput = (dateTimePickerRef.value as any)?.$el?.querySelector('input')
    if (nativeInput) {
        nativeInput.addEventListener('click', (e: MouseEvent) => {
            e.stopPropagation()
            openDatePicker()
        })
    }
    
})


defineExpose({
    validate
})
</script>

<style scoped>
.hidden-input {
    opacity: 0;
    height: 0;
    width: 1px;
}
</style>
