<script setup>
import { onBeforeMount, ref, watch, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { date } from 'quasar';
import { useRoute } from 'vue-router';

import QCalendarMonthWrapper from 'src/components/ui/QCalendarMonthWrapper.vue';
import { QCalendarMonth } from '@quasar/quasar-ui-qcalendar/src/index.js';
import '@quasar/quasar-ui-qcalendar/src/QCalendarVariables.scss';

import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import useNotify from 'src/composables/useNotify.js';
import axios from 'axios';

const props = defineProps({
    year: {
        type: Number,
        required: true,
    },
    month: {
        type: Number,
        required: true,
    },
    absenceType: {
        type: Object,
        default: null,
    },
    businessFk: {
        type: Number,
        default: null,
    },
    events: {
        type: Object,
        default: null,
    },
});

const emit = defineEmits(['refresh', 'onDeletedEvent']);

const route = useRoute();
const { t } = useI18n();
const { notify } = useNotify();
const { locale } = useI18n();

const calendarRef = ref(null);
const weekdayStore = useWeekdayStore();
const selectedDate = ref();
const calendarEventDates = [];
const today = ref(date.formatDate(Date.vnNew(), 'YYYY-MM-DD'));
const todayTimestamp = computed(() => {
    const date = Date.vnNew();
    date.setHours(0, 0, 0, 0);
    return date.getTime();
});
const _year = computed(() => props.year);

const updateSelectedDate = (year) => {
    const _date = new Date(year, props.month - 1, 1);
    selectedDate.value = date.formatDate(_date, 'YYYY-MM-DD');
};

const createEvent = async (date) => {
    const params = {
        dated: date,
        absenceTypeId: props.absenceType.id,
        businessFk: props.businessFk,
    };

    const { data } = await axios.post(`Workers/${route.params.id}/createAbsence`, params);

    if (data) emit('refresh');
};

const editEvent = async (event) => {
    const absenceType = props.absenceType;
    const params = {
        absenceId: event.absenceId,
        absenceTypeId: absenceType.id,
    };
    const { data } = await axios.patch(
        `Workers/${route.params.id}/updateAbsence`,
        params,
    );

    if (data) emit('refresh');
};

const deleteEvent = async (event, date) => {
    const params = { absenceId: event.absenceId };
    const { data } = await axios.delete(`Workers/${route.params.id}/deleteAbsence`, {
        params,
    });

    if (data) emit('onDeletedEvent', date.getTime());
};

const handleDateSelected = (date) => {
    if (!props.absenceType) {
        notify(t('Choose an absence type from the right menu'), 'warning');
        return;
    }

    const { year, month, day } = date.scope.timestamp;
    const _date = new Date(year, month - 1, day);
    const stamp = _date.getTime();
    const event = props.events[stamp];

    if (!event) createEvent(_date);
};

const handleEventSelected = async (event, { year, month, day }) => {
    if (!props.absenceType) {
        notify(t('Choose an absence type from the right menu'), 'warning');
        return;
    }

    const date = new Date(year, month - 1, day);
    if (!event?.absenceId) await createEvent(date);
    else if (event.type == props.absenceType.code) deleteEvent(event, date);
    else editEvent(event);
};

const getEventByTimestamp = ({ year, month, day }) => {
    const stamp = new Date(year, month - 1, day).getTime();
    return props.events[stamp] || null;
};

const getEventAttrs = (timestamp) => {
    const event = getEventByTimestamp(timestamp);
    if (!event) return {};

    const { name, color, isFestive, type } = event;

    // Atributos a asignar a cada slot que representa un evento en el calendario

    const attrs = {
        title: name,
        style: color ? `background-color: ${color};` : ``,
        label: timestamp.day,
    };

    if (isFestive) {
        attrs.class = '--festive';
        attrs.label = timestamp.day;
    } else attrs.class = `--${type}`;

    return attrs;
};

const isToday = (timestamp) => {
    const { year, month, day } = timestamp;
    return todayTimestamp.value === new Date(year, month - 1, day).getTime();
};
onBeforeMount(() => {
    updateSelectedDate(_year.value);
});

watch(_year, (newValue) => {
    updateSelectedDate(newValue);
});
</script>

<template>
    <QCalendarMonthWrapper
        style="height: 290px; width: 310px"
        class="outline"
        bordered
        transparent-background
        view-customization="workerCalendar"
    >
        <template #header>
            <span class="full-width text-center text-body1 q-py-sm">{{
                weekdayStore.getLocaleMonths[$props.month - 1].locale
            }}</span>
        </template>
        <template #calendar>
            <QCalendarMonth
                ref="calendarRef"
                v-model="selectedDate"
                @click-date="handleDateSelected"
                show-work-weeks
                no-outside-days
                :selected-dates="calendarEventDates"
                no-active-date
                :weekdays="[1, 2, 3, 4, 5, 6, 0]"
                short-weekday-label
                :locale="locale"
                :now="today"
                mini-mode
            >
                <template #day="{ scope: { timestamp } }">
                    <!-- Este slot representa cada día del calendario y muestra un botón representando el correspondiente evento -->
                    <QBtn
                        v-bind="{ ...getEventAttrs(timestamp) }"
                        @click="
                            handleEventSelected(getEventByTimestamp(timestamp), timestamp)
                        "
                        rounded
                        dense
                        flat
                        class="calendar-event"
                        :class="{
                            '--today': isToday(timestamp),
                        }"
                    />
                </template>
            </QCalendarMonth>
        </template>
    </QCalendarMonthWrapper>
</template>

<style lang="scss">
.q-calendar-month__day:has(.q-calendar-month__day--content):has(.q-btn.--festive)
    .q-calendar-month__day--label__wrapper
    button {
    color: transparent;
}
.calendar-event {
    display: flex;
    justify-content: center;
    width: 32px;
    height: 32px;
    font-size: 13px;
    line-height: 1.715em;
    cursor: pointer;

    &.--today {
        border: 2px solid $info;
    }

    &.--festive {
        color: $negative;
    }

    &.--holiday {
        & > span:nth-child(2) .block {
            color: white;
        }
    }

    &:hover {
        opacity: 0.8;
    }
}
</style>

<i18n>
es:
    Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
</i18n>
