"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildDaysCalendarGrid = exports.DAYS_CALENDAR_ITEMS_COUNT = void 0;
const isDate_1 = require("@astral/utils/date/isDate");
const constants_1 = require("../../../constants");
const buildIsoDate_1 = require("../buildIsoDate");
const checkIsDateInRange_1 = require("../checkIsDateInRange");
const compareDateDayByUTC_1 = require("../compareDateDayByUTC");
const isDateOutOfRange_1 = require("../isDateOutOfRange");
const FULL_ROWS_COUNT = 6;
exports.DAYS_CALENDAR_ITEMS_COUNT = FULL_ROWS_COUNT * constants_1.DAYS_IN_WEEK;
const buildDaysCalendarGrid = ({ minDate, maxDate, selectedDate, selectedRanges, hoveredDate, baseDate, isMondayFirst = true, productionCalendarStorage, }) => {
    /**
     * нормализованный номер месяца от базовой даты
     */
    const month = baseDate.getUTCMonth() + 1;
    /**
     * получаем новую дату, т.к. пропс может содержать дни, часы, минуты, что собьет наш счет
     */
    const startDate = (0, buildIsoDate_1.buildIsoDate)({ year: baseDate.getUTCFullYear(), month });
    /**
     * отступ для компенсации первого дня недели, 1 для понедельника, 0 для воскресенья
     */
    const firstWeekDayGap = Number(isMondayFirst);
    /**
     * номер первого дня текущего месяца в календаре, зависит от флага isMondayFirst
     */
    let startWeekDay = startDate.getUTCDay();
    if (startWeekDay === 0 && isMondayFirst) {
        startWeekDay = constants_1.DAYS_IN_WEEK;
    }
    /**
     * текущая дата пользователя
     */
    const currentDate = new Date();
    return Array.from({ length: exports.DAYS_CALENDAR_ITEMS_COUNT }).map((_, index) => {
        // текущая дата в счетчике
        const date = new Date(startDate);
        date.setUTCDate(startDate.getUTCDate() + index - startWeekDay + firstWeekDayGap);
        /**
         * нормализованный номер месяца
         */
        const dateMonth = date.getUTCMonth() + 1;
        const productionCalendarDay = productionCalendarStorage?.get(date.toISOString());
        const hasBothEdgeDates = Boolean(minDate && maxDate);
        const isDisabled = (hasBothEdgeDates &&
            (0, isDateOutOfRange_1.isDateOutOfRange)({
                date,
                dateA: minDate,
                dateB: maxDate,
                deep: isDateOutOfRange_1.DateCompareDeep.Day,
            })) ||
            (Boolean(minDate) && date < minDate) ||
            (Boolean(maxDate) && date > maxDate);
        return {
            ...productionCalendarDay,
            isOutOfAvailableRange: dateMonth !== month,
            index,
            isSelected: (((0, isDate_1.isDate)(selectedDate) &&
                (0, compareDateDayByUTC_1.compareDateDayByUTC)(selectedDate, date)) ||
                selectedRanges?.some(({ dateA, dateB }) => (0, compareDateDayByUTC_1.compareDateDayByUTC)(dateA, date) ||
                    (0, compareDateDayByUTC_1.compareDateDayByUTC)(dateB, date))) ??
                false,
            isCurrentInUserLocalTime: date.getUTCFullYear() === currentDate.getFullYear() &&
                date.getUTCDate() === currentDate.getDate() &&
                date.getUTCMonth() === currentDate.getMonth(),
            date,
            isInSelectedRange: selectedRanges?.some(({ dateA, dateB }) => (0, checkIsDateInRange_1.checkIsDateInRange)({
                date,
                dateA,
                dateB,
                deep: isDateOutOfRange_1.DateCompareDeep.Day,
            })) ?? false,
            isInHoveredRange: (0, checkIsDateInRange_1.checkIsDateInRange)({
                date,
                dateA: selectedDate,
                dateB: hoveredDate,
                deep: isDateOutOfRange_1.DateCompareDeep.Day,
            }),
            monthDay: date.getUTCDate(),
            isDisabled,
        };
    });
};
exports.buildDaysCalendarGrid = buildDaysCalendarGrid;
