define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote',
    'uiRegistry',
    'Magento_Checkout/js/model/url-builder'
], function ($, wrapper, quote, registry, urlBuilder) {
    'use strict';

    return function (targetModule) {
        return wrapper.wrap(targetModule, function (originalAction, paymentData, messageContainer) {
            
            var shippingDate = null;
            var shippingW3w = null;
            var shippingMessage = null;

            // Read directly from checkoutProvider at order placement time (user has filled fields by now)
            var checkoutProvider = registry.get('checkoutProvider');
            if (checkoutProvider) {
                var shippingFields = checkoutProvider.get('shippingFields');
                if (shippingFields) {
                    shippingDate = shippingFields.shipping_date || null;
                    shippingW3w = shippingFields.shipping_w3w || null;
                    shippingMessage = shippingFields.shipping_message || null;
                }
            }

            // Fallback to window data if checkoutProvider was empty
            if (!shippingDate && !shippingMessage && window.shippingFieldsData) {
                shippingDate = window.shippingFieldsData.shipping_date;
                shippingW3w = window.shippingFieldsData.shipping_w3w;
                shippingMessage = window.shippingFieldsData.shipping_message;
            }

            if (shippingDate || shippingW3w || shippingMessage) {
                var deferred = $.Deferred();
                $.ajax({
                    url: urlBuilder.createUrl('/carts/mine/save-shipping-fields', {}),
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify({
                        shippingDate: shippingDate || '',
                        shippingW3w: shippingW3w || '',
                        shippingMessage: shippingMessage || ''
                    })
                }).done(function () {
                }).fail(function () {
                }).always(function () {
                    originalAction(paymentData, messageContainer)
                        .done(deferred.resolve)
                        .fail(deferred.reject);
                });
                return deferred.promise();
            }

            return originalAction(paymentData, messageContainer);
        });
    };
});
