<template>
    <div class="date-filter inline-flex h-8 items-center [&>.dp__main]:!inline-flex [&>.dp__main]:!items-center">
        <VueDatePicker
            ref="datepicker"
            v-model="internalValue"
            :week-picker="mode === 'week'"
            :enable-time-picker="false"
            :locale="frLocale"
            :format="formatDisplay"
            auto-apply
            :multi-calendars="false"
            position="left"
            teleport
            @update:model-value="onUpdate"
        >
            <template #trigger>
                <button
                    class="relative flex h-8 w-8 items-center justify-center rounded-full text-orange-500 transition hover:bg-orange-50"
                >
                    <Icon name="mdi:calendar-blank" size="20" />
                </button>
            </template>

            <template #action-buttons>
                <div class="flex gap-2 px-3 pb-2">
                    <button
                        class="rounded px-2 py-1 text-xs font-medium text-primary-500 hover:bg-primary-500/10 transition"
                        @click="selectToday"
                    >
                        {{ t('common.today') }}
                    </button>
                    <button
                        class="rounded px-2 py-1 text-xs font-medium text-primary-500 hover:bg-primary-500/10 transition"
                        @click="selectThisWeek"
                    >
                        {{ t('common.thisWeek') }}
                    </button>
                </div>
            </template>
        </VueDatePicker>
    </div>
</template>

<script setup lang="ts">
import { VueDatePicker } from '@vuepic/vue-datepicker'
import '@vuepic/vue-datepicker/dist/main.css'
import { fr as frLocale } from 'date-fns/locale'

const { t } = useI18n()

const props = defineProps<{
    modelValue?: Date | [Date, Date] | null
    placeholder?: string
    pickerMode?: 'day' | 'week'
}>()

const emit = defineEmits<{
    'update:modelValue': [value: Date | [Date, Date] | null]
}>()

const datepicker = ref<InstanceType<typeof VueDatePicker> | null>(null)
const mode = computed(() => props.pickerMode ?? 'week')
const internalValue = ref<Date | Date[] | null>(null)

const displayValue = computed(() => {
    if (!internalValue.value) return ''
    if (internalValue.value instanceof Date) {
        return formatFullDate(internalValue.value)
    }
    if (Array.isArray(internalValue.value) && internalValue.value.length >= 2) {
        const [start, end] = internalValue.value
        if (!start || !end) return ''
        return `${formatShortDate(start)} - ${formatShortDate(end)}`
    }
    return ''
})

function formatDisplay(dates: Date | Date[]): string {
    if (!dates) return ''
    if (dates instanceof Date) return formatFullDate(dates)
    if (!Array.isArray(dates)) return ''
    const valid = dates.filter((d): d is Date => d instanceof Date && !isNaN(d.getTime()))
    if (valid.length === 0) return ''
    if (valid.length === 1) return formatFullDate(valid[0])
    return `${formatShortDate(valid[0])} - ${formatShortDate(valid[1])}`
}

function formatFullDate(d: Date): string {
    if (!d || !(d instanceof Date) || isNaN(d.getTime())) return ''
    const day = String(d.getDate()).padStart(2, '0')
    const month = String(d.getMonth() + 1).padStart(2, '0')
    const year = d.getFullYear()
    return `${day}/${month}/${year}`
}

function formatShortDate(d: Date): string {
    if (!d || !(d instanceof Date) || isNaN(d.getTime())) return ''
    const day = String(d.getDate()).padStart(2, '0')
    const month = String(d.getMonth() + 1).padStart(2, '0')
    return `${day}/${month}`
}

function onUpdate(value: Date | Date[] | null) {
    if (!value) {
        emit('update:modelValue', null)
        return
    }

    if (mode.value === 'week' && Array.isArray(value)) {
        const valid = value.filter((d): d is Date => d instanceof Date && !isNaN(d.getTime()))
        if (valid.length >= 2) {
            emit('update:modelValue', [valid[0], valid[1]])
        }
    } else if (mode.value === 'day' && value instanceof Date) {
        emit('update:modelValue', value)
    }
}

function onClear() {
    internalValue.value = null
    datepicker.value?.closeMenu()
    emit('update:modelValue', null)
}

function selectToday() {
    const today = new Date()
    today.setHours(0, 0, 0, 0)
    internalValue.value = today
    emit('update:modelValue', today)
}

function selectThisWeek() {
    const now = new Date()
    const day = now.getDay()
    const monday = new Date(now)
    monday.setDate(now.getDate() - day + (day === 0 ? -6 : 1))
    monday.setHours(0, 0, 0, 0)
    const sunday = new Date(monday)
    sunday.setDate(monday.getDate() + 6)
    sunday.setHours(23, 59, 59, 999)
    internalValue.value = [monday, sunday]
    emit('update:modelValue', [monday, sunday])
}

watch(() => props.modelValue, (val) => {
    if (val === null || val === undefined) {
        internalValue.value = null
    } else if (Array.isArray(val)) {
        internalValue.value = [...val]
    } else {
        internalValue.value = val
    }
}, { immediate: true })
</script>

<style>
.date-filter .dp__theme_light {
    --dp-primary-color: #222783;
    --dp-primary-text-color: #fff;
    --dp-border-color: #d4d4d8;
    --dp-menu-border-color: #d4d4d8;
    --dp-border-color-hover: #222783;
    --dp-hover-color: #f3f4f8;
    --dp-font-size: 0.875rem;
}

.date-filter .dp__input_wrap {
    width: auto;
}

.date-filter .dp__main {
    font-family: inherit;
}
</style>
