<script setup lang="ts">
import datepicker from '@vuepic/vue-datepicker';

import type { CustomEvent } from '~/src/calendar/helpers.ts';
import { newDate } from '~/src/helpers.ts';

defineProps<{
    maxitems: number;
}>();

const { $translator: translator } = useNuxtApp();
const config = useConfig();
const { isDark } = useDark();

const today = newDate();

const modelValue = defineModel<CustomEvent[]>();

const showIconSelector = ref<number | false>(false);

const maxDaysInMonths: Record<number, number> = {
    1: 31,
    2: 29,
    3: 31,
    4: 30,
    5: 31,
    6: 30,
    7: 31,
    8: 31,
    9: 30,
    10: 31,
    11: 30,
    12: 31,
};

const formatDate = (date: Date): string => {
    return translator.translate(`calendar.dates.${date.getMonth() + 1}`, { day: date.getDate().toString() });
};

const prototype = () => {
    return { name: '', month: '', day: '', comment: '' };
};

const validation = (v: CustomEvent): string | null => {
    if (JSON.stringify(v) === JSON.stringify(prototype())) {
        return null;
    }

    if (!v.name) {
        return 'profile.calendar.customEvents.validation.missingName';
    }
    if (!v.month || !v.day) {
        return 'profile.calendar.customEvents.validation.missingDate';
    }
    if (v.day < 1 || v.day > maxDaysInMonths[v.month]) {
        return 'profile.calendar.customEvents.validation.invalidDate';
    }

    return null;
};
</script>

<template>
    <ListInput
        v-model="modelValue"
        :prototype="prototype()"
        :maxitems="maxitems"
        disable-sorting
    >
        <template #default="s">
            <datepicker
                :model-value="new Date(today.getFullYear(), s.val.month - 1, s.val.day)"
                :format="formatDate"
                auto-apply
                :enable-time-picker="false"
                :clearable="false"
                no-today
                vertical
                :dark="isDark"
                :locale="config.locale"
                @update:model-value="(date: Date) => {
                    s.val.month = date.getMonth() + 1;
                    s.val.day = date.getDate();
                }"
            />
            <button
                type="button"
                :class="['btn', 'btn-outline-secondary', showIconSelector === s.i ? 'btn-secondary text-white border' : '']"
                @click="showIconSelector = showIconSelector === s.i ? false : s.i"
            >
                <Icon :v="s.val.icon" />
            </button>
            <input
                v-model="s.val.name"
                class="form-control"
                required
                maxlength="24"
                :placeholder="$t('profile.calendar.customEvents.name')"
                @keyup="s.update(s.val)"
                @paste="$nextTick(() => s.update(s.val))"
                @change="s.update(s.val)"
            >
            <input
                v-model="s.val.comment"
                class="form-control"
                maxlength="128"
                :placeholder="$t('profile.calendar.customEvents.comment')"
                @keyup="s.update(s.val)"
                @paste="$nextTick(() => s.update(s.val))"
                @change="s.update(s.val)"
            >

            <IconSelector
                v-if="showIconSelector === s.i"
                class="hanging shadow shadow-lg border"
                @change="s.update({ ...s.val, icon: $event }); showIconSelector = false"
            />
        </template>
        <template #validation="s">
            <p v-if="validation(s.val)" class="small text-danger">
                <Icon v="exclamation-triangle" />
                <span class="ml-1">{{ $t(validation(s.val)!) }}</span>
            </p>
        </template>
    </ListInput>
</template>

<style lang="scss" scoped>
.hanging {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    max-width: 500px;
    z-index: 5000;
}
</style>
