<script setup>
import { computed, onMounted, ref, watch, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n';

import ZoneDeliveryPanel from './ZoneDeliveryPanel.vue';
import ZoneDeliveryCalendar from './ZoneDeliveryCalendar.vue';

import { useStateStore } from 'stores/useStateStore';
import { useWeekdayStore } from 'src/stores/useWeekdayStore';
import { useArrayData } from 'src/composables/useArrayData';

const { t } = useI18n();
const stateStore = useStateStore();
const weekdayStore = useWeekdayStore();

const nMonths = ref(4);
const _date = ref(Date.vnNew());
const _data = ref(null);
const firstDay = ref(null);
const lastDay = ref(null);
const months = ref([]);
const days = ref({});
const exclusions = ref({});
const geoExclusions = ref({});
const events = ref([]);
const arrayData = useArrayData('ZoneDeliveryDays', {
    url: 'Zones/getEvents',
});
const { store } = arrayData;

const refreshEvents = () => {
    days.value = {};
    if (!data.value) return;

    let day = new Date(firstDay.value.getTime());

    while (day <= lastDay.value) {
        let stamp = day.getTime();
        let wday = day.getDay();
        let dayEvents = [];
        let _exclusions = exclusions.value[stamp] || [];

        if (events.value) {
            for (let event of events.value) {
                let match;
                switch (event.type) {
                    case 'day':
                        match = event.dated == stamp;
                        break;
                    default:
                        match =
                            event.wdays[wday] &&
                            (!event.started || stamp >= event.started) &&
                            (!event.ended || stamp <= event.ended);
                        break;
                }
                if (match && !_exclusions.find((e) => e.zoneFk == event.zoneFk)) {
                    dayEvents.push(event);
                }
            }
        }
        if (dayEvents.length) days.value[stamp] = dayEvents;

        day.setDate(day.getDate() + 1);
    }
};

const date = computed({
    get: () => _date.value,
    set: (value) => {
        _date.value = value;
        let stamp = value.getTime();

        firstDay.value = new Date(stamp);
        firstDay.value.setDate(1);

        lastDay.value = new Date(stamp);
        lastDay.value.setMonth(lastDay.value.getMonth() + nMonths.value);
        lastDay.value.setDate(0);

        months.value = [];
        for (let i = 0; i < nMonths.value; i++) {
            let monthDate = new Date(stamp);
            monthDate.setMonth(value.getMonth() + i);
            months.value.push(monthDate);
        }
        refreshEvents();
    },
});

const data = computed({
    get: () => {
        return _data.value;
    },
    set: (value) => {
        _data.value = value;

        value = value || {};

        events.value = value.events;
        function toStamp(date) {
            return date && new Date(date).setHours(0, 0, 0, 0);
        }

        exclusions.value = {};
        let _exclusions = value.exclusions;

        if (_exclusions) {
            for (let exclusion of _exclusions) {
                let stamp = toStamp(exclusion.dated);
                if (!exclusions[stamp]) exclusions.value[stamp] = [];
                exclusions.value[stamp].push(exclusion);
            }
        }

        geoExclusions.value = {};
        let _geoExclusions = value.geoExclusions;

        if (_geoExclusions) {
            for (let geoExclusion of _geoExclusions) {
                let stamp = toStamp(geoExclusion.dated);
                if (!geoExclusions[stamp]) geoExclusions.value[stamp] = [];
                geoExclusions.value[stamp].push(geoExclusion);
            }
        }

        let _events = value.events;
        if (_events) {
            for (let event of _events) {
                event.dated = toStamp(event.dated);
                event.ended = toStamp(event.ended);
                event.started = toStamp(event.started);
                event.wdays = weekdayStore.fromSet(event.weekDays || '');
            }
        }

        refreshEvents();
    },
});

watch(
    () => store.data,
    (value) => {
        data.value = value;
    },
    { immediate: true }
);

const getMonthNameAndYear = (date) => {
    const monthName = weekdayStore.getLocaleMonths[date.getMonth()].locale;
    const year = date.getFullYear();
    return `${monthName} ${year}`;
};

const headerTitle = computed(() => {
    if (!months.value?.length) return;

    const firstMonth = getMonthNameAndYear(months.value[0]);
    const lastMonth = getMonthNameAndYear(months.value[months.value.length - 1]);

    return `${firstMonth} - ${lastMonth}`;
});

const step = (direction) => {
    const _date = new Date(date.value);
    _date.setMonth(_date.getMonth() + nMonths.value * direction);
    date.value = _date;
};

onMounted(async () => {
    stateStore.rightDrawer = true;
    let initialDate = Date.vnNew();
    initialDate.setDate(1);
    initialDate.setHours(0, 0, 0, 0);
    date.value = initialDate;
    weekdayStore.initStore();
});

onUnmounted(() => arrayData.destroy());
</script>

<template>
    <template v-if="stateStore.isHeaderMounted()">
        <Teleport to="#actions-append">
            <div class="row q-gutter-x-sm">
                <QBtn
                    flat
                    @click="stateStore.toggleRightDrawer()"
                    round
                    dense
                    icon="menu"
                >
                    <QTooltip bottom anchor="bottom right">
                        {{ t('globals.collapseMenu') }}
                    </QTooltip>
                </QBtn>
            </div>
        </Teleport>
    </template>
    <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
        <QScrollArea class="fit text-grey-8">
            <ZoneDeliveryPanel />
        </QScrollArea>
    </QDrawer>
    <QPage class="q-pa-md flex justify-center">
        <QCard style="height: max-content">
            <div class="calendars-header">
                <QBtn
                    icon="arrow_left"
                    size="sm"
                    flat
                    class="full-height"
                    @click="step(-1)"
                />
                <span>{{ headerTitle }}</span>
                <QBtn
                    icon="arrow_right"
                    size="sm"
                    flat
                    class="full-height"
                    @click="step(1)"
                />
            </div>
            <div class="calendars-container">
                <ZoneDeliveryCalendar
                    v-for="(month, index) in months"
                    :key="index"
                    :month="month.getMonth() + 1"
                    :year="month.getFullYear()"
                    :month-date="month"
                    :geo-exclusions="geoExclusions"
                    :exclusions="exclusions"
                    :days-map="days"
                />
            </div>
        </QCard>
    </QPage>
</template>

<style lang="scss" scoped>
.calendars-header {
    height: 45px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: $primary;
    font-weight: bold;
    font-size: 16px;
}

.calendars-container {
    max-width: 800px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
}
</style>
