import { reactive, ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { defineStore } from 'pinia';

export const useWeekdayStore = defineStore('weekdayStore', () => {
    const { t } = useI18n();

    const weekdays = [
        { code: 'sun', name: 'Sunday' },
        { code: 'mon', name: 'Monday' },
        { code: 'tue', name: 'Tuesday' },
        { code: 'wed', name: 'Wednesday' },
        { code: 'thu', name: 'Thursday' },
        { code: 'fri', name: 'Friday' },
        { code: 'sat', name: 'Saturday' },
    ];

    const monthCodes = [
        'jan',
        'feb',
        'mar',
        'apr',
        'may',
        'jun',
        'jul',
        'aug',
        'sep',
        'oct',
        'nov',
        'dec',
    ];

    const localeOrder = {
        es: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'],
        en: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
    };

    const weekdaysMap = reactive({});
    const localeWeekdays = ref([]);

    const initStore = () => {
        getWeekdaysMap();
    };

    const getWeekdaysMap = () => {
        if (Object.keys(weekdaysMap).length > 0) return weekdaysMap;

        weekdays.forEach((day, i) => {
            const obj = {
                ...day,
                index: i,
                char: day.name.substr(0, 1),
                abr: day.name.substr(0, 3),
            };
            weekdaysMap[day.code] = obj;
        });
    };

    const getLocales = computed(() => {
        // El día de mañana esto permitirá ordenar los weekdays en base a el locale si se lo desea reemplazando localeOrder.es por localeOrder[locale]
        const locales = [];
        for (let code of localeOrder.es) {
            const weekDay = weekdaysMap[code];
            const locale = t(`weekdays.${weekdaysMap[code].code}`);
            const obj = {
                ...weekDay,
                locale,
                localeChar: locale.substr(0, 1),
                localeAbr: locale.substr(0, 3),
            };
            locales.push(obj);
        }
        return locales;
    });

    const getLocalesMap = computed(() => {
        const locales = {};
        for (let code of localeOrder.es) {
            const weekDay = weekdaysMap[code];
            const locale = t(`weekdays.${weekdaysMap[code].code}`);
            const obj = {
                ...weekDay,
                locale,
                localeChar: locale.substr(0, 1),
                localeAbr: locale.substr(0, 3),
            };
            locales[weekDay.code] = obj;
        }
        return locales;
    });

    const getLocaleMonths = computed(() => {
        const locales = [];
        for (let code of monthCodes) {
            const obj = {
                code: code,
                locale: t(`months.${code}`),
            };
            locales.push(obj);
        }
        return locales;
    });

    /**
     * Transforms weekday set into an array whose indexes are weekday index
     * with selected days set to %true.
     *
     * @param {String} weekDays Weekday codes separated by commas
     * @return {Array<Boolean>} Array with selected days set to %true
     */
    const fromSet = (_weekDays) => {
        let wdays = [];

        if (_weekDays) {
            let codes = _weekDays.split(',');
            for (let code of codes) {
                let data = weekdaysMap[code];
                if (data) wdays[data.index] = true;
            }
        }

        return wdays;
    };

    /**
     * Perform the inverse operation of fromSet() method. Transforms an
     * array whose indexes are weekday index with selected days set to %true to
     * weekday codes separated by commas.
     *
     * @param {Array<Boolean>} _weekDays Array with selected days set to %true
     * @return {String} weekDays Weekday codes separated by commas
     */
    const toSet = (_weekDays) => {
        let wdays = [];

        if (_weekDays) {
            for (let i = 0; i < _weekDays.length; i++) {
                if (!_weekDays[i]) continue;
                let data = weekdays[i];
                if (data) wdays.push(data.code);
            }
        }

        return wdays.join(',');
    };

    return {
        initStore,
        weekdaysMap,
        localeWeekdays,
        getLocales,
        weekdays,
        monthCodes,
        getLocaleMonths,
        fromSet,
        toSet,
        getLocalesMap,
    };
});
