import * as i0 from '@angular/core';
import { EventEmitter, Directive, Injectable, Output, Input } from '@angular/core';
import { isNullOrUndefined, getDateDayTime } from '@ironsource/fusion-ui/utils';
import { CalendarType } from '@ironsource/fusion-ui/components/calendar/entities';

const HOVER_RANGE_CLASS = 'hover-range';
const HOVER_CURRENT_CLASS = 'hover-current';
const DAY_NAMES = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
const DEFAULT_CALENDAR_COMPONENT_CONFIGURATION = {
    month: new Date(),
    allowFutureSelection: false,
    parentDaterangeId: '',
    selection: {
        startDate: new Date(),
        endDate: new Date()
    },
    maxDate: null,
    calendarType: CalendarType.DATE_PICKER
};

/* eslint-disable @angular-eslint/directive-class-suffix */
class CalendarService {
    constructor() {
        this.dayHoverStart = new EventEmitter();
        this.dayHoverEnd = new EventEmitter();
        this.parsedMonths = {};
    }
    daysInMonth(month, year) {
        return 32 - new Date(year, month, 32).getDate();
    }
    getMonthKey(month) {
        return month.getFullYear().toString() + '_' + month.getMonth().toString();
    }
    getParsedMonth(month, maxDate) {
        if (month) {
            const key = maxDate ? `${this.getMonthKey(month)}-${maxDate.getDate()}` : this.getMonthKey(month);
            return this.parsedMonths[key];
        }
        return { weeks: [] };
    }
    createMonth(monthToCreateAsUtc, maxDate) {
        const parsedMonth = { weeks: [] };
        const year = monthToCreateAsUtc.getFullYear();
        const month = monthToCreateAsUtc.getMonth();
        const firstDay = new Date(year, month, 1);
        const firstDayInMonth = firstDay.getDay();
        const now = this.getCurrentDateUTC();
        const maxDay = this.daysInMonth(month, year);
        const key = maxDate ? `${this.getMonthKey(monthToCreateAsUtc)}-${maxDate.getDate()}` : this.getMonthKey(monthToCreateAsUtc);
        let day;
        let week;
        let dayCounter = 1;
        if (this.parsedMonths[key]) {
            return this.parsedMonths[key];
        }
        for (let weekNum = 0; weekNum < 6; weekNum++) {
            week = [];
            for (let currDayInWeek = 0; currDayInWeek < 7; currDayInWeek++) {
                day = { date: null, isToday: false, isInFuture: false };
                if ((weekNum > 0 || currDayInWeek >= firstDayInMonth) && dayCounter <= maxDay) {
                    day.date = new Date(year, month, dayCounter);
                    dayCounter++;
                    if (now < day.date || (maxDate && maxDate < day.date)) {
                        day.isInFuture = true;
                    }
                    if (day.date.getTime() === now.getTime()) {
                        day.isToday = true;
                    }
                }
                week.push(day);
            }
            parsedMonth.weeks.push(week);
        }
        this.parsedMonths[key] = parsedMonth;
        return parsedMonth;
    }
    getCurrentDateUTC() {
        const d = new Date();
        return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
    }
    getDateAsUTC(date) {
        return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
    }
    compareDates(firstDate, secondDate) {
        return (firstDate.getDate() === secondDate.getDate() &&
            firstDate.getMonth() === secondDate.getMonth() &&
            firstDate.getFullYear() === secondDate.getFullYear());
    }
    static { this.ɵfac = function CalendarService_Factory(t) { return new (t || CalendarService)(); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CalendarService, outputs: { dayHoverStart: "dayHoverStart", dayHoverEnd: "dayHoverEnd" } }); }
    static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: CalendarService, factory: CalendarService.ɵfac, providedIn: 'root' }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CalendarService, [{
        type: Directive
    }, {
        type: Injectable,
        args: [{
                providedIn: 'root'
            }]
    }], null, { dayHoverStart: [{
            type: Output
        }], dayHoverEnd: [{
            type: Output
        }] }); })();

const DAY_UNIX_TIMESTAMP = 86400000;
class CalendarBaseComponent {
    set configuration(configuration) {
        if (configuration.month) {
            this.calendarService.createMonth(configuration.month, configuration.maxDate);
        }
        this._configurations = configuration;
        if (!isNullOrUndefined(this._configurations.selection.date)) {
            this._configurations.selection.startDate = this._configurations.selection.startDate ?? this._configurations.selection.date;
            this._configurations.selection.endDate = this._configurations.selection.endDate ?? this._configurations.selection.date;
        }
    }
    get configuration() {
        return this._configurations;
    }
    constructor(
    /** @internal */
    calendarService) {
        this.calendarService = calendarService;
        this.daySelected = new EventEmitter();
        /** @internal */
        this.daysOfTheWeek = DAY_NAMES;
        /** @internal */
        this._configurations = DEFAULT_CALENDAR_COMPONENT_CONFIGURATION;
    }
    ngOnInit() {
        if (this.configuration.month) {
            this.calendarService.createMonth(this.configuration.month, this.configuration.maxDate);
        }
    }
    /** @internal */
    selectDay(day) {
        this.daySelected.emit(day);
    }
    /** @internal */
    isDisabled(day) {
        return !day.date || (day.isInFuture && !this.configuration.allowFutureSelection) || this.isInMInMaxRange(day.date);
    }
    /** @internal */
    isActive(value) {
        if (value.date &&
            ((this.configuration.selection.startDate && this.configuration.selection.endDate) || this.configuration.selection.date)) {
            return (this.calendarService.compareDates(value.date, this.configuration.selection.startDate ?? this.configuration.selection.date) ||
                this.calendarService.compareDates(value.date, this.configuration.selection.endDate ?? this.configuration.selection.date));
        }
        return false;
    }
    /** @internal */
    dayHovered(day, event) { }
    /** @internal */
    hoverEnd() { }
    /** @internal */
    getDayClasses(day) {
        const selectedStartDateTimestamp = getDateDayTime(this.configuration.selection.startDate ?? this.configuration.selection.date);
        const selectedEndDateTimestamp = getDateDayTime(this.configuration.selection.endDate ?? this.configuration.selection.date);
        const dayDateTimestamp = getDateDayTime(day.date);
        const isStartDate = dayDateTimestamp === selectedStartDateTimestamp;
        const isEndDate = dayDateTimestamp === selectedEndDateTimestamp;
        return {
            today: day.isToday,
            oneDaySelection: dayDateTimestamp && isStartDate && isEndDate,
            selected: dayDateTimestamp >= selectedStartDateTimestamp && dayDateTimestamp <= selectedEndDateTimestamp,
            selectedStart: dayDateTimestamp !== selectedEndDateTimestamp && isStartDate,
            selectedEnd: isEndDate && dayDateTimestamp !== selectedStartDateTimestamp,
            selectedDayAfterDay: (isEndDate || isStartDate) && selectedEndDateTimestamp === selectedStartDateTimestamp + DAY_UNIX_TIMESTAMP,
            active: this.isActive(day),
            disabled: this.isDisabled(day)
        };
    }
    isInMInMaxRange(date) {
        const minDate = this.configuration?.minDate;
        const maxDate = this.configuration?.maxDate;
        const isBeforeMinDate = minDate ? date.getTime() < minDate.getTime() : false;
        const isAfterMaxDate = maxDate ? date.getTime() > maxDate.getTime() : false;
        return isBeforeMinDate || isAfterMaxDate;
    }
    static { this.ɵfac = function CalendarBaseComponent_Factory(t) { return new (t || CalendarBaseComponent)(i0.ɵɵdirectiveInject(CalendarService)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CalendarBaseComponent, inputs: { configuration: "configuration" }, outputs: { daySelected: "daySelected" } }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CalendarBaseComponent, [{
        type: Directive
    }], () => [{ type: CalendarService }], { configuration: [{
            type: Input
        }], daySelected: [{
            type: Output
        }] }); })();

/**
 * Generated bundle index. Do not edit.
 */

export { CalendarBaseComponent, CalendarService, DAY_NAMES, DEFAULT_CALENDAR_COMPONENT_CONFIGURATION, HOVER_CURRENT_CLASS, HOVER_RANGE_CLASS };
//# sourceMappingURL=ironsource-fusion-ui-components-calendar-common-base.mjs.map
