(function($){
// this.removeUnapprovedItemsFromCart();
    let app = {

        checkout_btn_el: $( '[data-checkout-approver]' ),
        checkbox_terms_accept_el: $( '#terms_use_accept_terms' ),
        submit_terms_accept_el: $( '#terms_use_submit' ),
        redirect_url: '',
        need_approval: [],
        cart_items: [],
        to_be_removed_count: 0,

        start: function() {
            this.sayHi();
            this.getRedirectURL();
            this.getProductsIdsNeedingApproval();
            this.parseCartItems();
            this.connectClicks();
        },

        sayHi: function() {
            console.info('### Checkout Approver is ON' );
        },

        getRedirectURL: function() {
            this.redirect_url = this.checkout_btn_el.data('checkoutUrl' );
        },

        getProductsIdsNeedingApproval: function() {
            let need_approval = this.checkout_btn_el.data('needApproval' );
            if ( ! need_approval ) {
                return;
            }

            need_approval = need_approval.toString();

            this.need_approval = need_approval
                .split(',')
                .map( function( item ) {
                    return parseInt( item );
                })
                .filter( function( item ) {
                    return Number.isInteger( item ) && parseInt(item) > 0;
                });

            this.to_be_removed_count = this.need_approval.length;
        },

        /**
         * Parses the html basket and extracts data needed for 'product removal' function to run.
         */
        parseCartItems: function() {
            this.cart_items = [];

            let basket = $('.basket_list');

            if ( ! basket.length ) {
                return;
            }

            let removeLinks = basket.find('.basket_item .remove_from_basket');

            if ( ! removeLinks.length ) {
                return;
            }

            let self = this;

            removeLinks.each( function() {
                self.cart_items.push({
                    id: $(this).data('id'),
                    item_key: $(this).data('cartItemKey'),
                    quantity: $(this).data('quantity'),
                    name: $(this).data('name'),
                    price: $(this).data('price'),
                    category: $(this).data('category')
                })
            });

        },

        connectClicks: function() {
            let self = this;

            this.checkout_btn_el.on('click', function( e ) {
                e.preventDefault();

                if ( true === self.canProceed() ) {
                    self.redirectToCheckout();
                } else {
                    self.displayApprovePopup();
                }

                return false;
            });

            this.submit_terms_accept_el.on( 'click', e => {
                e.preventDefault();
                $.magnificPopup.close();
                return false;
            });


        },

        redirectToCheckout: function() {
            window.location.href = this.redirect_url;
        },

        /**
         * Checks if user can proceed to checkout.
         *
         * @returns {boolean}
         */
        canProceed: function() {
            if ( ! this.need_approval.length ) {
                return true;
            }

            if ( ! this.cart_items.length ) {
                return true;
            }

            let cart_items_needing_approval = this.getCartItemsNeedingApproval();

            if ( ! cart_items_needing_approval.length ) {
                return true;
            }

            return false;
        },

        /**
         * Gets the cart items filtered: only ones that need approval.
         *
         * @returns {*[]}
         */
        getCartItemsNeedingApproval: function() {
            let self = this;

            let needing_approval = this.cart_items.filter( function( item ) {
                return ( -1 !== self.need_approval.indexOf( item.id ) );
            });

            return needing_approval;
        },

        displayApprovePopup: function() {
            $.magnificPopup.open({
                items: {
                    src: '#terms_use_popup'
                },
                type: 'inline',
                modal: true,
                mainClass: 'my-mfp-slide-bottom',
                callbacks: {
                    afterClose: this.onTermsModalClosed.bind(this)
                }
            }, 0);
        },

        /**
         * Actions hooked to moment the terms modal has closed.
         * If the checkbox was checked, the user will get redirected to the checkout page.
         * Otherwise: the items that need acceptance are removed from the cart.
         */
        onTermsModalClosed: function() {
            let terms_accepted = this.checkTermsAccepted();
            switch ( terms_accepted ) {
                case true:
                    this.redirectToCheckout()
                    break;
                case false:
                    this.removeUnapprovedItemsFromCart()
                    break;
            }
        },

        /**
         * Returns the current value of the terms checkbox.
         *
         * @returns {boolean}
         */
        checkTermsAccepted() {
            return this.checkbox_terms_accept_el.is( ':checked' );
        },

        /**
         * @todo
         */
        removeUnapprovedItemsFromCart: function() {
            let cart_items_needing_approval = this.getCartItemsNeedingApproval();

            if ( ! cart_items_needing_approval.length ) {
                return;
            }

            cart_items_needing_approval.forEach( cart_item => this.removeItemFromCart( cart_item ) );
        },

        /**
         * Triggers the AJAX removal of the item from cart.
         *
         * @todo need to refactor the original ajax call -- create an endpoint that allows to remove multiple cart items at once to avoid gitseparate calls and streamline the redirect.
         * @todo find a clearer way to do ajaxUpdateMainCart();
         *
         * @param cart_item
         */
        removeItemFromCart: function( cart_item ) {

            let self = this;

            let data = {
                action: 'remove_item_from_cart',
                cart_item_key: cart_item.item_key,
            }

            /**
             * Note: this ajax call is taken from main.js, as it has some
             * post-work to on the html elements.
             *
             * @todo the original function doesn't work with the 'main cart'
             * explanation: after removal of the item from the list the items are not refreshed
             * in the main cart by default. Here, i patch it with "ajaxUpdateMainCart()" call,
             * but it's not optimal.
             *
             * @see main.js:2045
             */
            $.ajax({
                url  : checkout_approver_params.ajaxurl,
                data : data,
                type : 'POST',
                beforeSend: function() {
                    $('.preloader-wrap').css('display', 'flex');
                },
                complete: function() {
                    $('.preloader-wrap').hide();
                    var html_cart  = $('.b_header .control_buttons .basket_wrapper .basket_inner');
                    var count_cart = html_cart.data('count-cart');
                    $('.b_header .icon_basket span').text( count_cart );
                },
                success: function(data) {
                    if ( data ) {
                        $('.b_header .control_buttons .basket_wrapper .basket_inner').replaceWith( data );
                        removeProductFromCart();
                        $('.b_header .basket_list').each(function () {
                            var $this = $(this);
                            $this.mCustomScrollbar({scrollInertia: 100});
                        });

                        self.to_be_removed_count--;
                        ajaxUpdateMainCart();

                        if ( self.to_be_removed_count < 1 ) {
                            self.redirectToCheckout();
                        }
                    }
                }
            });
        }

    }

    app.start();

})(jQuery);