<script setup>
import {NDatePicker, NIcon, NFlex, NTooltip, NSkeleton} from 'naive-ui'
import {computed, ref} from "vue";
import {router} from "@inertiajs/vue3";
import {TbCalendar} from 'vue-icons-plus/tb'
import {formatRussianDate, formatRussianDateRange} from "../Utils/dateFormatter.js";
import {useReportStore} from "../Stores/report.js";
import {formatDistanceStrict} from "date-fns";

const props = defineProps({
    // Пользователь с ролью админ или зав
    isHeadOrAdmin: {
        type: Boolean,
        default: false
    },
    date: {
        type: [Number, Array]
    },
    isShowCurrentDateSwitch: {
        type: Boolean,
        default: false
    },
    hint: {
        type: Boolean,
        default: false
    }
})

const reportStore = useReportStore()
const isLoading = ref(false)
const showCalendar = ref(false)
const modelValue = defineModel('date')

// Всегда используем диапазон, но для врача показываем как один день
const calendarType = 'daterange'

// Форматированное значение для отображения
const formattedValue = computed(() => {
    const value = modelValue.value

    if (!value || !Array.isArray(value) || !value[0] || !value[1]) {
        return ''
    }

    // Для админа/зав. показываем диапазон
    if (props.isHeadOrAdmin) {
        return formatRussianDateRange(value)
    }

    // Для врача показываем одну дату (конец смены)
    return formatRussianDate(value[1])
})

// Проверяем, выбран ли один день
const isOneDaySelected = computed(() => {
    if (!modelValue.value || !Array.isArray(modelValue.value)) return false
    const [start, end] = modelValue.value
    if (!start || !end) return false

    const diff = formatDistanceStrict(start, end)
    return diff === '0 seconds' || diff === '1 day'
})

// Блокировка будущих дат с учетом смен 09:00-09:00
const isDateDisabled = (ts) => {
    const date = new Date(ts)
    const now = new Date()

    // Получаем сегодняшнюю дату без времени
    const today = new Date()
    today.setHours(0, 0, 0, 0)

    // Если выбранная дата меньше сегодня - разрешаем (прошлые даты)
    if (date < today) {
        return false
    }

    // Получаем текущий час
    const currentHour = now.getHours()

    // Если сейчас меньше 09:00, то максимальная дата - сегодня
    // Если сейчас 09:00 или больше, то максимальная дата - завтра
    const maxDaysOffset = currentHour < 9 ? 0 : 1

    const maxDate = new Date()
    maxDate.setDate(maxDate.getDate() + maxDaysOffset)
    maxDate.setHours(23, 59, 59, 999)

    // Блокируем только даты строго больше максимальной
    return date > maxDate
}

// Получить начало смены для даты
const getShiftStart = (date) => {
    const shiftStart = new Date(date)
    shiftStart.setHours(9, 0, 0, 0)
    return shiftStart
}

// Получить конец смены для даты
const getShiftEnd = (date) => {
    const shiftEnd = new Date(date)
    shiftEnd.setHours(9, 0, 0, 0)
    shiftEnd.setDate(shiftEnd.getDate() + 1)
    return shiftEnd
}

// Получить текущую смену
const getCurrentShift = () => {
    const now = new Date()
    const today9am = new Date()
    today9am.setHours(9, 0, 0, 0)

    if (now < today9am) {
        const start = new Date(today9am)
        start.setDate(start.getDate() - 1)
        return [start, today9am]
    } else {
        const end = new Date(today9am)
        end.setDate(end.getDate() + 1)
        return [today9am, end]
    }
}

// Получить предыдущую смену
const getPreviousShift = () => {
    const now = new Date()
    const today9am = new Date()
    today9am.setHours(9, 0, 0, 0)

    if (now < today9am) {
        const start = new Date(today9am)
        start.setDate(start.getDate() - 2)
        const end = new Date(today9am)
        end.setDate(end.getDate() - 1)
        return [start, end]
    } else {
        const start = new Date(today9am)
        start.setDate(start.getDate() - 1)
        return [start, today9am]
    }
}

// Шорткаты
const shortcuts = {
    'Сегодня': () => getCurrentShift(),
    'Вчера': () => getPreviousShift(),
    'За 7 дней': () => {
        const currentShift = getCurrentShift()
        const end = currentShift[1]
        const start = new Date(end)
        start.setDate(start.getDate() - 7)
        start.setHours(9, 0, 0, 0)
        return [start, end]
    },
    'За 30 дней': () => {
        const currentShift = getCurrentShift()
        const end = currentShift[1]
        const start = new Date(end)
        start.setDate(start.getDate() - 30)
        start.setHours(9, 0, 0, 0)
        return [start, end]
    },
    'Текущий год': () => {
        const currentShift = getCurrentShift()
        const end = currentShift[1]
        const start = new Date(end.getFullYear(), 0, 1)
        start.setHours(9, 0, 0, 0)
        return [start, end]
    }
}

// Обработка изменения даты
const handleDateUpdate = (value) => {
    if (!value || !Array.isArray(value) || !value[0] || !value[1]) return

    isLoading.value = true

    // Нормализуем в мс-таймстемпы: шорткаты/быстрый выбор отдают Date, календарь — число.
    // Иначе Date уходит в URL как ISO (...Z), а число остаётся числом → рассинхрон startAt/endAt.
    const toTs = (v) => v instanceof Date ? v.getTime() : Number(v)
    let finalValue = [toTs(value[0]), toTs(value[1])]

    // Для врача: если выбран диапазон, преобразуем в один день (берем конец смены)
    if (!props.isHeadOrAdmin) {
        // Если выбрано несколько дней, берем последний день
        finalValue = [finalValue[1], finalValue[1]]
    }

    modelValue.value = finalValue

    // Дебаунс для предотвращения двойной отправки
    setTimeout(() => {
        if (JSON.stringify(modelValue.value) === JSON.stringify(finalValue)) {
            reportStore.openedCollapsible = []
            router.reload({
                data: {
                    startAt: finalValue[0],
                    endAt: finalValue[1]
                },
                onFinish: () => {
                    isLoading.value = false
                }
            })
        }
    }, 100)
}

// Кнопка "Сегодня/Текущий год"
const onQuickSelect = () => {
    const currentShift = getCurrentShift()

    if (isOneDaySelected.value) {
        // Если выбран один день, переключаем на текущий год
        const end = currentShift[1]
        const start = new Date(end.getFullYear(), 0, 1)
        start.setHours(9, 0, 0, 0)
        handleDateUpdate([start, end])
    } else {
        // Если выбран диапазон, переключаем на сегодня
        handleDateUpdate(currentShift)
    }

    showCalendar.value = false
}

// Текст для кнопки
const quickButtonText = computed(() => {
    return isOneDaySelected.value ? 'Текущий год' : 'Сегодня'
})
</script>

<template>
    <NTooltip v-if="hint" placement="right" width="220" :arrow="false">
        <template #trigger>
            <div v-bind="$attrs" class="relative inline-flex items-center">
                <template v-if="isLoading">
                    <NSkeleton width="240" height="20" round />
                </template>
                <template v-else>
                    <div
                        v-if="formattedValue"
                        class="font-medium leading-3 cursor-pointer"
                        @click="showCalendar = true"
                    >
                        {{ formattedValue }}
                    </div>

                    <NDatePicker
                        v-model:value="modelValue"
                        v-model:show="showCalendar"
                        class="opacity-0 absolute! inset-x-0 bottom-full -translate-y-1/2"
                        placement="top-start"
                        :shortcuts="shortcuts"
                        :is-date-disabled="isDateDisabled"
                        input-readonly
                        bind-calendar-months
                        type="daterange"
                        @update:value="handleDateUpdate"
                    >
                    </NDatePicker>

                    <div class="cursor-pointer p-2 flex items-center justify-center" @click="showCalendar = true">
                        <NIcon size="20">
                            <TbCalendar />
                        </NIcon>
                    </div>
                </template>
            </div>
        </template>
        <span class="text-sm">Учёт времени с 09:00 текущих суток по 09:00 следующих суток</span>
    </NTooltip>
    <div v-else v-bind="$attrs" class="relative inline-flex items-center">
        <template v-if="isLoading">
            <NSkeleton width="240" height="20" round />
        </template>
        <template v-else>
            <div
                v-if="formattedValue"
                class="font-medium leading-3 cursor-pointer"
                @click="showCalendar = true"
            >
                {{ formattedValue }}
            </div>

            <NDatePicker
                v-model:value="modelValue"
                v-model:show="showCalendar"
                class="opacity-0 absolute! inset-x-0 bottom-full -translate-y-1/2"
                placement="top-start"
                :shortcuts="shortcuts"
                :is-date-disabled="isDateDisabled"
                input-readonly
                bind-calendar-months
                type="daterange"
                @update:value="handleDateUpdate"
            >
            </NDatePicker>

            <div class="cursor-pointer p-2 flex items-center justify-center" @click="showCalendar = true">
                <NIcon size="20">
                    <TbCalendar />
                </NIcon>
            </div>
        </template>
    </div>
</template>

<style scoped>
:deep(.n-input) {
    position: absolute;
    pointer-events: none;
}
</style>
