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

import ZoneClosingTable from './ZoneClosingTable.vue';
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.sass';

import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import axios from 'axios';

const props = defineProps({
    year: {
        type: Number,
        required: true,
    },
    month: {
        type: Number,
        required: true,
    },
    monthDate: {
        type: Object,
        default: null,
    },
    geoExclusions: {
        type: Object,
        default: () => {},
    },
    exclusions: {
        type: Object,
        default: () => {},
    },
    daysMap: {
        type: Object,
        default: null,
    },
});

const emit = defineEmits(['onDateSelected']);

const { locale } = useI18n();
const route = useRoute();

const calendarRef = ref(null);
const weekdayStore = useWeekdayStore();
const showZoneClosingTable = ref(false);
const zoneClosingData = ref(null);
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 _monthDate = computed(() => date.formatDate(props.monthDate, 'YYYY-MM-DD'));

const isZoneDeliveryView = computed(() => route.name === 'ZoneDeliveryDays');

const onEventSelection = async ({ year, month, day }) => {
    if (!isZoneDeliveryView.value) return;

    const date = new Date(year, month - 1, day);
    const stamp = date.getTime();
    const events = props.daysMap[stamp];
    if (!events) return;

    const zoneIds = [];
    for (let event of events) zoneIds.push(event.zoneFk);

    const params = {
        zoneIds: zoneIds,
        date: date,
    };

    const { data } = await axios.post('Zones/getZoneClosing', params);
    zoneClosingData.value = data;
    showZoneClosingTable.value = true;
};

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

const getEventType = ({ year, month, day }) => {
    const stamp = new Date(year, month - 1, day).getTime();
    if (props.exclusions[stamp]) return 'exclusion';
    if (props.geoExclusions[stamp]) return 'geoExclusion';
    return 'event';
};

const getEventAttrs = ({ year, month, day }) => {
    const stamp = new Date(year, month - 1, day).getTime();

    let colorClass = '--event';
    if (props.geoExclusions[stamp]) colorClass = '--geoExcluded';
    else if (props.exclusions[stamp]) colorClass = '--excluded';

    const attrs = {
        class: colorClass,
        label: day,
    };

    return attrs;
};

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

const calendarHeaderTitle = computed(() => {
    return `${weekdayStore.getLocaleMonths[props.month - 1].locale} ${props.year}`;
});

const handleDateClick = (timestamp) => {
    if (isZoneDeliveryView.value) return;

    const event = getEventByTimestamp(timestamp);
    const { year, month, day } = timestamp;
    const date = new Date(year, month - 1, day);
    const stamp = date.getTime();
    const eventType = getEventType(timestamp);

    let geoIds = [];
    if (eventType === 'geoExclusion')
        geoIds = props.geoExclusions[stamp].map((geoExclusion) => geoExclusion.geoFk);

    emit('onDateSelected', {
        date,
        isNewMode: !event,
        event: event && event.length > 0 ? event[0] : null,
        eventType,
        geoIds,
    });
};
</script>

<template>
    <QCalendarMonthWrapper
        style="height: 290px; width: 290px"
        transparent-background
        view-customization="workerCalendar"
    >
        <template #header>
            <span class="full-width text-center text-body1 q-py-sm">{{
                calendarHeaderTitle
            }}</span>
        </template>
        <template #calendar>
            <QCalendarMonth
                ref="calendarRef"
                :model-value="_monthDate"
                show-work-weeks
                no-outside-days
                no-active-date
                :weekdays="[1, 2, 3, 4, 5, 6, 0]"
                short-weekday-label
                :locale="locale"
                :now="today"
                @click-date="handleDateClick($event.scope.timestamp)"
                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-if="getEventByTimestamp(timestamp)"
                        v-bind="{ ...getEventAttrs(timestamp) }"
                        @click="
                            isZoneDeliveryView
                                ? onEventSelection(timestamp)
                                : handleDateClick(timestamp)
                        "
                        rounded
                        dense
                        flat
                        class="calendar-event"
                        :class="{
                            '--today': isToday(timestamp),
                        }"
                    >
                        <QPopupProxy v-if="isZoneDeliveryView">
                            <ZoneClosingTable
                                v-if="zoneClosingData && zoneClosingData.length"
                                :rows="zoneClosingData"
                            />
                        </QPopupProxy>
                    </QBtn>
                </template>
            </QCalendarMonth>
        </template>
    </QCalendarMonthWrapper>
</template>

<style lang="scss">
.calendar-event {
    display: flex;
    justify-content: center;
    width: 32px;
    height: 32px;
    font-size: 13px;
    line-height: 1.715em;
    cursor: pointer;
    color: white;

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

    &.--event {
        background-color: $positive;
        color: black;
    }

    &.--excluded {
        background-color: $negative;
    }

    &.--geoExcluded {
        background-color: $primary;
    }

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