<!--
 * -------------------------------------------------------------------------
 *
 * The Vue template written in PUG format.
 * It is inspired by Morooka's codepen Shopping UI (see https://codepen.io/mo-ro/pen/jObjGJm).
 *
 * -------------------------------------------------------------------------
 -->

    <template lang="pug">
        .wrapper
            .screen.-left
                .app-bar
                    .bottom-area
                        .price
                            img.logo(:src="vendorLogo" loading="lazy" alt="")
                        .button(@click="gotoHome()")
                            p GO TO HOME
                .title Picked items
                transition(name="noContent")
                    .no-content(v-if="$data.shopItems.length == 0")
                        p.text This vendor currently has no products in our stock.
                    .no-content(v-if="$data.shopItems.length == 1 && $data.shopItems[ 0 ][ 'id' ] == null")
                        p.text
                            code {{ $data.shopItems[ 0 ][ 'brand' ] }}
                            span &nbsp; currently has no products in our stock.
                .shop-items(v-if="$data.shopItems.length >= 1 && $data.shopItems[ 0 ][ 'id' ] != null")
                    .item(v-for="item in shopItems")
                        .item-block
                            .image-area(:style="{backgroundColor: item.color}")
                                img.image(:src="item.image")
                            .name
                                small {{ item.brand }}
                                span {{ item.name }}
                            .description {{ item.description }}
                            .bottom-area(:data-amount="item.amount")
                                .price ${{ item.price }}
                                .button(@click="addToCart(item)" :ref="'addButton' + item.id" :class="{'-active': item.inCart}")
                                    transition(name="buttonText" mode="out-in")
                                        p(v-if="!item.inCart")
                                            span(v-if="item.amount > 0") ADD TO CART
                                            span(v-else="") ABSENT NOW
                                        .cover(v-else="")
                                            .check
            .screen.-right(ref="cartItems")
                .app-bar
                    .bottom-area
                        .price
                            img.logo(:src="vendorLogo" loading="lazy" alt="")
                        .button(@click="gotoHome()")
                            p GO TO HOME
                .title Your cart
                transition(name="noContent")
                    .no-content(v-if="$data.cartItems.length === 0")
                        p.text Your cart is empty.
                form.cart-items(action="order/add" method="post")
                    transition-group(name="cartList" tag="div")
                        .cart-item(v-for="item in $data.cartItems" :key="item.id")
                            .left
                                .cart-image
                                    .image-wrapper
                                        img.image(:src="item.image")
                            .right
                                .name
                                    small {{ item.brand }}
                                    span {{ item.name }}
                                .price ${{ item.price }}
                                .count
                                    .button(@click="decrement(item)") <
                                    .number {{item.count}}
                                    .button(@click="increment(item)") >
                            input(type="hidden" :name="'products[' + item.id + ']'" :value="item.count")
                    legend(v-if="$data.cartItems.length > 0")
                        small Buyer name:
                        input(type="text" name="customer" :value="customer.name" required)
                        input(type="hidden" name="customer_id" :value="customer.id")
                    legend(v-if="$data.cartItems.length > 0")
                        small Buyer delivery address:
                        input(type="text" name="delivery" :value="customer.address" required)
                    .order-details(v-if="$data.cartItems.length > 0")
                        .bottom-area
                            .price ${{ cartSum }}
                            .button(@click="order()")
                                p ORDER
                    input(type="hidden" name="submit" value="1")
    </template>

    <!--
     * ---------------------------------------------------------------------
     *
     * Define variables used in the template above or in its scripts below.
     * They are "shopItems", "cartItems", "cartSum", "vendorLogo",
     * "vendorJSON", "customerJSON", "customer".
     *
     * ---------------------------------------------------------------------
     -->

    <script>
        export default {
            data ( ) {
                const node = document.querySelector('html head link[rel="canonical"]');
                return {
                    shopItems:    [ ],
                    cartItems:    [ ],
                    cartSum:      0,
                    vendorLogo:   'dataset' in node
                                             ?  node.dataset.logo
                                             :  '',
                    vendorJSON:   'dataset' in node
                                            ?  node.dataset.url + '/json'
                                            :  '',
                    customerJSON: 'customer/json',
                    customer:     { id:      0,
                                    name:    '',
                                    address: '' }
                };
            },

            /**
             * -------------------------------------------------------------
             *
             * Handle the event when the template above is successfully
             * parsed and mounted on the page.
             *
             * -------------------------------------------------------------
             */

            mounted: function ( ) {
                this.readProducts (
                    this.readCustomer
                );
            },

            /**
             * -------------------------------------------------------------
             *
             * Define procedures used in the template above. They are
             * "addToCart", "decrement", "increment", "order".
             *
             * -------------------------------------------------------------
             */

            methods: {
                gotoHome ( ) {
                    const url = document.baseURI;
                    window.location.assign ( url );
                },

                addToCart ( item ) {
                    if ( ! item.inCart ) {
                        if ( item.amount > 0 ) {
                            item.inCart = true;
                            const newItem = Object.assign ( { }, item, { count:    1,
                                                                         maxcount: item.amount } );
                            this.$data.cartItems.push ( newItem );
                            const animationTarget = this.$refs[ `addButton${item.id}` ];
                            gsap.to ( animationTarget, {
                                width:    '4.6rem',
                                duration: 0.8,
                                ease:     'power4'
                            });
                            this.plusCartSum ( item.price );
                        }
                    }
                    this.$nextTick ( ( ) => {
                        this.$refs.cartItems.scrollTop = this.$refs.cartItems.scrollHeight;
                    });
                },

                decrement ( item ) {
                    if ( item.count > 0 ) {
                        item.count--;
                        this.minusCartSum ( item.price );
                    }
                    const targetShopItem = this.$data.shopItems.find (
                        ( shopItem ) => shopItem.id === item.id
                    );
                    this.$nextTick( function ( ) {
                        if ( item.count < 1 ) {
                            const animationTarget = this.$refs[ `addButton${targetShopItem.id}` ];
                            gsap.to ( animationTarget, {
                                width:    '13.6rem',
                                duration: 0.8,
                                ease:     'power4'
                            });
                            targetShopItem.inCart = false;
                            const targetIndex = this.$data.cartItems.findIndex (
                                ( cartItem ) => cartItem.id === item.id
                            );
                            this.$data.cartItems.splice ( targetIndex, 1 );
                        }
                    });
                },

                increment ( item ) {
                    if ( item.count < item.maxcount ) {
                        item.count++;
                        this.plusCartSum ( item.price );
                    } else if ( item.count < 1 ) {
                        this.decrement ( item );
                    }
                },

                order ( ) {
                    if ( this.$data.cartItems.length > 0 ) {
                        const form = event.target.closest ( 'form' );
                        if ( form ) {
                            if ( form.reportValidity ( ) ) {
                                document.body.classList.add ( 'ordering' );
                                setTimeout (
                                    ( ) => { form.requestSubmit ( ); },
                                    750
                                );
                            }
                        }
                    }
                },

                /**
                 * ---------------------------------------------------------
                 *
                 * Define local procedures used only in scripts above. They
                 * are "plusCartSum", "minusCartSum", "readProducts",
                 * "readCustomer".
                 *
                 * ---------------------------------------------------------
                 */

                plusCartSum ( price, upward = true ) {
                    const sum = parseFloat ( price ) * ( upward ?  1
                                                                : -1 );
                    this.$data.cartSum = Math.round ( ( this.$data.cartSum + sum ) * 100 ) / 100;
                },

                minusCartSum ( price ) {
                    this.plusCartSum ( price, false );
                },

                readProducts ( nextReading = false ) {
                    if ( this.$data.vendorJSON ) {
                        axios.get  ( this.$data.vendorJSON )
                             .then (
                                 ( res ) => {
                                     if ( typeof res.data == 'object' ) {
                                         this.$data.shopItems = res.data;
                                         if ( nextReading ) {
                                             nextReading ( );
                                         }
                                     }
                                 }
                             );
                    }
                },

                readCustomer ( nextReading = false ) {
                    if ( this.$data.customerJSON ) {
                        axios.get  ( this.$data.customerJSON )
                             .then (
                                 ( res ) => {
                                     if ( typeof res.data == 'object' ) {
                                         this.$data.customer = res.data;
                                         if ( nextReading ) {
                                             nextReading ( );
                                         }
                                     }
                                 }
                             );
                    }
                }
            }
        };
    </script>
