import { r as registerInstance, d as createEvent, h, c as getElement } from './core-34fac203.js';
import { T as Tunnel } from './i18n.provider-31a85d1e.js';
import './translations-c4959f9b.js';
import { g as getValidator } from './validatorFactory-d4b539f1.js';
import { D as DatePickerService } from './date-picker.service-e6e813e8.js';

let inputId = 0;
const DatePicker = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.calendarListener = ({ detail }) => this.handleCalendarSelection(detail);
        this.inputBlurListener = (e) => this.handleBlur(e);
        this.inputKeyListener = (e) => this.handleInputKey(e);
        this.toggleClickListener = () => this.open();
        this.overlayListener = () => this.close();
        /**
         * The date picker id
         */
        this.inputId = `'anj-date-picker-${inputId++}`;
        /**
         * How to align the overlay when it opens.
         * Options are `"bottom-end"` or `"bottom-start"` which is the default.
         */
        this.placement = 'bottom-end';
        this.anjDateChange = createEvent(this, "anjDateChange", 7);
        this.anjInputControlDidLoad = createEvent(this, "anjInputControlDidLoad", 7);
    }
    get date() {
        const date = (this.innerDateValue) ? new Date(this.innerDateValue) : new Date();
        return this.adapter.getCalendarDate(date, this.rangeParams);
    }
    injectedPropWatcher() {
        this.assignAdapter();
    }
    connectedCallback() {
        this.assignAdapter();
        this.input = this.element.parentElement;
        this.input.addEventListener('anjInput', this.inputKeyListener);
        this.input.addEventListener('anjBlur', this.inputBlurListener);
        this.connectToggle(this.input.querySelector('anj-date-picker-toggle'));
        this.configureValidationParameters();
    }
    componentDidLoad() {
        this.anjInputControlDidLoad.emit();
    }
    disconnectedCallback() {
        this.unbindCalendar();
        if (this.overlay) {
            this.overlay.removeEventListener('anjWillDismiss', this.overlayListener);
            this.overlay = null;
        }
        if (this.input) {
            this.input.removeEventListener('anjInput', this.inputKeyListener);
            this.input.removeEventListener('anjBlur', this.inputBlurListener);
        }
        const toggle = this.input.querySelector('anj-date-picker-toggle');
        if (toggle) {
            toggle.removeEventListener('click', this.toggleClickListener);
        }
    }
    /**
     * open the date picker
     */
    async open() {
        if (this.calendar)
            return;
        if (!this.overlay) {
            this.bindOverlay(this.element.querySelector('anj-overlay'));
        }
        this.bindCalendar();
        const popper = await this.overlay.popper();
        const d = this.innerDateValue || this.input.value;
        if (!popper) {
            this.configureValidationParameters();
            this.processInputValue(d ? d : '');
            this.calendar.monthMode = true;
            this.calendar.date = this.date;
            this.calendar.rangeParams = this.rangeParams;
            await this.overlay.open(this.element);
        }
        this.previouslyActiveElement = this.input.querySelector('anj-date-picker-toggle button');
        return this.calendar.focusControls();
    }
    /**
     * close the date picker
     */
    async close() {
        if (this.previouslyActiveElement) {
            await this.input.setFocus();
            this.previouslyActiveElement.focus();
            this.previouslyActiveElement = undefined;
        }
        await this.overlay.close();
        this.unbindCalendar();
    }
    /**
     * handle changes from the anj-input
     */
    processInputValue(inputValue) {
        this.innerDateValue = this.adapter.processDateInput(inputValue);
        this.outerValue = this.adapter.prepDateStringOutput(this.innerDateValue);
        if (inputValue) {
            this.anjDateChange.emit({ inner: this.adapter.convertToDate(this.innerDateValue), outer: this.outerValue });
        }
        else {
            this.anjDateChange.emit({});
        }
    }
    /**
     * handle changes from the angular directive
     */
    async setInputValue(inputValue) {
        const inputDate = (typeof inputValue === 'string') ? this.adapter.convertToDate(this.adapter.processDateInput(inputValue)) : this.adapter.processDateInput(inputValue);
        this.outerValue = this.adapter.prepDateStringOutput(inputDate);
        this.innerDateValue = this.adapter.processDateInput(this.outerValue);
        this.anjDateChange.emit({ inner: inputValue, outer: this.outerValue, refreshOuter: true });
    }
    /**
     * formatter, passed to anj-input, which supports conversion to short-date
     */
    inputFormatter(inputValue) {
        return Promise.resolve(this.adapter.prepDateStringOutput(inputValue));
    }
    /**
     * comparator, passed to anj-input, which compares two dates of various formats for parity
     */
    hasValueChanged(newVal, oldVal) {
        return Promise.resolve(this.adapter.prepDateStringOutput(newVal) !== this.adapter.prepDateStringOutput(oldVal));
    }
    async innerValue() {
        return this.innerDateValue;
    }
    // VALIDATION BLOCK
    async remoteCustomValidator(valueString) {
        const valueDate = this.adapter.processDateInput(valueString);
        return this.updateCustomValidity(valueDate);
    }
    configureValidationParameters() {
        this.rangeParams = {};
        if (this.input.min) {
            this.min = this.adapter.processDateInput(this.input.min);
            this.rangeParams.minDate = this.min;
        }
        if (this.input.max) {
            this.max = this.adapter.processDateInput(this.input.max);
            this.rangeParams.maxDate = this.max;
        }
        this.setCustomValidator();
    }
    setCustomValidator() {
        this.validator = getValidator([
            { name: 'min', options: { min: this.min } },
            { name: 'max', options: { max: this.max } }
        ]);
    }
    updateCustomValidity(value) {
        let response = {};
        if (this.validator) {
            response = this.validator.validate(value);
        }
        return response;
    }
    assignAdapter() {
        this.adapter = new DatePickerService(this.locale, this.language, this.timezoneOverride, this.dateFormat);
    }
    connectToggle(toggle) {
        if (toggle) {
            toggle.addEventListener('click', this.toggleClickListener);
        }
    }
    handleBlur({ target }) {
        if (target.tagName === 'ANJ-INPUT') {
            this.processInputValue(target.value);
        }
    }
    handleCalendarSelection(dateSelection) {
        this.innerDateValue = dateSelection;
        this.outerValue = this.adapter.localize(this.innerDateValue);
        this.input.value = this.outerValue;
        this.anjDateChange.emit({ inner: this.adapter.convertToDate(this.innerDateValue), outer: this.outerValue, refreshOuter: true });
        this.close();
    }
    handleInputKey({ target }) {
        this.processInputValue(target.value);
        this.input.checkValidity();
    }
    bindOverlay(el) {
        if (el) {
            this.overlay = el;
            this.overlay.addEventListener('anjWillDismiss', this.overlayListener);
        }
    }
    bindCalendar() {
        this.calendar = document.createElement('anj-calendar');
        this.overlay.appendChild(this.calendar);
        this.calendar.date = this.date;
        this.calendar.adapter = this.adapter;
        this.calendar.rangeParams = this.rangeParams;
        this.calendar.addEventListener('anjCalendarDaySelect', this.calendarListener);
    }
    unbindCalendar() {
        if (this.calendar) {
            this.calendar.removeEventListener('anjCalendarDaySelect', this.calendarListener);
            this.calendar.remove();
            this.calendar = null;
        }
    }
    render() {
        return (h("anj-overlay", { class: "anj-dropdown-menu anj-date-picker-menu", placement: this.placement, trapFocus: true }));
    }
    get element() { return getElement(this); }
    static get watchers() { return {
        "locale": ["injectedPropWatcher"],
        "language": ["injectedPropWatcher"],
        "timezoneOverride": ["injectedPropWatcher"],
        "dateFormat": ["injectedPropWatcher"]
    }; }
    static get style() { return "anj-date-picker {\n  bottom: 0;\n  display: inline-block;\n  position: absolute;\n  right: 0;\n  -webkit-transition: z-index 1s 0.5s;\n  transition: z-index 1s 0.5s;\n  z-index: 1;\n}\n\n.anj-date-picker-menu {\n  background-color: transparent;\n  border: none;\n  float: right;\n  margin: 0;\n  padding: 0;\n}"; }
};
Tunnel.injectProps(DatePicker, ['locale', 'language', 'timezoneOverride', 'dateFormat']);

export { DatePicker as anj_date_picker };
