jQuery(document).ready(function($) {
    function write_log(msg) {
        if (IS_WP_DEBUG === undefined || IS_WP_DEBUG === '1') {
            console.log(msg);
        }
    }
    let $last_payload = [];
    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 $districtInput = $('#nele_district');
    const $blockInput = $('#nele_block');
    const $entranceInput = $('#nele_entrance');
    const $floorInput = $('#nele_floor');
    const $aptInput = $('#nele_apt');
    const $postCodeInput = $("#_billing_postcode");
    const $officeField = $('p.nele_office_field');
    const $streetInputField = $('p.nele_street_field');
    const $streetNumField = $('p.nele_street_num_field');
    const $districtField = $('p.nele_district_field');
    const $blockField = $('p.nele_block_field');
    const $entranceField = $('p.nele_entrance_field');
    const $floorField = $('p.nele_floor_field');
    const $aptField = $('p.nele_apt_field');
    const $deliveryToOffice = $("#nele_ship_to");
    const $billing_first_name = $("#_billing_first_name");
    const $billing_last_name = $("#_billing_last_name");
    const $billing_company = $("#_billing_company");
    const $billing_country = $("#_billing_country");
    const $billing_email = $("#_billing_email");
    const $billing_phone = $("#_billing_phone");
    const $payment_method = $("#_payment_method");
    const $transaction_id = $("#_transaction_id");

    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;
    }

    function getShipTo() {
        return isShipToOffice() ? "to_office" : "to_address";
    }

    function isShipToOffice() {
        return $deliveryToOffice.is(':checked');
    }

    function isShipToAddress() {
        return ! isShipToOffice();
    }

    if ($officeIdInput.val() !== '') {
        $deliveryToOffice.click();
    }

    function setFieldsVisibility() {
        $officeField.toggle(isShipToOffice());
        $streetInputField.add($streetNumField).add($districtField).add($blockField).add($entranceField).add($floorField).add($aptField).toggle(! isShipToOffice());
    }

    function showWooMessage(response, isError = false) {
        const refinedMsg = response['data'] !== undefined ? response['data']['response'] : response['response'];
        if (refinedMsg === undefined || refinedMsg.length === 0) {
            write_log("Unknown error happened - no message is available. See logs");
            return;
        }
        const afterElem = $("#lost-connection-notice");
        const elem = $(`<div class="`+(isError ? "error" : "notice notice-success")+`" style="display: block;">\t<p><strong>`+refinedMsg+`</strong></p></div>`)
        afterElem.after(elem);
        write_log((isError ? "Error happened: " : "") + refinedMsg);
    }

    function nele_register_ajax_handler(selector, action) {
        $(selector).on('click', function() {
            neleShowLoader();
            const orderId = $(this).data('order-id');
            const data = {
                'action': action,
                'order_id': orderId
            };
            $.ajax({
                type: 'POST',
                url: nele_orders_object.ajax_url,
                data: data,
                success: function(response) {
                    const isError = response.success === false;
                    showWooMessage(response, isError);
                    if (! isError) {
                        location.reload();
                    }
                    neleShowLoader(false);
                },
                error: function(response) {
                    showWooMessage(response, true);
                    neleShowLoader(false);
                }
            });
        });
    }

    nele_register_ajax_handler('.create-shipment-button', 'create_shipment_action');
    nele_register_ajax_handler('.generate-pdf-button', 'generate_pdf_action');

    function save_changes_action() {
        neleShowLoader();
        const data = {
            'action': 'custom_save_changes_action',
            'order_id': $('.save-changes-button').data('order-id'),
            'ship_to_office': isShipToOffice(),
            'state': $stateInput.val(),
            'place': $cityInput.val(),
            'place_id': $cityIdInput.val(),
            'office': $officeInput.val(),
            'office_id': $officeIdInput.val(),
            'street': $streetInput.val(),
            'street_num': $streetNumInput.val(),
            'district': $districtInput.val(),
            'block': $blockInput.val(),
            'entrance': $entranceInput.val(),
            'floor': $floorInput.val(),
            'apt': $aptInput.val(),
            'csm': getShippingMethod(),
            'billing_first_name': $billing_first_name.val(),
            'billing_last_name': $billing_last_name.val(),
            'billing_company': $billing_company.val(),
            'billing_country': $billing_country.val(),
            'billing_postcode': $postCodeInput.val(),
            'billing_email': $billing_email.val(),
            'billing_phone': $billing_phone.val(),
            'payment_method': $payment_method.val(),
            'transaction_id': $transaction_id.val()
        };
        if (arraysMatch($last_payload, data)) {
            write_log('save_changes_action: The AJAX payload is the same as the last request. Skipping.');
            return;
        }
        $last_payload = data;
        $.ajax({
            type: 'POST',
            url: nele_orders_object.ajax_url,
            data: data,
            success: function (response) {
                const isError = response.success === false;
                showWooMessage(response, isError);
                if (! isError) {
                    location.reload();
                }
                neleShowLoader(false);
            },
            error: function (response) {
                showWooMessage(response, true);
                neleShowLoader(false);
            }
        });
    }

    $(".cancel-edit-button").on('click', function() {
        $(".edit_address").hide();
        $(".address").show();
        const edit_btn = $("h3 a.edit_address").first();
        edit_btn.show();
        window.scrollTo(0, 0);
    })

    function validateCityInputVal() {
        if ($cityIdInput.val() === '' && $postCodeInput.val() !== '') {
            write_log("postcode set empty");
            $postCodeInput.val('');
        }
    }

    $cityInput.on('keyup keypress blur change', function(e) {
        validateCityInputVal();
    });

    $('.save-changes-button').on('click', save_changes_action);

    $billing_first_name.add($billing_last_name).add($billing_email).add($postCodeInput).add($billing_country).
    add($billing_company).add($transaction_id).add($payment_method).add($billing_phone).add($billing_email).
    add($cityInput).add($officeInput).add($streetInput).add($streetNumInput).add($districtInput).add($blockInput).
    add($entranceInput).add($floorInput).add($aptInput).on('keypress',function(e) {
        if(e.which === 13) {
            save_changes_action();
        }
    });

    function getShippingMethod() {
        return $('select.shipping_method option:selected').val();
    }

    $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
        }
    });

    function hideOfficeField() {
        $officeIdInput.val('');
        $officeInput.val('');
        $officeField.hide();
    }

    $stateInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: nele_orders_object.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);
            $cityIdInput.val('');
            $cityInput.autocomplete('close').val('').focus().blur();  // this is the w/a for the autocomplete UI issue
        },
        focus: function(event, ui) {
            event.preventDefault();
        }
    });

    $cityInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: nele_orders_object.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: {
                    action: 'nele_ajax_get_cities',
                    country: $billingCountrySelect.val(),
                    csm: getShippingMethod(),
                    ship_to: getShipTo(),
                    city: $cityIdInput.val(),
                    city_name: $cityInput.val()
                },
                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) {
                $postCodeInput.val(postcode_vals[1]);  // take the postcode from the place representation we have
            }
            if (isShipToOffice()) {
                $officeField.show();
                $officeInput.autocomplete("search", ui.item.label[0]);
            }
        },
        focus: function(event, ui) {
            event.preventDefault();
        },
        change: function (event, ui) {
            if (ui.item === null && $cityIdInput.val() !== '') {
                write_log("resetting the cityId");
                $cityIdInput.val('');
                hideOfficeField();
            }
            validateCityInputVal();
        }
    });

    $officeInput.autocomplete({
        source: function( request, response ) {
            $.ajax( {
                url: nele_orders_object.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: {
                    action: 'nele_ajax_get_offices',
                    country: $billingCountrySelect.val(),
                    csm: getShippingMethod(),
                    ship_to: getShipTo(),
                    city: $cityIdInput.val(),
                    city_name: $cityInput.val(),
                    office: $officeIdInput.val(),
                    office_name: $officeInput.val()
                },
                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);
        },
        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: nele_orders_object.ajax_url,
                method: 'POST',
                dataType: 'json',
                data: {
                    action: 'nele_ajax_get_streets',
                    country: $billingCountrySelect.val(),
                    csm: getShippingMethod(),
                    ship_to: getShipTo(),
                    city: $cityIdInput.val(),
                    city_name: $cityInput.val(),
                    street: $streetInput.val(),
                    street_num: $streetNumInput.val(),
                    district: $districtInput.val(),
                    block: $blockInput.val(),
                    entrance: $entranceInput.val(),
                    floor: $floorInput.val(),
                    apt: $aptInput.val()
                },
                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();
        }
    });

    const initialSetuper = new MutationObserver(function(mutationsList, observer) {
        if ($deliveryToOffice.length > 0) {
            setTimeout(function() {
                $deliveryToOffice.change(setFieldsVisibility);
                setFieldsVisibility();
                $cityInput.attr("autocomplete", "one-time-code");
                $streetInput.attr("autocomplete", "one-time-code");
                $streetNumInput.attr("autocomplete", "one-time-code");
            }, 300);
            initialSetuper.disconnect();
        }
    });
    initialSetuper.observe(document.documentElement, { childList: true, subtree: true });

    let $edit_box = jQuery("#nele-order-settings-table");
    const orderEditObserver = new MutationObserver(function(mutationsList, observer) {
        if ($edit_box.css('display') !== 'none') {
            $edit_box.css('display', 'table');
        }
    });
    orderEditObserver.observe(document.documentElement, { childList: true, subtree: true });
});
