(function (window, document) {
    'use strict';

    var jd = window.zertiJalaliDate;
    if (!jd) {
        return;
    }

    function readCalendarI18n() {
        return typeof window.zertiCalendarI18n === 'object' && window.zertiCalendarI18n !== null
            ? window.zertiCalendarI18n
            : {};
    }

    function jalaliMonthNames() {
        var i18n = readCalendarI18n();
        return Array.isArray(i18n.jalaliMonths) ? i18n.jalaliMonths : [];
    }

    function jalaliWeekdayNames() {
        var i18n = readCalendarI18n();
        return Array.isArray(i18n.jalaliWeekdays) ? i18n.jalaliWeekdays : [];
    }

    var POPUP_WIDTH = 280;

    var sharedPopup = null;
    var activePicker = null;

    function readTimeZone() {
        return typeof window.zertiAdminClock === 'object' && window.zertiAdminClock && window.zertiAdminClock.timeZone
            ? window.zertiAdminClock.timeZone
            : undefined;
    }

    function readTheme() {
        var admin = document.getElementById('zertiAdmin');
        return admin && admin.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'light';
    }

    function ensureSharedPopup() {
        if (sharedPopup) {
            return sharedPopup;
        }

        var calI18n = readCalendarI18n();
        var popup = document.createElement('div');
        popup.className = 'zerti-jalali-datepicker';
        popup.setAttribute('role', 'dialog');
        popup.setAttribute('aria-label', calI18n.ariaJalali || '');
        popup.setAttribute('aria-modal', 'false');
        popup.innerHTML =
            '<div class="zerti-jalali-datepicker__header">' +
            '<button type="button" class="btn btn-sm btn-outline-secondary zerti-jalali-datepicker__nav" data-zerti-jalali-prev aria-label="">&rsaquo;</button>' +
            '<div class="zerti-jalali-datepicker__title"></div>' +
            '<button type="button" class="btn btn-sm btn-outline-secondary zerti-jalali-datepicker__nav" data-zerti-jalali-next aria-label="">&lsaquo;</button>' +
            '</div>' +
            '<div class="zerti-jalali-datepicker__weekdays"></div>' +
            '<div class="zerti-jalali-datepicker__days"></div>' +
            '<div class="zerti-jalali-datepicker__footer">' +
            '<button type="button" class="btn btn-sm btn-link zerti-jalali-datepicker__today" data-zerti-jalali-today></button>' +
            '<button type="button" class="btn btn-sm btn-link text-danger zerti-jalali-datepicker__clear" data-zerti-jalali-clear></button>' +
            '</div>';

        document.body.appendChild(popup);

        popup.querySelector('[data-zerti-jalali-prev]').setAttribute('aria-label', calI18n.prevMonth || '');
        popup.querySelector('[data-zerti-jalali-next]').setAttribute('aria-label', calI18n.nextMonth || '');
        popup.querySelector('[data-zerti-jalali-today]').textContent = calI18n.today || '';
        popup.querySelector('[data-zerti-jalali-clear]').textContent = calI18n.clear || '';

        var weekdayHtml = '';
        jalaliWeekdayNames().forEach(function (name) {
            weekdayHtml += '<span class="zerti-jalali-datepicker__weekday">' + name + '</span>';
        });
        popup.querySelector('.zerti-jalali-datepicker__weekdays').innerHTML = weekdayHtml;

        sharedPopup = {
            el: popup,
            titleEl: popup.querySelector('.zerti-jalali-datepicker__title'),
            daysEl: popup.querySelector('.zerti-jalali-datepicker__days'),
        };

        popup.querySelector('[data-zerti-jalali-prev]').addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (activePicker) {
                activePicker.changeMonth(-1);
            }
        });
        popup.querySelector('[data-zerti-jalali-next]').addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (activePicker) {
                activePicker.changeMonth(1);
            }
        });
        popup.querySelector('[data-zerti-jalali-today]').addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (activePicker) {
                activePicker.selectToday();
            }
        });
        popup.querySelector('[data-zerti-jalali-clear]').addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (activePicker) {
                activePicker.setValue('');
                activePicker.close();
            }
        });
        sharedPopup.daysEl.addEventListener('click', function (e) {
            var btn = e.target.closest('[data-zerti-jalali-day]');
            if (!btn || !activePicker) {
                return;
            }
            e.preventDefault();
            e.stopPropagation();
            activePicker.selectDay(
                parseInt(btn.getAttribute('data-jy'), 10),
                parseInt(btn.getAttribute('data-jm'), 10),
                parseInt(btn.getAttribute('data-jd'), 10)
            );
        });

        document.addEventListener('mousedown', function (e) {
            if (!activePicker || !sharedPopup || !sharedPopup.el.classList.contains('is-open')) {
                return;
            }
            if (sharedPopup.el.contains(e.target) || e.target === activePicker.input) {
                return;
            }
            activePicker.close();
        });
        document.addEventListener('keydown', function (e) {
            if (e.key === 'Escape' && activePicker) {
                activePicker.close();
            }
        });
        window.addEventListener(
            'resize',
            function () {
                if (activePicker) {
                    activePicker.positionPopup();
                }
            },
            { passive: true }
        );
        window.addEventListener(
            'scroll',
            function () {
                if (activePicker) {
                    activePicker.positionPopup();
                }
            },
            true
        );

        return sharedPopup;
    }

    function closeActivePicker() {
        if (activePicker) {
            activePicker.close();
        }
    }

    function JalaliDatepicker(input) {
        this.input = input;
        this.viewYear = 0;
        this.viewMonth = 0;
        this.bound = false;
    }

    JalaliDatepicker.prototype.syncTheme = function () {
        var ui = ensureSharedPopup();
        ui.el.setAttribute('data-bs-theme', readTheme());
    };

    JalaliDatepicker.prototype.changeMonth = function (delta) {
        this.viewMonth += delta;
        if (this.viewMonth > 12) {
            this.viewMonth = 1;
            this.viewYear += 1;
        } else if (this.viewMonth < 1) {
            this.viewMonth = 12;
            this.viewYear -= 1;
        }
        this.render();
        this.positionPopup();
    };

    JalaliDatepicker.prototype.setValue = function (value) {
        this.input.value = value;
        this.input.dispatchEvent(new Event('input', { bubbles: true }));
        this.input.dispatchEvent(new Event('change', { bubbles: true }));
    };

    JalaliDatepicker.prototype.selectDay = function (jy, jm, jdVal) {
        this.setValue(jd.formatJalaliParts(jy, jm, jdVal, true));
        this.close();
    };

    JalaliDatepicker.prototype.selectToday = function () {
        var today = jd.todayJalaliParts(readTimeZone());
        this.viewYear = today[0];
        this.viewMonth = today[1];
        this.selectDay(today[0], today[1], today[2]);
    };

    JalaliDatepicker.prototype.open = function () {
        if (this.input.disabled || this.input.readOnly) {
            return;
        }

        closeActivePicker();
        this.syncTheme();

        var selected = jd.parseJalaliString(this.input.value);
        if (selected) {
            this.viewYear = selected[0];
            this.viewMonth = selected[1];
        } else {
            var today = jd.todayJalaliParts(readTimeZone());
            this.viewYear = today[0];
            this.viewMonth = today[1];
        }

        activePicker = this;
        this.render();

        var ui = ensureSharedPopup();
        ui.el.classList.add('is-open');
        ui.el.setAttribute('aria-hidden', 'false');

        var self = this;
        window.requestAnimationFrame(function () {
            if (activePicker === self) {
                self.positionPopup();
            }
        });
    };

    JalaliDatepicker.prototype.close = function () {
        var ui = ensureSharedPopup();
        ui.el.classList.remove('is-open');
        ui.el.setAttribute('aria-hidden', 'true');
        if (activePicker === this) {
            activePicker = null;
        }
    };

    JalaliDatepicker.prototype.positionPopup = function () {
        var ui = ensureSharedPopup();
        var popup = ui.el;
        var rect = this.input.getBoundingClientRect();

        if (!rect.width && !rect.height) {
            popup.style.top = '50%';
            popup.style.left = '50%';
            popup.style.transform = 'translate(-50%, -50%)';
            return;
        }

        popup.style.transform = 'none';
        popup.style.width = POPUP_WIDTH + 'px';

        var top = rect.bottom + 6;
        var left = rect.left;

        if (left + POPUP_WIDTH > window.innerWidth - 8) {
            left = window.innerWidth - POPUP_WIDTH - 8;
        }
        if (left < 8) {
            left = 8;
        }

        var popupHeight = popup.offsetHeight || 280;
        if (top + popupHeight > window.innerHeight - 8) {
            top = rect.top - popupHeight - 6;
        }
        if (top < 8) {
            top = 8;
        }

        popup.style.top = Math.round(top) + 'px';
        popup.style.left = Math.round(left) + 'px';
    };

    JalaliDatepicker.prototype.render = function () {
        var ui = ensureSharedPopup();
        var jy = this.viewYear;
        var jm = this.viewMonth;
        ui.titleEl.textContent = (jalaliMonthNames()[jm - 1] || '') + ' ' + jd.toPersianDigits(String(jy));

        var selected = jd.parseJalaliString(this.input.value);
        var today = jd.todayJalaliParts(readTimeZone());
        var monthLen = jd.jalaliMonthLength(jy, jm);
        var firstWeekday = jd.jalaliWeekday(jy, jm, 1);
        var startOffset = (firstWeekday + 1) % 7;

        var html = '';
        var cell = 0;
        var d;
        for (d = 0; d < startOffset; d += 1) {
            html += '<span class="zerti-jalali-datepicker__day zerti-jalali-datepicker__day--empty"></span>';
            cell += 1;
        }
        for (d = 1; d <= monthLen; d += 1) {
            var classes = ['zerti-jalali-datepicker__day'];
            if (selected && selected[0] === jy && selected[1] === jm && selected[2] === d) {
                classes.push('zerti-jalali-datepicker__day--selected');
            }
            if (today[0] === jy && today[1] === jm && today[2] === d) {
                classes.push('zerti-jalali-datepicker__day--today');
            }
            html +=
                '<button type="button" class="' +
                classes.join(' ') +
                '" data-zerti-jalali-day data-jy="' +
                jy +
                '" data-jm="' +
                jm +
                '" data-jd="' +
                d +
                '">' +
                jd.toPersianDigits(String(d)) +
                '</button>';
            cell += 1;
        }
        while (cell % 7 !== 0) {
            html += '<span class="zerti-jalali-datepicker__day zerti-jalali-datepicker__day--empty"></span>';
            cell += 1;
        }
        ui.daysEl.innerHTML = html;
    };

    JalaliDatepicker.prototype.bind = function () {
        if (this.bound || this.input.getAttribute('data-zerti-jalali-bound') === '1') {
            return;
        }
        this.bound = true;
        this.input.setAttribute('data-zerti-jalali-bound', '1');

        if (!this.input.getAttribute('placeholder')) {
            this.input.setAttribute('placeholder', readCalendarI18n().placeholderJalali || '');
        }
        this.input.setAttribute('autocomplete', 'off');
        this.input.setAttribute('inputmode', 'numeric');
        if (!this.input.getAttribute('dir')) {
            this.input.setAttribute('dir', window.zertiAdminTextDirection ? window.zertiAdminTextDirection() : 'rtl');
        }

        var self = this;
        this.input.addEventListener('click', function (e) {
            e.preventDefault();
            self.open();
        });
        this.input.addEventListener('keydown', function (e) {
            if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                self.open();
            }
        });
    };

    function upgradeNativeDateInput(input) {
        if (!input || input.getAttribute('data-zerti-jalali-upgraded') === '1') {
            return input;
        }
        var val = input.value;
        input.type = 'text';
        input.setAttribute('data-zerti-jalali-date', '');
        input.setAttribute('data-zerti-jalali-upgraded', '1');
        if (val) {
            input.value = jd.gregorianYmdToJalaliDisplay(val, true);
        }
        return input;
    }

    function bindInput(input) {
        if (!input || input.getAttribute('data-zerti-jalali-bound') === '1') {
            return;
        }
        if (input.type === 'date') {
            upgradeNativeDateInput(input);
        }
        if (!input.hasAttribute('data-zerti-jalali-date') && input.type !== 'text') {
            return;
        }
        if (!input.hasAttribute('data-zerti-jalali-date')) {
            input.setAttribute('data-zerti-jalali-date', '');
        }
        var picker = new JalaliDatepicker(input);
        picker.bind();
        input.__zertiJalaliPicker = picker;
    }

    window.zertiInitJalaliDatepickers = function (root) {
        var admin = document.getElementById('zertiAdmin');
        if (!admin) {
            return;
        }
        var searchRoot = root && root.querySelectorAll && root !== document ? root : admin;
        if (!searchRoot.querySelectorAll) {
            return;
        }
        searchRoot.querySelectorAll('[data-zerti-jalali-date]').forEach(function (input) {
            bindInput(input);
        });
    };
})(window, document);
