
(function(document, window, $, store) {
    //'use strict';

    function generateAllowTimes(hourOffset, minutes) {
        var times = [];
        for(var i=hourOffset; i < 24+hourOffset; i++) {
            var hour = i % 24;
            minutes.forEach(function(minute) {
                times.push((hour < 10 ? '0' : '') + hour + ':' + minute)
            });
        }
        return times;
    }

    function initDatepickerForDate($element) {
        $element.datetimepicker({
            timepicker: false,
            format: 'Y-m-d',
            formatDate: 'Y-m-d',
            disabledDates: $element.attr('data-picker-disabled').split(','),
            minDate: Math.max(new Date($element.attr('data-picker-min-date') || false), Date.now()),
            maxDate: $element.attr('data-picker-max-date') || false,
        });
    }

    function renderProduct($node, productIndex, values, onProductInputChange, onProductRemoveClick) {
        var $priceBox = $node.find('[data-price-box]');
        
        // Change inputs name
        $node
            .find('[data-product-input]')
            .each(function(_, element) {
                var name = element.getAttribute('name').replace('{n}', productIndex);
                element.setAttribute('name', name);
                element.setAttribute('id', name);
                element.value = values[element.getAttribute('data-field-name')] || '';
            })
            .on('change', function() {
                var $productSelect = $node.find('[data-product]');
                var product = $productSelect.length > 0 
                    ? Number($node.find('[data-product] :selected').attr('data-product_price')) 
                    : values._price;
                var quantity = Number($node.find('[data-quantity]').val());
                var total = (product && quantity) ? product * quantity : 0; 
                $priceBox
                    .text('$' + total)
                    .attr('data-value', total);
            });
        
        $node.find('[data-product-name]').text(values._name);
        $node.find('[data-product-img]').attr('src', values._img);
        
        $node.find('[data-picker-date]').each(function() {
            var $element = $(this);
            initDatepickerForDate($element);
        });
        $node.find('[data-picker-time]').datetimepicker({
            datepicker: false,
            format: 'H:i',
            allowTimes: generateAllowTimes(9, ['00', '15', '30', '45'])
        });

        $node
            .on('change', '[data-product-input]', onProductInputChange)
            .on('click', '[data-remove]', function(event) {
                event.preventDefault();
                $node.detach()
                onProductRemoveClick(event);
            })
            .find('[data-product-input]').change();

        return $node;
    }

    function addNewProduct(values, $templateNode, $listNode, onChange, onRemove) {
    	
        var $node = $templateNode.clone();
        renderProduct(
            $node, 
            $listNode.children().length, 
            values,
            onChange,
            onRemove
        );
        $listNode.append($node);
    }

    function initCartForm($formElement) {
        var $productTemplate = $formElement.find('[data-cart-product-template]').detach().children().clone();
        var $orderInputs = $formElement.find('[data-order-input]');
        var $productBlocks = $formElement.find('[data-cart-blocks]');
        var $addButton = $formElement.find('[data-cart-add]');
        var $addCatalogoButton = $formElement.find('[data-cart-catalogo]');
        var $totalPriceBox = $formElement.find('[data-total-price-box]');
        var cart = store.namespace('cart-' + $formElement.attr('data-suplemento-id'));
        var products = cart.get('products', [{}]); 
        var details = cart.get('details', {}); 

        // store cart metadata
        cart.set('metadata', {
            name: $formElement.attr('data-suplemento-name'),
            link: $formElement.attr('action')
        });

        function updateStore(totalPrice) {
            var products = [];
            $productBlocks.children().each(function(_, productElement) {
                var product = {};
                var $productElement = $(productElement);
                var $selectedProduct = $productElement.find('[data-product] :selected');
                
                $productElement
                    .find('[data-product-input]')
                    .each(function(_, inputElement) {
                        product[inputElement.getAttribute('data-field-name')] = inputElement.value;
                    });
                
                product._name = $selectedProduct.length > 0 ? $selectedProduct.attr('data-product_name') : product._name;
                product._price = $selectedProduct.length > 0 ? $selectedProduct.attr('data-product_price') : product._price;
                products.push(product);
            });
            cart.set('products', products);

            var details = {};
            $orderInputs.each(function(_, element) {
                details[element.getAttribute('data-field-name')] = element.value || '';
            });
            cart.set('products', products);
            cart.set('details', details);
            cart.set('total', totalPrice);
        }

        function updatePrice() {
            var price = 0;
            $productBlocks.find('[data-price-box]').each(function(_, element) {
                price += Number(element.getAttribute('data-value'));
            });
            $totalPriceBox.text('$' + price);
            updateStore(price);
            updateActiveCarts('[data-active-carts]', '[data-active-cart-block]');
        }

        $addButton.on('click', function(event) {
            event.preventDefault();
            addNewProduct(
                {}, 
                $productTemplate, 
                $productBlocks, 
                updatePrice, 
                updatePrice
            );
        });
        $addCatalogoButton.on('click', function(event) {
            event.preventDefault();
            window.location.href = $(this).attr('data-cart-catalogo');
        });

        $orderInputs
            .each(function(_, element) {
                var $element = $(element);
                element.value = details[element.getAttribute('data-field-name')] || '';
                if (element.hasAttribute('data-picker-date')) {
                    initDatepickerForDate($element);
                }
                if (element.hasAttribute('data-picker-time')) {
                    $element.datetimepicker({
                        datepicker: false,
                        format: 'H:i',
                        allowTimes: generateAllowTimes(9, ['00', '15', '30', '45'])
                    });
                }
            })
            .on('change', function(event) {
                updateStore();
            });
        
        if (products.length > 0) {
            products.map(function(product) {
                addNewProduct(
                    product, 
                    $productTemplate, 
                    $productBlocks, 
                    updatePrice, 
                    updatePrice
                );
            });
            updatePrice();
        } else {
            $addButton.click();
        }
    }

    function inArray(listOfValues, valueKey, value) {
        var result = listOfValues.find(function(item) {
            return item === value || item[valueKey] === value;
        });
        return result !== undefined; 
    }

    function bindAddToCartButtons(buttonSelector) {
        

        $(buttonSelector).on('click', function(event) {
            event.preventDefault();

            var cart = store.namespace('cart-' + this.getAttribute('data-suplemento-id'));
            var products = cart.get('products', []);
            var product = {
                id: this.getAttribute('data-product-id'),
                _name: this.getAttribute('data-product-name'),
                _price: this.getAttribute('data-product-price'),
                _img: this.getAttribute('data-product-img'),
                quantity: 1
            };
            if (!inArray(products, 'id', product.id)) {
                products.push(product);
            }

            cart.set('products', products);
            window.location.href = this.getAttribute('href');
        });
    }

    function updateActiveCarts(activeCartsSelector, activeCartIconSelector) {
        

        var $activeCarts = $(activeCartsSelector);
        var $activeCartIcon = $(activeCartIconSelector).children();
        
        $activeCarts.empty()
        
        store.each(function(item) {
            var products;
            var metadata;
            var total;
            var $node;


            if (item.match(/cart-[0-9]+.products/i)) {
                products = store.get(item);
                if (products.length > 0) {
                    metadata = store.get(item.replace('products', 'metadata'));
                    total = store.get(item.replace('products', 'total')) || 0;
                    if (metadata && metadata.name && metadata.link) {
                        $node = $activeCartIcon.clone();
                        $node.find('[data-suplemento-name]').text(metadata.name.substring(0, 8)+' ...');
                        $node.find('[data-suplemento-cart]').attr('href', metadata.link);
                        $node.find('[data-cart-products-quantity]').text(products.length);
                        $node.find('[data-cart-total]').text('$' + total);
                        $activeCarts.append($node);
                    }
                }
            }
        });
    }
	
	$(document).ready(function () {
        var cartForm = document.getElementById('cart-form');
        
        if (cartForm !== null) {
            $.datetimepicker.setLocale('es');
            initCartForm($(cartForm));
        }

        bindAddToCartButtons('[data-add-to-cart]');
        updateActiveCarts('[data-active-carts]', '[data-active-cart-block]');
	});
})(document, window, jQuery, store);
