jQuery(document).ready(function($) {
    function write_log(msg) {
        if (IS_WP_DEBUG === undefined || IS_WP_DEBUG === '1') {
            console.log(msg);
        }
    }
    // const { __, _x, _n, _nx } = wp.i18n;
    let $last_payload = [];
    let $prevCountry = undefined;
    let $customHtmlFixPlanned = false;
    let $prevCountryFixPlanned = false;
    let $customShippingAddPlanned = false;
    let $deliveryToOffice = true;
    let $previousShippingMethod = undefined;
    const $billingCountrySelect = $('#billing_country');
    const $stateInput = $('#nele_state');
    const $cityInput = $('#nele_place');
    const $cityIdInput = $("#nele_place_id");
    const $officeInput = $('#nele_office');
    const $officeIdInput = $("#nele_office_id");
    const $streetInput = $('#nele_street');
    const $streetNumInput = $('#nele_street_num');
    const $blockInput = $('input#nele_block');
    const $entranceInput = $('input#nele_entrance');
    const $floorInput = $('input#nele_floor');
    const $aptInput = $('input#nele_apt');
    const $postCodeInput = $("#billing_postcode");
    const $shipToRadio = $('input[name="nele_ship_to"]');
    const $billingCountryField = $('#billing_country_field');
    const $stateField = $('#nele_state_field');
    const $cityField = $('#nele_place_field');
    const $officeField = $('#nele_office_field');
    const $streetInputField = $('#nele_street_field');
    const $streetNumField = $('#nele_street_num_field');
    const $blockField = $('#nele_block_field');
    const $entranceField = $('#nele_entrance_field');
    const $floorField = $('#nele_floor_field');
    const $aptField = $('#nele_apt_field');
    const $postCodeField = $("#billing_postcode_field");
    const $customHtmlElem = $(neleCheckoutInlineHtml);
    let $isFirstShippingSetupRun = true;
    let $last_update_payload = undefined;

    if ($billingCountrySelect.val() === '') {
        $billingCountrySelect.val('BG');  // set initial country so that we do not see the default Woo checkout logic
    }

    function ajaxFormData(action) {
        return {
            action: action,
            country: $billingCountrySelect.val(),
            csm: getShippingMethod(),
            ship_to: getShipTo(),
            state_name: isShipToAddress() ? $stateInput.val() : undefined,
            city: $cityIdInput.val(),
            city_name: $cityInput.val(),
            postcode: $postCodeInput.val(),
            office: isShipToOffice() ? $officeIdInput.val() : undefined,
            office_name: isShipToOffice() ? $officeInput.val() : undefined,
            street: isShipToAddress() ? $streetInput.val() : undefined,
            street_num: isShipToAddress() ? $streetNumInput.val() : undefined,
            block: isShipToAddress() ? $blockInput.val() : undefined,
            entrance: isShipToAddress() ? $entranceInput.val() : undefined,
            floor: isShipToAddress() ? $floorInput.val() : undefined,
            apt: isShipToAddress() ? $aptInput.val() : undefined
        };
    }

    function getShippingMethod() {
        let selectedShippingMethod = jQuery('#custom_shipping').val();

        if (! selectedShippingMethod) {
            write_log("Getting the first shipping value from the list of available");
            selectedShippingMethod = $('input.shipping_method').first().val();
        }
        return selectedShippingMethod;
    }

    function arraysMatch(arr1, arr2) {
        if (Object.keys(arr1).length !== Object.keys(arr2).length) {
            return false;
        }
        for (const key in arr1) {
            if (! arr2.hasOwnProperty(key)) {
                return false;
            }
            if (arr1[key] !== arr2[key]) {
                return false;
            }
        }
        return true;
    }

    $(document).on('change', 'input.shipping_method', function() {
        write_log('on shipping method change');
        clearStateInput();
        clearCityInput();
        clearOfficeInput();
        write_log('on shipping method change: send ajax');
        update_checkout();
    });

    $(document).on('change', '#billing_country', function() {
        write_log('on billing country change');
        $cityField.add($officeField).add($streetInputField).add($streetNumField).add($blockField).add($entranceField).add($floorField).add($aptField).hide();
        clearStateInput();
        clearCityInput();
        clearOfficeInput();
        $('#custom_shipping_field').remove();
        write_log('on billing country change: send ajax');
        update_checkout();
    });

    $cityInput.on('change', function() {
        write_log("on cityInput change");
        const postcode_vals = $cityInput.val().match(/\(([^)]+)\)[^(]*$/);
        if (postcode_vals) {
            $postCodeInput.val(postcode_vals[1]);  // take the postcode from the place representation we have
        }
    });

    $postCodeInput.on('change', function() {
        if (! isShipToAddress()) {
            return;
        }
        write_log("on postcode change");
        onAddressChange();
    });

    function getShipTo() {
        return $shipToRadio.filter(':checked').val();
    }

    function isShipToOffice() {
        return getShipTo() === "to_office";
    }

    function isShipToAddress() {
        return getShipTo() === "to_address";
    }

    function clearStateInput() {
        $stateInput.autocomplete('close').val('').focus().blur();  // this is the w/a for the autocomplete UI issue
    }

    function clearCityInput() {
        $cityIdInput.val('');
        $cityInput.autocomplete('close').val('').focus().blur();  // this is the w/a for the autocomplete UI issue
    }

    function clearOfficeInput() {
        $officeIdInput.val('');
        $officeInput.autocomplete('close').val('').focus().blur();  // this is the w/a for the autocomplete UI issue
        onAddressChange();
    }

    function translateDeliveryCaptions() {
        const shipping_method = getShippingMethod();
        if (neleTranslations[shipping_method] === undefined) {
            // in case we hit some method not created by this plugin
            return;
        }
        const delivery_to = neleTranslations[shipping_method]['delivery_to'];
        const to_office_caption = neleTranslations[shipping_method]['to_office'];
        const to_office_description = neleTranslations[shipping_method]['to_office_description'];
        const to_address_caption = neleTranslations[shipping_method]['to_address'];
        const to_address_description = neleTranslations[shipping_method]['to_address_description'];
        $(".delivery-to > h3").text(delivery_to);
        $("li.to-office > label > div").html('<span>' + to_office_caption + '</span>' + to_office_description);
        $("li.to-address > label > div").html('<span>' + to_address_caption + '</span>' + to_address_description);
        if ($('#custom_shipping').find('li').length === 0) {
            $("section.delivery-to").show(1000);
        }
    }

    function store_field_values() {
        const vals = {
            "nele_shipping_method": getShippingMethod(),
            "nele_shipping_method_label": $("#select2-custom_shipping-container").text(),
            "nele_ship_to": getShipTo(),
            "nele_country": $billingCountrySelect.val(),
            "nele_state": $stateInput.val(),
            "nele_city": $cityInput.val(),
            "nele_city_id": $cityIdInput.val(),
            "nele_office": $officeInput.val(),
            "nele_office_id": $officeIdInput.val(),
            "nele_street": $streetInputField.val(),
            "nele_street_no": $streetNumInput.val(),
            "nele_block": $blockInput.val(),
            "nele_ent": $entranceInput.val(),
            "nele_floor": $floorInput.val(),
            "nele_apt": $aptInput.val(),
        }
        for (const key in vals) {
            window.localStorage.setItem(key, vals[key]);
        }
        return vals;
    }

    function update_checkout(just_run = false) {
        const payload = store_field_values();
        if ($last_update_payload !== undefined && arraysMatch($last_update_payload, payload)) {
            return;
        }
        if (just_run) {  // wait a little before triggering the refresh - data is not there yet
            write_log("Running the update_checkout");
            $last_update_payload = payload;
            $(document.body).trigger('update_checkout');
        } else {
            setTimeout(update_checkout, 1000, true);
            write_log("Scheduled update_checkout run in 1000 ms");
        }
    }

    function onAddressChange()  {
        write_log("onAddressChange");
        const payload = ajaxFormData('nele_ajax_update_price');
        if (arraysMatch($last_payload, payload)) {
            // write_log('onAddressChange: The AJAX payload is the same as the last request. Skipping.');
            return;
        }
        const storedPayload = $last_payload;
        $last_payload = payload;
        neleShowLoader();
        $.ajax({
            url: wc_checkout_params.ajax_url,
            method: 'POST',
            dataType: 'json',
            data: payload,
            success: function () {
                setTimeout(()=> {
                        write_log('onAddressChange: success: send ajax');
                        update_checkout();
                    }, 1000); // since sometimes we hit a race
                hideLoaderIfShown();
            },
            error: function(error) {
                console.error('Error posting address data: ' + error);
                write_log('onAddressChange: error: send ajax');
                $last_payload = storedPayload; // revert the stored value
                update_checkout();
                hideLoaderIfShown();
            }
        });
    }

    function restoreAutocomplete(use_default) {
        write_log("restoreAutocomplete: use_default=" + use_default);
        $streetInput.attr("autocomplete", use_default ? "off" : "one-time-code");
        $streetNumInput.attr("autocomplete", use_default ? "off" : "one-time-code");
    }

    function setStreetsAutocomplete() {
        write_log("setStreetsAutocomplete");
        const payload = ajaxFormData('nele_ajax_has_streets');
        if (arraysMatch($last_payload, payload)) {
            write_log('setStreetsAutocomplete: The AJAX payload is the same as the last request. Skipping.');
            return;
        }
        $.ajax({
            url: wc_checkout_params.ajax_url,
            type: "POST",
            dataType: "json",
            data: payload,
            success: function (result, status, xhr) {
                restoreAutocomplete(result.result === '0')
            },
            error: function (xhr, status, error) {
                write_log("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
            }
        });
    }

    $stateInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: wc_checkout_params.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: ajaxFormData('nele_ajax_get_states'),
                success: function( data ) {
                    response( data );
                },
                beforeSend: function() {
                    const loader = $('.loader-states');
                    if (loader.length > 0) {
                        loader.show();
                    } else {
                        $('<div>', { class: 'loader loader-states' }).insertAfter($stateInput);
                    }
                },
                complete: function() {
                    $('.loader-states').hide();
                }
            } );
        },
        select: function( event, ui ) {
            event.preventDefault();
            $stateInput.val(ui.item.label);
            write_log("state set to " + ui.item.value);
            clearCityInput();
        },
        focus: function(event, ui) {
            event.preventDefault();
        }
    });

    $cityInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: wc_checkout_params.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: ajaxFormData('nele_ajax_get_cities'),
                success: function( data ) {
                    response( data );
                },
                beforeSend: function() {
                    const loader = $('.loader-cities');
                    if (loader.length > 0) {
                        loader.show();
                    } else {
                        $('<div>', { class: 'loader loader-cities' }).insertAfter($cityInput);
                    }
                },
                complete: function() {
                    $('.loader-cities').hide();
                }
            } );
        },
        select: function( event, ui ) {
            event.preventDefault();
            $cityInput.val(ui.item.label);
            $cityIdInput.val(ui.item.value);
            write_log("cityId set to " + ui.item.value);
            const postcode_vals = ui.item.label.match(/\(([^)]+)\)[^(]*$/);
            if (postcode_vals) {
                write_log('setting postcode value since city was selected');
                $postCodeInput.val(postcode_vals[1]);  // take the postcode from the place representation we have
            }
            onAddressChange();
            if ($deliveryToOffice) {
                $officeField.show();
                $officeInput.autocomplete("search", ui.item.label[0]);
            }
            if (isShipToAddress() && $cityIdInput.val() !== '') {
                setStreetsAutocomplete();
            }
        },
        focus: function(event, ui) {
            event.preventDefault();
        },
        change: function (event, ui) {
            // is not autocomplete selection
            if (ui.item === null && $cityIdInput.val() !== '') {
                write_log("resetting the cityId");
                // clearCityInput();
                $cityIdInput.val('');
            }
            if (isShipToAddress() && $cityIdInput.val() !== '') {
                setStreetsAutocomplete();
            } if (isShipToOffice()) {
                clearOfficeInput();
            }
            // validateCityInputVal();
        }
    });

    $officeInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: wc_checkout_params.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: ajaxFormData('nele_ajax_get_offices'),
                minLength: 0,
                success: function( data ) {
                    response( data );
                },
                beforeSend: function() {
                    const loader = $('.loader-offices');
                    if (loader.length > 0) {
                        loader.show();
                    } else {
                        $('<div>', { class: 'loader loader-offices' }).insertAfter($officeInput);
                    }
                },
                complete: function() {
                    $('.loader-offices').hide();
                }
            } );
        },
        select: function( event, ui ) {
            event.preventDefault();
            $officeInput.val(ui.item.label);
            $officeIdInput.val(ui.item.value);
            write_log("officeId set to " + ui.item.value);
            onAddressChange();
        },
        focus: function(event, ui) {
            event.preventDefault();
        },
        change: function (event, ui) {
            if (ui.item === null && $officeIdInput.val() !== '') {
                write_log("resetting the officeId");
                $officeIdInput.val('');
            }
        }
    }).click(function(){
        $(this).autocomplete('search', $officeInput.val() || $cityInput[0])
    });

    $streetInput.autocomplete({
        source: function( request, response ) {
            if ($cityIdInput.val() === '') {
                // no need in sending the street autoload request if city was specified by hand
                return;
            }
            $.ajax( {
                url: wc_checkout_params.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: ajaxFormData('nele_ajax_get_streets'),
                success: function( data ) {
                    response( data );
                },
                beforeSend: function() {
                    const loader = $('.loader-streets');
                    if (loader.length > 0) {
                        loader.show();
                    } else {
                        $('<div>', { class: 'loader loader-streets' }).insertAfter($streetInput);
                    }
                },
                complete: function() {
                    $('.loader-streets').hide();
                }
            } );
        },
        select: function( event, ui ) {
            event.preventDefault();
            $streetInput.val(ui.item.label);
        },
        focus: function(event, ui) {
            event.preventDefault();
        }
    });

    function onCitySelectWhenToAddress() {
        if (! isShipToAddress()) {
            return;
        }
        write_log("onCitySelectWhenToAddress");
        onAddressChange();
    }

    $officeInput.on('change', onAddressChange);
    $cityInput.on('change', onCitySelectWhenToAddress);

    function arrangeAddrFields(parent) {
        write_log("arrangeAddrFields");
        parent.append($postCodeField).append($streetInputField).append($streetNumField);
        const customAddrFields = $(".district-detailed-fields");
        if (customAddrFields.length === 0) {
            $('<div class="district-detailed-fields">').insertAfter($streetNumField);
        } else {
            customAddrFields.insertAfter($streetNumField);
        }
        if ($(".district-detailed-fields #nele_block_field").length === 0) {
            $blockField.add($entranceField).add($floorField).add($aptField).appendTo($(".district-detailed-fields"));
        }
        const fields = $streetInputField.add($streetNumField).add($blockField).add($entranceField).add($floorField).add($aptField);
        fields.show();
    }

    function fixCustomHtmlLayout() {
        if (! $billingCountrySelect.val()) {
            return;
        }
        write_log("fixCustomHtmlLayout");
        $billingCountryField.after($customHtmlElem);
        const toOffice = $('#to-office-fields');
        const toAddress = $('#to-address-fields');
        if ($deliveryToOffice) {
            toAddress.hide();
            $stateField.hide();
            $cityField.removeClass('form-row-first');
            $cityField.addClass('form-row-wide');
            toOffice.append($cityField).append($officeField);
            $cityField.show();
            toOffice.show();
        } else {
            toOffice.hide();
            $cityField.removeClass('form-row-wide');
            $cityField.addClass('form-row-first');
            toAddress.append($stateField).append($cityField).append($postCodeField).append($streetInputField).append($streetNumField).append($blockField).append($entranceField).append($floorField).append($aptField);
            $stateField.show();
            $cityField.show();
            toAddress.show();
        }
        arrangeAddrFields(toAddress);
    }

    function onBillingCountryFieldRendered() {
        write_log("onBillingCountryFieldRendered");
        $previousShippingMethod = undefined;
        const radioButtons = $('.delivery-to--content input[type="radio"]');
        radioButtons.off('change').change(function() {
            write_log("onBillingCountryFieldRendered change");
            const toOffice = $('#to-office-fields');
            const toAddress = $('#to-address-fields');
            let parentLi = $(this).closest('li');
            if (parentLi.hasClass('to-office')) {
                $deliveryToOffice = true;
                jQuery("#nele_ship_to_to_office").click();  // select value in a woo field
                $cityField.removeClass('form-row-first');
                $cityField.addClass('form-row-wide');
                $stateField.hide();
                toOffice.append($cityField).append($officeField);
                $cityField.show();
                if ($cityIdInput.val()) {
                    $officeField.show();
                } else {
                    $cityInput.val('');
                }
                toOffice.show();
                toAddress.hide();
            } else if (parentLi.hasClass('to-address')) {
                $deliveryToOffice = false;
                jQuery("#nele_ship_to_to_address").click();
                $cityField.removeClass('form-row-wide');
                $cityField.addClass('form-row-first');
                toAddress.append($stateField).append($cityField).append($postCodeField).append($streetInputField);
                $stateField.show();
                $cityField.show();
                arrangeAddrFields(toAddress);
                toOffice.hide();
                if ($cityInput.val()) {
                    setStreetsAutocomplete();
                }
                toAddress.show();
            }
            onAddressChange();  // force the delivery price re-calculation
        });
    }

    function hideLoaderIfShown() {
        neleShowLoader(false);
    }

    function originalShippingMethodsAmt() {
        return  $('#shipping_method').find('li').length;
    }

    function createCustomShippingMethodSelect() {
        write_log("createCustomShippingMethodSelect");
        const $originalShippingMethods = $('#shipping_method');
        if (originalShippingMethodsAmt() === 0) {
            $("section.delivery-to").hide();
            jQuery("#select2-custom_shipping-container span").text(neleLoc.no_shipping_methods);
        } else {
            jQuery("#select2-custom_shipping-container span").text(neleLoc.select_a_shipping_method);
        }
        const customShipping = $('#custom_shipping');
        customShipping.empty();
        const existingField = $("#custom_shipping_field");
        if (existingField.length > 0) {
            write_log("createCustomShippingMethodSelect: element already exists");
            existingField.insertAfter($billingCountryField);
        } else {
            write_log("createCustomShippingMethodSelect: creating new element");
            $('<p class="form-row form-row-wide address-field" id="custom_shipping_field" data-priority="43"><label for="custom_shipping">' + neleLoc.delivery_method + '&nbsp;<abbr class="required" title="' + neleLoc.required + '">*</abbr></label><select id="custom_shipping" data-placeholder="' + neleLoc.select_a_shipping_method + '"></select></p>').insertAfter($billingCountryField);
        }
        const customShippingMethodSelect2 = customShipping.select2();

        $originalShippingMethods.find('li').each(function() {
            customShippingMethodSelect2.append($('<option>', {
                text: $(this).find('label').text(),
                value: $(this).find('input').val()
            }));
        });
        // select same shipping method in the original selector
        customShippingMethodSelect2.on('change', changeOriginalShippingMethod);
    }

    function cmpShippingMethods() {
        const sourceValue = $('#custom_shipping').find(":selected").text();
        const targetValue = $('#shipping_method').find('label:contains("'+sourceValue+'")').siblings('input').filter(':checked, :not(:radio)').next('label').text();
        const match = targetValue.length > 0;
        if (! match) {
            write_log("Shipping methods do not match: " + sourceValue + " != " + $('#shipping_method').find("input:checked").text());
        }
        return match;
    }

    let shippingAttempts = 0;

    function changeOriginalShippingMethodCheckup() {
        if (cmpShippingMethods() === true) {
            shippingAttempts = 0;
            hideLoaderIfShown();
            return;
        }
        // try to set once again
        shippingAttempts += 1;
        if (shippingAttempts > 10) {
            const sourceValue = $('#custom_shipping').find(":selected").text();
            write_log("changeOriginalShippingMethodCheckup: unable to set the shipping value by selected in custom shipping: " + sourceValue);
            return;
        }
        setTimeout(changeOriginalShippingMethod, 500);
    }

    function changeOriginalShippingMethod() {
        write_log("changeOriginalShippingMethod");
        if (cmpShippingMethods() === true) {
            shippingAttempts = 0;
            hideLoaderIfShown();
            return;
        }
        const sourceValue = $('#custom_shipping').find(":selected").text();
        if (sourceValue.length === 0) {
            write_log("changeOriginalShippingMethod: scheduling new run since new value is empty");
            setTimeout(changeOriginalShippingMethod, 600);
            return;
        }
        const targetValue = $('#shipping_method').find('label:contains("'+sourceValue+'")').siblings('input');
        if (targetValue.length === 0) {
            write_log("changeOriginalShippingMethod: scheduling new run since nothing to select from");
            setTimeout(changeOriginalShippingMethod, 600);
            return;
        }
        neleShowLoader();
        write_log("changeOriginalShippingMethod: new value=" + sourceValue);
        if ($('#shipping_method').find('input:checked').length === 0 && ! $isFirstShippingSetupRun) {
            targetValue.attr("checked", true);
        } else {
            targetValue.click();
            $isFirstShippingSetupRun = false;
        }
        write_log("changeOriginalShippingMethod: scheduling new run with the checkup logic");
        setTimeout(changeOriginalShippingMethodCheckup, 500);
    }

    // fix the layout of the custom html fields since they are moved around on Woo ajax complete
    const layoutFixer = new MutationObserver(function(mutationsList, observer) {
        if (!$customHtmlFixPlanned && ($('.woocommerce-billing-fields .delivery-to').is(':first-child') || $(".delivery-to").length === 0)) {
            $customHtmlFixPlanned = true;
            setTimeout(function() {
                fixCustomHtmlLayout(); // since delivery fields are jumping to the top of the page
                $customHtmlFixPlanned = false;
            }, 200);
        }
        if (!$prevCountryFixPlanned && $prevCountry !== $billingCountrySelect.val()) {
            $('#custom_shipping').empty();
            $prevCountryFixPlanned = true;
            $prevCountry = $billingCountrySelect.val();
            setTimeout(function() {
                onBillingCountryFieldRendered();  //since the re-rendered html needs to have event listeners attached
                $prevCountryFixPlanned = false;
            }, 200);
        }
        if (! $customShippingAddPlanned && $("#custom_shipping_field").length === 0) {
            $customShippingAddPlanned = true;
            setTimeout(function() {
                createCustomShippingMethodSelect();  // since the re-rendered html needs to have event listeners attached
                $customShippingAddPlanned = false;
            }, 200);
        }
    });
    layoutFixer.observe(document.documentElement, { childList: true, subtree: true });

    function onShipToRadioRendered() {
        write_log("onShipToRadioRendered");
        $("input#toOffice").click(); // make a default delivery selection
        $cityInput.attr("autocomplete", "one-time-code");
        restoreAutocomplete(false);
        changeOriginalShippingMethod();
    }

    // do some initial setup
    const initialSetup = new MutationObserver(function(mutationsList, observer) {
        if ($('input#toOffice').length > 0) {
            createCustomShippingMethodSelect();
            waitAndRunShippingMethodChangeLogic();
            setTimeout(function() {
                const checkoutForm = $('form.checkout');
                if (checkoutForm.length) {
                    checkoutForm.off('input keydown change');
                }
                onShipToRadioRendered();
            }, 300);
            initialSetup.disconnect();
        }
    });
    initialSetup.observe(document.documentElement, { childList: true, subtree: true });

    function customShippingMethodChangedObserverLogic() {
        const shippingMethod = getShippingMethod();
        if (shippingMethod && $previousShippingMethod !== shippingMethod) {
            write_log('Translated changed shipping method: old ' + $previousShippingMethod + ' != new ' + shippingMethod);
            $previousShippingMethod = shippingMethod;
            translateDeliveryCaptions();
        }
    }

    // on select shipping method change
    const customShippingMethodChangedObserver = new MutationObserver(function(mutationsList, observer) {
        customShippingMethodChangedObserverLogic();
    });
    customShippingMethodChangedObserver.observe(document.documentElement, { childList: true, subtree: true });

    // check post code field, since it should be displayed in a different manner for different cases
    const postCodeFieldFixer = new MutationObserver(function(mutationsList, observer) {
        if ($billingCountrySelect.val() !== '' && $postCodeField.length > 0) {
            setTimeout(function() {
                $postCodeField.removeClass('form-row-wide');
                $postCodeField.addClass('form-row-last');
                $postCodeField.show();
            }, 300);
            postCodeFieldFixer.disconnect();
        }
    });
    postCodeFieldFixer.observe(document.documentElement, { childList: true, subtree: true });

    function shippingMethodChangedObserverLogic() {
        write_log("shippingMethodChangedObserverLogic: shipping methods list was modified");
        createCustomShippingMethodSelect();
        customShippingMethodChangedObserverLogic();
    }

    // Function to wait for AJAX requests to complete and then run the observer logic
    function waitAndRunShippingMethodChangeLogic() {
        changeOriginalShippingMethodCheckup();
        let sourceValues = [];
        $('#shipping_method').find('li').each(function() {
            sourceValues.push($(this).find('input').val());
        });
        let targetValues = [];
        $('#custom_shipping').find('option').each(function() {
            targetValues.push($(this).val());
        });
        if (! arraysMatch(sourceValues, targetValues)) {
            shippingMethodChangedObserverLogic();
        }
        setTimeout(waitAndRunShippingMethodChangeLogic, 1000);
    }
});

