/*!
 * Built with Stencil
 * By PostNord.
 */
import dayjs from "dayjs";
import weekOfYear from "dayjs/plugin/weekOfYear";
import customParseFormat from "dayjs/plugin/customParseFormat";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
import toObject from "dayjs/plugin/toObject";
import "dayjs/locale/sv.js";
import "dayjs/locale/en.js";
import "dayjs/locale/da.js";
import "dayjs/locale/fi.js";
import "dayjs/locale/nb.js";
dayjs.extend(weekOfYear);
dayjs.extend(customParseFormat);
dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.extend(toObject);
const CALENDAR = 'calendar';
const MONTHS = 'months';
const YEARS = 'years';
export { CALENDAR, MONTHS, YEARS };
export function getToday() {
    return dayjs();
}
export function getDayjsObject({ year, month, date }) {
    return dayjs().set('year', year).set('month', month).set('date', date);
}
/** Validate the date. */
export function validateDate(value, format) {
    if (!value)
        return false;
    const val = typeof value === 'string' ? value : getDayjsObject(value);
    return dayjs(val, format, true).isValid();
}
/**
 * Get the Dayjs object with the value & format param.
 **/
export function getDate(value, format) {
    const val = typeof value === 'string' ? value : getDayjsObject(value);
    return dayjs(val, format);
}
/** Get a readable i18n format of the date. */
export function getReadableDate(date, lang, format) {
    const data = getDateJs(date);
    return data.locale(lang === 'no' ? 'nb' : lang).format(format);
}
export function getDateJs({ year, month, date, day }) {
    const dateObject = dayjs().set('y', year).set('M', month).set('D', date);
    if (typeof day === 'number')
        return dateObject.set('d', day);
    return dateObject;
}
export function getDateObject(data, format) {
    const dateObj = typeof data === 'string' ? getDate(data, format) : data;
    const year = dateObj.get('year');
    const month = dateObj.get('month');
    const date = dateObj.get('date');
    const day = dateObj.get('day');
    return {
        year,
        month,
        date,
        day,
    };
}
export function getDiff(from, to, format) {
    const dateFrom = getDate(from, format);
    const dateTo = getDate(to, format);
    return dateTo.diff(dateFrom, 'd');
}
export function isBefore(data, max, format, type) {
    const date = getDate(data, format);
    const dateMax = getDate(max, format);
    return date.isSameOrBefore(dateMax, type);
}
export function isAfter(data, min, format, type) {
    const date = getDate(data, format);
    const dateMin = getDate(min, format);
    return date.isSameOrAfter(dateMin, type);
}
export function selectedDate(dateOne, dateTwo, format, type) {
    if (!validateDate(dateOne, format) || !validateDate(dateTwo, format))
        return false;
    let date = getDate(dateOne, format);
    let compare = getDate(dateTwo, format);
    if (type === 'month') {
        date = date.set('year', 2000);
        compare = compare.set('year', 2000);
    }
    return date.isSame(compare, type);
}
export function modifyDate({ data, amount = 1, unit, minus, plus, }) {
    if (minus)
        return data.subtract(amount, unit);
    if (plus)
        return data.add(amount, unit);
    return data;
}
/** Set another year for the value. */
export function setYear({ year, minus = false, plus = false, }) {
    const data = dayjs().set('year', year);
    return modifyDate({ data, unit: 'y', plus, minus }).year();
}
/**
 * You select a month you wish to decrease or increase by 1.
 */
export function setMonth({ month, minus = false, plus = false, }) {
    const data = dayjs().set('month', month);
    return modifyDate({ data, unit: 'M', plus, minus }).month();
}
export function setDay(date, { minus = false, plus = false, }) {
    const data = getDayjsObject(date);
    return modifyDate({ data, unit: 'D', plus, minus }).date();
}
export function navigateGrid(code, data, disableWeekends, type) {
    if (type === 'date')
        return navDate(code, data, disableWeekends);
    return navList(code, data, type);
}
export function navDate(code, data, disableWeekend) {
    const date = getDayjsObject(data);
    const { space, enter, next, down, previous, upwards, pageDown, pageUp, end, home } = getCode(code);
    if (space || enter)
        return date;
    if (next || down)
        return date.add(next ? 1 : 7, 'day');
    if (previous || upwards)
        return date.subtract(previous ? 1 : 7, 'day');
    if (pageDown)
        return date.add(1, 'month');
    if (pageUp)
        return date.subtract(1, 'month');
    const day = date.get('day');
    const endDay = disableWeekend ? 5 : 7;
    const startDay = day === 0 ? -6 : 1;
    if (end && day !== 0)
        return date.set('day', endDay);
    if (home && day !== 1)
        return date.set('day', startDay);
    return date;
}
export function navList(key, data, type) {
    const date = getDayjsObject(data);
    const enter = key.match(/^(Enter|Space)$/);
    if (enter)
        return date;
    // Add one day
    const next = key === 'ArrowRight';
    // Minus one day
    const previous = key === 'ArrowLeft';
    // Add one week
    const down = key === 'ArrowDown';
    // Minus one week
    const upwards = key === 'ArrowUp';
    const setNumber = next || previous ? 1 : 3;
    const { years, months } = date.toObject();
    const dateValue = type === 'year' ? years : months;
    const oppositeType = type === 'year' ? 'month' : 'year';
    if (next || down)
        return date.set(type, dateValue + setNumber).set(oppositeType, data[oppositeType]);
    if (previous || upwards)
        return date.set(type, dateValue - setNumber).set(oppositeType, data[oppositeType]);
    return date;
}
export function getGrid(year, month) {
    const allDays = [];
    const grid = [];
    const date = dayjs().set('year', year).set('month', month);
    const numberOfDays = date.daysInMonth();
    for (let i = 0; numberOfDays > i; i++) {
        const day = date.set('date', i);
        const week = day.week();
        allDays.push({
            week,
            day: day.day() + 1,
            date: i + 1,
        });
    }
    const weeks = [...new Set(allDays.map(({ week }) => week))];
    weeks.forEach((week, index) => {
        const list = allDays.filter(day => day.week === week);
        if (index === 0 && list.length !== 7) {
            const numberOfDaysOutsideWeek = 7 - list.length;
            for (let i = 0; numberOfDaysOutsideWeek > i; i++) {
                list.unshift({ week, blank: true });
            }
        }
        if (index + 1 === weeks.length && list.length !== 7) {
            const numberOfDaysOutsideWeek = 7 - list.length;
            for (let i = 0; numberOfDaysOutsideWeek > i; i++) {
                list.push({ week, blank: true });
            }
        }
        grid.push({ week: week, list });
    });
    return grid;
}
export function getCode(code) {
    const enter = code === 'Enter';
    const space = code === 'Space';
    // Add/sub one day
    const next = code === 'ArrowRight';
    const previous = code === 'ArrowLeft';
    // Add/sub one week
    const down = code === 'ArrowDown';
    const upwards = code === 'ArrowUp';
    // Add/sub one month
    const pageDown = code === 'PageDown';
    const pageUp = code === 'PageUp';
    // Go the first/last day of the week
    const end = code === 'End';
    const home = code === 'Home';
    return {
        enter,
        space,
        next,
        previous,
        down,
        upwards,
        pageDown,
        pageUp,
        end,
        home,
    };
}
