/**
    Если пользователь авторизован, корзина будет сохраняться в базу данных в профиль пользователя,
    если пользователь неавторизован, пишем корзину в куку.
    
    put
    putMany
    remove
*/

var Bag = Object.create(Object.Extendable).extend({
    storageType: 'cookie', // or 'database'
    name: 'bag', // переменная для cookie
    items: [], // собствннно данные
    total: 0,
    qty: 0,
    
    /**
        Инициализация корзины.
        Заполяем Bag.items из базы данных, либо из cookie в зависимости от того авторизован ли пользователь 
    */
    init: function () {
/*
        // проверим авторизацию пользователя
        $.ajax({
            type: "GET",
            url: "/order/ajax/check_authorization/",
            dataType: "json",
            success: function (authorized) {
                if (authorized) {
                    // если авторизован, берем содержимое корзины из базы
                    Bag.storageType = 'database';
                } else {
                    // если не авторизован - из куков
                    Bag.storageType = 'cookie';
                }
                Bag.getBagItemsFromStorage();
            }
        });

*/
        Bag.getBagItemsFromStorage();
    },
        
    /**
        Добавляем элемент в корзину. 
        Если нужно добавить item без синхронизации с хранилищем, делаем doUpdateStorage = false
    */
    put: function (item, doUpdateStorage) {        
        // Пробуем привести пришедший item в валидный вид,
        // если привести не удалось, останавливаем добавление
        item = Bag.testItem(item);
        if (! item) {
            return false;
        }
        
        // Смотрим, есть ли уже такой item в нашей корзине,
        // если есть - вызываем метод обновления item'a - updateItem
        var itemExists = false;
        $.each(Bag.items, function (i, bagItem) {
            if (parseInt(bagItem.id, 10) === parseInt(item.id, 10)) {
                Bag.updateItem(bagItem, item);
                itemExists = true;
                return false;
            }
        });        
        // если пришел новый элемент, добавляем его в корзину
        if (! itemExists) {
            Bag.items.push(item); 
        }
        
        // Пересчитываем показатели и обновляем html
        Bag.updateTotal();
        Bag.updateHtml();
        
        // Теперь нужно записать изменения в выбранное при инициализации корзины хранилище.
        // Записывать, правда, будем не всегда: если метод вызван с параметро doUpdateStorage = false, 
        // значит вызывающая сторона хочет напулять сразу много item'ов в корзину и только потом сделать 
        // синхронизацию с хранилищем (например, так делает метод putMany)
        doUpdateStorage = (typeof doUpdateStorage === 'undefined') ? true : doUpdateStorage;
        if (doUpdateStorage) {
            Bag.updateStorage();
        }
        
        if (item.type === 'service') {
            Bag.updateHtml_orderpage();
        }
    },
    
    /**
        Кладем кучку элементов в корзину
    */
    putMany: function (items) {
        // Идем по каждому элементу пришедшего массива и вызываем для него метод put()
        // вторым аргументом которому передаем false, чтобы выполнить только одно обращение к хранилищу
        $.each(items, function (i, item) {
            Bag.put(item, false);
        });
        
        // Пересчитываем показатели и обновляем html
        Bag.updateTotal();
        Bag.updateHtml();
        
        // В конце сихранизируемся с хранилищем
        Bag.updateStorage();
    },
    
    /**
        Удаляем элемент из корзины по id.
    */
    remove: function (id) {
        $.each(Bag.items, function (i, bagItem) {
            if (parseInt(bagItem.id, 10) === parseInt(id, 10)) { 
                Bag.items.splice(i, 1);
                return false;
            }
        });
        
        // Пересчитываем показатели и обновляем html
        Bag.updateTotal();
        Bag.updateHtml();
        
        Bag.updateHtml_orderpage();
        
        // В конце сихранизируемся с хранилищем 
        Bag.updateStorage();
    },
    
    /**
        Проверка item'a на валидность
        Возвращает вадилдный item
    */
    testItem: function (item) {
        // Для начала проверим наличие обзятельных полей
        var requiredFields = ['id', 'qty', 'price', 'type'],
            requiredFieldsValid = true;
        $.each(requiredFields, function (n, field) {
            if (typeof item[field] === 'undefined') {
                requiredFieldsValid = false;
            }
        });
        // eсли нет всех обязательных полей, item не прошел проверку
        if (! requiredFieldsValid) {
            return false;
        }
        
        // Проверим поле "количество", оно должно быть числом и лежать в пределах от 0 до 1000
        if (! (/^-?\d+$/.test(item.qty)) || item.qty === null || item.qty < 1 || item.qty > 100000) {
            return false;
        }
        
        // Приводим данные к нужным типам, заодно отбросим все лишнее        
        var validItem = {
            qty:    parseInt(item.qty, 10),
            id:     parseInt(item.id, 10),
            price:  parseFloat(item.price),
            type:   item.type
        };
        
        return validItem;
    },
    
    /**
        Проверка на валидность всех item'ов корзины
    */
    testItems: function (items) {
        var validItems = [];
        $.each(items, function (i, item) {
            var validItem = Bag.testItem(item);
            if (validItem) {
                validItems.push(validItem);
            }
        });
        return validItems;
    },
    
    /**
        Этот метод вызываетсся при попытке добавить элемент, который уже есть в корзине.
    */
    updateItem: function (bagItem, item) {
        // увеличиваем количество товара в корзине
        bagItem.qty += item.qty;
    },
    
    /**
        Берем содержимое корзины из хранилища.
        Хранилищем может быть как cookie так и поле в модели профайла пользователя.
        Тип хранилища определяется в методе init()
    */
    getBagItemsFromStorage: function () {        
        if (Bag.storageType === 'cookie') {
        
            if (Cookie.get(Bag.name)) {
                cookie = JSON.parse(Cookie.get(Bag.name));
                // Данные в cookie могут быть плохие, поэтому обязательно вызываем функцию приведения к нормальному виду!!!!!!!
                Bag.items = Bag.testItems(cookie);
            }
            Bag.updateTotal();
            Bag.updateHtml();
        } else if (Bag.storageType === 'database') {
            $.ajax({
                type:       "GET",
                url:        "/order/ajax/get_bag/",
                dataType:   "json",
                success:    function (items) {
                    if (items) {
                        Bag.items = items;
                    }
                    Bag.updateTotal();
                    Bag.updateHtml();
                }
            });
            
        }
    },
    
    updateStorage: function () {
        if (Bag.storageType === 'cookie') {
            
            Cookie.set(Bag.name, JSON.stringify(Bag.items), null, '/');
            
            //console.log(Cookie.get(Bag.name));
            
        } else if (Bag.storageType === 'database') {
        
            $.ajax({
                type: "POST",
                data: {items : JSON.stringify(Bag.items)},
                url: "/order/ajax/update_bag/",
                dataType: "json",
                error: function () {
                    // вот здесь явно нужно что-то сделать
                }
            });
            
        }
    },
        

    
    /**
        Пересчитываем общее количество товаров и сумму покупок.
    */
    updateTotal: function () {
        Bag.total = 0;
        Bag.qty = 0;
        $.each(Bag.items, function (i, item) {
            Bag.total += item.qty * item.price;
            Bag.qty += item.qty;
        });
    },
    
    /**
        После каждого updateTotal обновляем html
        (например, состояние корзины в углу экрана)
    */
    updateHtml: function () {
        var $basket = $('#basket'),
            $total_qty = $('#total_qty'),
            $total = $('#total_money');
        if (Bag.qty) {
            $basket.show();
            $total_qty.html('{qty} {qty_word}'.supplant({qty: Bag.qty, qty_word: Meta.decline(Bag.qty, "товаров", "товар", "товара", "товаров")}));
            $total.html(Meta.beautyPrice(Bag.total) + ' руб.')
        } else {
            $basket.hide();
        }
    },
    
    /**
        Меняем количество на странице оформления заказа
    */
    append_orderpage: function(item, $html) {
        // кладем на странице оформления заказа
        var Bag = this,
            flag = true,
            cost = 0;
        if (Bag.testItem(item)) {
            // если нам ввели правильное число, ищем наш айтем
            $.each(Bag.items, function(i, ival){
                // если находим, проставляем ему новый qty
                if(ival.id === item.id) {
                    ival.qty = item.qty;
                    flag = false;
                    cost = item.qty * item.price;
                }
            });
            if (flag){
                // если не находим, добавляем новый айтем
                Bag.items.push(item);
                cost = item.qty * item.price;
            }
        } else {
            // если нам ввели лажу, удаляем из корзины наш айтем
            $.each(Bag.items, function(i, ival){
                if(ival.id === item.id) { 
                    Bag.items.splice(i,1);
                    cost = 0;
                    return false;
                }
            });
        }
        Bag.updateTotal();
        Bag.updateHtml();
        // В конце сихранизируемся с хранилищем 
        Bag.updateStorage();
        
        Bag.updateHtml_orderpage();
        $html.html(Meta.beautyPrice(cost));
        return true;
    },
    updateHtml_orderpage: function () {
        $('#bagTotalOrderPage').html(Meta.beautyPrice(Bag.total));
    }
});

$(document).ready(function(){
    var t;

    // запускаем корзину
    Bag.init();
    
    $('.buy').click(function (e) {
        e.preventDefault();
        var $el = $(this),
            $appendPlace = $el.parents('.item').find('span');
        Bag.put({
            id:     $el.attr('item_id'),
            qty:    1,
            price:  parseFloat($el.attr('item_price')),
            type:   'product'
        });

        // Ванины попупы
        clearTimeout(t);
        $('.basket_add').remove();
        $('<div class="basket_add"><img src="/static/i/basket_check.gif" alt=""><h3>Товар добавлен</h3><a href="/order/">Оформить заказ</a></div>')
        .appendTo($appendPlace)
        .fadeIn('fast')
        .mouseleave(function(){
            clearTimeout(t);
            t = setTimeout(function(){
                $('.basket_add').fadeOut();
            },1500);
        }).mouseenter(function(){
            clearTimeout(t);
        });
        ;
        t = setTimeout(function(){
            $('.basket_add').fadeOut();
        },1500);

    });
    
    $('.bagDelete').live('click', function(){
        var $aim = $(this).parents('.bagItem'),
            id = parseInt($aim.find('.bagId').text());
        Bag.remove(id);
        $aim.fadeOut(function(){
            $(this).remove();
        });
        return false;
    });
    
    $('.order_bagQty').keyup(function(){
        var $aim = $(this).parents('.bagItem'),
            item = {
                'id': parseInt($aim.find('.bagId').text()),
                'qty': parseInt($(this).val()),
                'price': parseFloat($aim.find('.bagPrice').text()),
                'type': 'product'
            },
            $html = $aim.find('.bagCost');
        if(! Bag.testItem(item) ) {
            $aim.addClass('disable');
        } else {
            $aim.removeClass('disable');
        }
        Bag.append_orderpage(item, $html);
        return true;
    });
    
    
    // добавляем дополнительные услуги
    $(".bagServiceAdd").click(function(){
        var $aim = $(this).parents('tr'),
            item = {
                'id': parseInt($aim.find('.bagId').text()),
                'title': $aim.find('.bagTitle').text(),
                'qty': 1,
                'price': parseInt($aim.find('.bagPrice').text()),
                'type':   'service',
            };
        $aim.remove();
        Bag.put(item);        
        $('.bagItems .bagItem:last').after('<tr class="bagItem"><td>{title}</a></td><td class="tar"></td><td class="tar"><input type="hidden" name="service_ids[]" value="{id}" /></td><td class="tar"><span class="bagCost">{price}</span></td><td><a href="javascript:void(0)" class="del bagDelete"><span class="jsValues" style="display:none;"><span class="bagId">{id}</span><span class="bagPrice">{price}</span></span></a></td></tr>'.supplant(item));
                
        if ($('#servicesToAdd tr').length === 1) {
            $('#servicesToAdd').remove();
        }
    });
    
});
