define(['jquery', 'mage/calendar'], function ($) {
    'use strict';

    return function (Component) {
        return Component.extend({
            inlineDatepickerReady: false,

            resolveMinDate: function () {
                if (this.options && (this.options.minDate === 0 || this.options.minDate === '0')) {
                    return 'today';
                }

                return (this.options && this.options.minDate) ? this.options.minDate : 'today';
            },

            toJqueryUiFormat: function (format) {
                var mapped = format || 'dd/MM/yyyy';

                return mapped
                    .replace(/yyyy/g, 'yy')
                    .replace(/MM/g, 'mm')
                    .replace(/dd/g, 'dd');
            },

            initInlineDatepicker: function (disabledWeekdays, disabledDates) {
                var self = this;
                var attempts = 0;
                var maxAttempts = 100;
                var interval = setInterval(function () {
                    attempts++;

                    var input = document.getElementById(self.uid);
                    var calendarId = self.uid + '-inline';
                    var calendarElement = document.getElementById(calendarId);

                    if (input && calendarElement && typeof $.fn.datepicker === 'function') {
                        var $calendar = $(calendarElement);
                        var jqFormat = self.toJqueryUiFormat(self.options.dateFormat);
                        var minDate = self.resolveMinDate();
                        var normalizedMinDate = minDate === 'today' ? 0 : minDate;

                        $calendar.datepicker({
                            dateFormat: jqFormat,
                            minDate: normalizedMinDate,
                            beforeShowDay: function (date) {
                                var dayIndex = date.getDay();
                                if (disabledWeekdays.indexOf(dayIndex) !== -1) {
                                    return [false, '', 'Unavailable'];
                                }

                                var dateString = date.getFullYear() + '-' +
                                    String(date.getMonth() + 1).padStart(2, '0') + '-' +
                                    String(date.getDate()).padStart(2, '0');
                                if (disabledDates.indexOf(dateString) !== -1) {
                                    return [false, '', 'Unavailable'];
                                }

                                return [true, '', ''];
                            },
                            onSelect: function (dateText) {
                                self.shiftedValue(dateText || '');
                            }
                        });

                        if (self.shiftedValue()) {
                            $calendar.datepicker('setDate', self.shiftedValue());
                        }

                        self.inlineDatepickerReady = true;

                        clearInterval(interval);
                        return;
                    }

                    if (attempts >= maxAttempts) {
                        clearInterval(interval);
                    }
                }, 100);
            },

            /**
             * Apply input hardening for the shipping date field only.
             */
            lockInputToPicker: function () {
                var self = this;
                var attempts = 0;
                var maxAttempts = 20;
                var interval = setInterval(function () {
                    attempts++;

                    // Date input in Magento UI template is bound with id=uid.
                    var $input = $('#' + self.uid);
                    if ($input.length) {
                        $input.attr('autocomplete', 'off');
                        $input.attr('autocorrect', 'off');
                        $input.attr('autocapitalize', 'off');
                        $input.attr('spellcheck', 'false');
                        $input.attr('readonly', 'readonly');

                        // Prevent keyboard entry while still allowing picker interaction.
                        $input.on('keydown.portalpeopleDate input.portalpeopleDate paste.portalpeopleDate drop.portalpeopleDate', function (event) {
                            event.preventDefault();
                        });

                        clearInterval(interval);
                        return;
                    }

                    if (attempts >= maxAttempts) {
                        clearInterval(interval);
                    }
                }, 100);
            },

            initialize: function () {
                this._super();

                if (this.dataScope !== 'shippingFields.shipping_date') {
                    return this;
                }

                var config = window.checkoutConfig && window.checkoutConfig.portalpeopleShippingFields;
                var disabledWeekdays = config && Array.isArray(config.disabledWeekdays)
                    ? config.disabledWeekdays
                    : [];
                var disabledDates = config && Array.isArray(config.disabledDates)
                    ? config.disabledDates
                    : [];

                if (!this.options) {
                    this.options = {};
                }

                this.lockInputToPicker();
                this.initInlineDatepicker(disabledWeekdays, disabledDates);

                return this;
            }
        });
    };
});
