// #region Imports
import { html } from '../../../../../Dom/Html';
import { dayNames, getWeekNumber, isDateEqual, isDateInDates, isToday, isWeekendDay } from '../../../../../Extensions/DateExtensions';
import { repeat, when } from '../../../../Directives/Directives';
import { Appearance } from '../../../../Types/Appearance';
import { CalendarView } from '../../../../Types/CalendarView';
import { TextAlignment } from '../../../../Types/TextAlignment';
// #endregion
/**
 * The template of the `CalendarDaysViewElement`.
 *
 * @public
 */
export function calendarDaysViewElementTemplate(e) {
    const displayDate = e.displayDate ?? new Date();
    const month = displayDate.getMonth();
    const year = displayDate.getFullYear();
    const daysInMonth = new Date(year, month + 1, 0).getDate();
    const firstDayOfMonth = new Date(year, month, 1).getDay();
    const leadingDaysCount = (firstDayOfMonth - e.firstDayOfWeek + 7) % 7;
    const trailingDaysCount = (7 - ((leadingDaysCount + daysInMonth) % 7)) % 7;
    const dayNamesIntl = e.intl
        ? [e.intl.sundayLabel, e.intl.mondayLabel, e.intl.tuesdayLabel, e.intl.wednesdayLabel, e.intl.thursdayLabel, e.intl.fridayLabel, e.intl.saturdayLabel]
        : ['na', 'na', 'na', 'na', 'na', 'na', 'na'];
    const isDataSelected = (data) => {
        if (e.value && isDateEqual(e.value, data)) {
            return true;
        }
        else if (e.values) {
            return e.values.some((x) => isDateEqual(x, data));
        }
        return false;
    };
    const getRangeState = (data) => {
        if (e.selection !== 'range' || !e.values || e.values.length < 2) {
            return { isRangeStart: false, isRangeMiddle: false, isRangeEnd: false, isRangePreview: false };
        }
        const sortedValues = [...e.values].sort((a, b) => a.getTime() - b.getTime());
        const startDate = sortedValues[0];
        const endDate = sortedValues[sortedValues.length - 1];
        const isRangeStart = isDateEqual(data, startDate);
        const isRangeEnd = isDateEqual(data, endDate);
        const isRangeMiddle = !isRangeStart && !isRangeEnd && data > startDate && data < endDate;
        // Check for range preview
        const isRangePreview = e.rangePreviewDate && e.values.length === 1 && ((data > startDate && data <= e.rangePreviewDate) || (data < startDate && data >= e.rangePreviewDate));
        return {
            isRangeStart: isRangeStart,
            isRangeMiddle: isRangeMiddle,
            isRangeEnd: isRangeEnd,
            isRangePreview: isRangePreview ?? false
        };
    };
    return html `
        <div part="heading"
             style="display: flex; flex: 1;">
            <mosaik-button-group .dir="${e.dir}"
                                 .appearance="${Appearance.Plain}">
                <mosaik-button part="month"
                               .label="${e.displayDate?.toLocaleString(e.locale, { month: 'long' }) ?? ''}"
                               @click="${() => e.setView(CalendarView.Month)}"></mosaik-button>
                <mosaik-button part="year"
                               .label="${e.displayDate?.toLocaleString(e.locale, { year: 'numeric' }) ?? ''}"
                               @click="${() => e.setView(CalendarView.Year)}"></mosaik-button>
            </mosaik-button-group>
            <div part="navigation">
                <slot name="header"></slot>
            </div>
        </div>

        <div part="labels"
             class="${e.showWeekNumbers ? 'week-numbers' : ''}">
            ${when(e.showWeekNumbers, () => html `
            <mosaik-text part="weekNumberLabel"
                         .dir="${e.dir}"
                         .text="${e.intl?.weekNumberLabel}"
                         .alignment="${TextAlignment.Center}"></mosaik-text>
            `)}
            ${repeat(dayNames(dayNamesIntl, e.firstDayOfWeek), (dayName) => dayName, (dayName) => html `
            <mosaik-text part="dayLabel"
                         .dir="${e.dir}"
                         .text="${dayName}"
                         .alignment="${TextAlignment.Center}"></mosaik-text>
            `)}
        </div>
        <div part="dayView"
             class="${e.showWeekNumbers ? 'week-numbers' : ''}">
            ${when(e.showAdjacent, () => html `
            <!-- adjacent days before the start of the month -->
            ${Array.from({ length: leadingDaysCount }, (_, i) => new Date(year, month, -i)).reverse()
        .map((day) => html `
            <mosaik-calendar-item part="item"
                                  .dir="${e.dir}"
                                  .text="${day.getDate().toLocaleString()}"
                                  .value="${day}"
                                  .markers="${e.markerHandler(day)}"
                                  .variant="${e.variant}"
                                  .appearance="${e.appearance}"
                                  .isAdjacent="${true}"
                                  .isSelected="${isDataSelected(day)}"
                                  .isBlackout="${isDateInDates(day, e.blackoutDates)}"
                                  .isSpecial="${isDateInDates(day, e.specialDates)}"
                                  .isToday="${e.isTodayHighlighted ? isToday(day) : false}"
                                  .isWeekend="${e.isWeekendHighlighted ? isWeekendDay(day) : false}"
                                  .isRangeStart="${getRangeState(day).isRangeStart}"
                                  .isRangeMiddle="${getRangeState(day).isRangeMiddle}"
                                  .isRangeEnd="${getRangeState(day).isRangeEnd}"
                                  .isRangePreview="${getRangeState(day).isRangePreview}"
                                  .disabled="${e.disabled && e.isDateInRange(day)}"
                                  @click="${() => e.selectAdjacentDay('previous', day)}"
                                  @mouseenter=${() => e.changeRangePreview(day)}
                                  @mouseleave=${() => e.clearRangePreview()}
                                  @focus=${() => e.changeRangePreview(day)}
                                  @blur=${() => e.clearRangePreview()}></mosaik-calendar-item>
            `)}
            `, () => html `
            <!-- empty days before the start of the month -->
            ${Array.from({ length: leadingDaysCount }, () => null).map(() => html `<div class="empty"></div>`)}
            `)}
            <!-- days of the month -->
            ${Array.from({ length: daysInMonth }, (_, i) => new Date(year, month, i + 1)).map((day, i) => html `
            <!-- week numbers -->
            ${when(e.showWeekNumbers && ((leadingDaysCount + i) % 7 === 0), () => html `
            <div part="weekNumber">
                <mosaik-text .dir="${e.dir}"
                             .text="${getWeekNumber(day).toString()}"
                             ?disabled="${e.disabled}"></mosaik-text>
            </div>
            `)}
            <mosaik-calendar-item part="item"
                                  .dir="${e.dir}"
                                  .text="${day.getDate().toLocaleString()}"
                                  .value="${day}"
                                  .markers="${e.markerHandler(day)}"
                                  .variant="${e.variant}"
                                  .appearance="${e.appearance}"
                                  .isSelected="${isDataSelected(day)}"
                                  .isBlackout="${isDateInDates(day, e.blackoutDates)}"
                                  .isSpecial="${isDateInDates(day, e.specialDates)}"
                                  .isToday="${e.isTodayHighlighted ? isToday(day) : false}"
                                  .isWeekend="${e.isWeekendHighlighted ? isWeekendDay(day) : false}"
                                  .isRangeStart="${getRangeState(day).isRangeStart}"
                                  .isRangeMiddle="${getRangeState(day).isRangeMiddle}"
                                  .isRangeEnd="${getRangeState(day).isRangeEnd}"
                                  .isRangePreview="${getRangeState(day).isRangePreview}"
                                  .disabled="${e.disabled && e.isDateInRange(day)}"
                                  @click="${() => e.selectDay(day)}"
                                  @mouseenter=${() => e.changeRangePreview(day)}
                                  @mouseleave=${() => e.clearRangePreview()}
                                  @focus=${() => e.changeRangePreview(day)}
                                  @blur=${() => e.clearRangePreview()}></mosaik-calendar-item>
            `)}
            ${when(e.showAdjacent, () => html `
            <!-- adjacent days after the end of the month -->
            ${Array.from({ length: trailingDaysCount }, (_, i) => new Date(year, month + 1, i + 1)).map((day) => html `
            <mosaik-calendar-item part="item"
                                  .dir="${e.dir}"
                                  .text="${day.getDate().toLocaleString()}"
                                  .value="${day}"
                                  .markers="${e.markerHandler(day)}"
                                  .variant="${e.variant}"
                                  .appearance="${e.appearance}"
                                  .isAdjacent="${true}"
                                  .isSelected="${isDataSelected(day)}"
                                  .isBlackout="${isDateInDates(day, e.blackoutDates)}"
                                  .isSpecial="${isDateInDates(day, e.specialDates)}"
                                  .isToday="${e.isTodayHighlighted ? isToday(day) : false}"
                                  .isWeekend="${e.isWeekendHighlighted ? isWeekendDay(day) : false}"
                                  .isRangeStart="${getRangeState(day).isRangeStart}"
                                  .isRangeMiddle="${getRangeState(day).isRangeMiddle}"
                                  .isRangeEnd="${getRangeState(day).isRangeEnd}"
                                  .isRangePreview="${getRangeState(day).isRangePreview}"
                                  .disabled="${e.disabled && e.isDateInRange(day)}"
                                  @click="${() => e.selectAdjacentDay('next', day)}"
                                  @mouseenter=${() => e.changeRangePreview(day)}
                                  @mouseleave=${() => e.clearRangePreview()}
                                  @focus=${() => e.changeRangePreview(day)}
                                  @blur=${() => e.clearRangePreview()}></mosaik-calendar-item>
            `)}
            `, () => html `
            <!-- empty days after the end of the month -->
            ${Array.from({ length: trailingDaysCount }, () => null).map(() => html `<div class="empty"></div>`)}
            `)}
        </div>
    `;
}
//# sourceMappingURL=CalendarDaysViewElementTemplate.js.map