generic.checkout = {};

/**
 * generic.checkout.cart 
 * - depends on: generic.cookie, generic.jsonrpc
 */ 
generic.checkout.cart = ( function() {

    return {
        setCookie: false, 
    
        order: new Hash(),
        payments: new Array(),
        carts: new Hash(), 
        items: new Array(),
        samples: new Array(),
     
        totalShoppedItems: 0, 
        totalItems: 0,
     
        transactionParams: {
    	transactionFields: {
        			"trans_fields" : ["TRANS_ID", "payments"]
    		},
    	paymentFields: {
        			"payment_fields" : ["address", "PAYMENT_TYPE", "PAYMENT_AMOUNT", "TRANS_PAYMENT_ID"]
    		},
    	orderFields: {
        			"order_fields" : ["items", "samples", "address", "TRANS_ORDER_ID"]
    		}
        },
	
        itemTypes: { 
        	"cart" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "cart"
        	},
        	"giftcard" : {
        		"id": "CART_GIFTCARD_ID",
        		"_SUBMIT" : "giftcard"
        	},
        	"collection" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "collection.items"
        	},
        	"kit" : {
        		"id": "COLLECTION_ID",
        		"_SUBMIT" : "alter_collection"
        	},
        	"replenishment" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "alter_replenishment"
        	},
        	"favorites" : {  
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "alter_collection"
        	}
        },

        initialize: function(args) { 
        	Object.extend(this, args); // copy args to obj
        },
    
        getCartTotals: function() {
    	var cookie = generic.cookie("cart");
    	if (cookie && cookie!==null) {
    	   // console.log("generic.cart.getCartTotals cookie: "+Object.toJSON(cookie)); 
    	   Object.extend(this, cookie);
	   
    	   generic.events.fire({event:'cart:countsUpdated'});
    	} else {
    	   // console.log("generic.cart.getCartTotals !cookie");  
    	   this.getCart();
    	}  
        },
    
        setCookie: function() { 
        	// console.log("generic.cart.setCookie "+this.totalItems);
        	var s  = {
        		totalItems: this.totalItems 
        	}
        	s = Object.toJSON(s);
        	generic.cookie("cart",s, {path:"/"}); 
        },
    
        getCart: function(args) {
            //console.log("generic.cart.getCart");
            var self = this; 

            if (args != null && args.pageDataKey) {
                var pageData = generic.page_data(args.pageDataKey);
                if (pageData.get("rpcdata")) {
                    // console.log( "cart page data found!" );
                    self._updateCartData(pageData.get("rpcdata"));
                    return;
                }
            }

            var params = {};
            params = Object.extend ( params, self.transactionParams.transactionFields );
            params = Object.extend ( params, self.transactionParams.paymentFields);
            params = Object.extend ( params, self.transactionParams.orderFields);
        
             var id = generic.jsonrpc.fetch({
                method : 'trans.get',
                params: [params],
                onSuccess:function(jsonRpcResponse) {
                    self._updateCartData(jsonRpcResponse.getValue()); 
                },
                onFailure: function(jsonRpcResponse){
                	//jsonRpcResponse.getError();
                	console.log('Transaction JSON failed to load');
                }
            });
            return id;
        },
   
         //sets up internal representation of cart state
        // Assuming one order per transaction
        _updateCartData: function(data){ 
            // console.log("generic.checkout.cart._updateCartData");
            var self = this;
            this.data = data;
            this.totalItems = data.items_count; 
            this.defaultCartId = data.default_cart_id;
            this.payments = (data.trans && data.trans.payments) ? $A(data.trans.payments) : null;  
            this.order = data.order; 
         
            // contents and sample_contents mirror the sku by qty hashes
            this.order.contents = new Hash();
            this.order.sample_contents = new Hash();

            if (this.order.items != null) {
                this.order.items = this.order.items.reject(function(item){ // filter out nulls
                    return item === null;
                });
            }
        
            var items = this.order.items || null;
            var totalShoppedItems = 0;
            if (items != null) {  
                items.each(function(item){   
                    if (!item) { return; }
                    totalShoppedItems+=item.ITEM_QUANTITY;
                
                    // set up contents by cart hashes 
                    var cartID = item.CART_ID;
                    var cart = self.carts.get(cartID);
                    if (!cart) {
                        self.carts.set(cartID, new Hash()); 
                        cart = self.carts.get(cartID); 
                        cart.set('contents', new Hash());
                    } 
                    var id = item['sku.SKU_BASE_ID'] ? item['sku.SKU_BASE_ID'] : item.COLLECTION_ID; 
                    cart.get('contents').set(id, item.ITEM_QUANTITY);
                
                    // compute per-unit tax (replace this with field from JSONRPC result when available)
                    var unitTax = item.APPLIED_TAX/item.ITEM_QUANTITY;
                    item.UNIT_TAX = unitTax;

                    // set up order contents hash (spans carts)
                    if (item.itemType.toLowerCase() == 'skuitem') {
                        var key = item['sku.SKU_BASE_ID'];
                        var qty = item.ITEM_QUANTITY; 
                        //error self.order.contents.set(key, qty);
                        self.order.contents[key] = qty; 
                    } else if (item.itemType.toLowerCase() == 'kititem') {
                        var key = item.COLLECTION_ID;
                        var qty = item.ITEM_QUANTITY;
                        self.order.contents.set(key,qty);
                    } else {
                        // FUTURE: other cart item types (e.g. kits)
                    } 
                
                });
            }
        
            this.totalShoppedItems = totalShoppedItems;
        
            var samples = this.order.samples;
            if (samples != null) {
                samples.each(function(item){
                    // set up contents by cart hashes
                    var cartID = item.CART_ID;
                    var cart = self.carts.get(cartID);
                 
                    if (!cart) {
                        self.carts.set(cartID, new Hash());
                        cart = self.carts.get(cartID);
                        cart.set('contents', new Hash());
                    } 
               
                    var id = item['sku.SKU_BASE_ID'] ? item['sku.SKU_BASE_ID'] : item.COLLECTION_ID; 
                    cart.get('contents').set(id, item.ITEM_QUANTITY);

                    // set up order contents hash (spans carts)
                    if (item.itemType.toLowerCase() == 'sampleitem') {
                        var key = item['sku.SKU_BASE_ID'];
                        var qty = item.ITEM_QUANTITY;
                        self.order.sample_contents.set(key,qty); 
                    } else {
                        // other item types (are likely errors)
                    } 
                });
            }
        
            // if (self.setCookie) self.setCookie();        
            generic.events.fire({event:'cart:countsUpdated'});
            // generic.events.fire({event:'cart:updated'}); 
        },
   
        /* args is a hash
        required keys: args.params.skus array, either args.params.INCREMENT or args.QTY with args.INCREMENT overriding args.QTY
        optional keys: args.itemType, args.OFFER_CODE, args.CART_ID*/ 
        updateCart: function(args){
            // console.log("cart.updateCart: "+Object.toJSON(args.params));
            if (!args.params) return null; 
            var self = this;   
            var onSuccess = args.onSuccess || Prototype.emptyFunction;  
            var onFailure = args.onFailure || Prototype.emptyFunction; 
            var itemType = args.params.itemType || "cart"; //e.g. cart, collection, giftcard etc
    	    var id = self.itemTypes[itemType].id;
            var method = 'rpc.form';
         
            var params = {
                '_SUBMIT': self.itemTypes[itemType]["_SUBMIT"] 
            };  
            if (typeof args.params.CAT_BASE_ID != "undefined"){
                params["CAT_BASE_ID"] = args.params.CAT_BASE_ID;   
            }else{
                console.log("MISSING CAT_BASE_ID");
            } 
            //id
            if (id == 'SKU_BASE_ID') {
                params[id] = (args.params.skus.length == 1) ? args.params.skus[0] 
                           : (args.params.skus.length > 1)  ? args.params.skus // accounts for EL US implementation of virtual skus ported from Mica
                           :                                  args.params.collectionId
                           ;
            } else if (id == 'COLLECTION_ID') {
                params[id] = args.params.collectionId;
            }

            //qty   
            if (args.params.INCREMENT && args.params.INCREMENT>=0) {   
               //currently +1 will be added regardless of INCREMENT's actual value
               //backend requires QTY property to exist but it will not be used
         	 params["INCREMENT"] = args.params.INCREMENT; 
         	 params["QTY"] = 1; 
            } else if (args.params.INCREMENT && args.params.INCREMENT<0) {
            	//decrements qty by -1
            } else if (args.params.QTY && args.params.QTY>=0) { 
            	params["QTY"] = args.params.QTY;  
            }
                     
            //offer code
            if (args.params.OFFER_CODE && args.params.OFFER_CODE.length>0) {
                params['OFFER_CODE'] = args.params.OFFER_CODE;
            }
            
            //favorites
            if (args.params.action && args.params.action.length > 0) {
            	params['action'] = 'add';
            }
            
            //kit
            if (args.params.action && args.params.action == 'save') {
                params['action'] = 'save';
            }
            //replenishment
            if (args.params.REPLENISHMENT_FREQ && args.params.REPLENISHMENT_FREQ >= 0) {
                params['REPLENISHMENT_FREQ'] = args.params.REPLENISHMENT_FREQ;            
            }           
            if (args.params.add_to_cart && args.params.add_to_cart != 0) {
                params['add_to_cart'] = args.params.add_to_cart;
            }
            
            // targeting of the correct cart is still missing (and important to get right) 
            // cart id if we are adding to something other than the default cart
            if (args.params.cart_id && (args.params.cart_id != self.defaultCartId)) {
                params['CART_ID'] = args.params.cart_id;
            }
            
            //method
            if (args.params.method && args.params.method.length > 0 ) {
                method = args.params.method;
            }
 
            var id = generic.jsonrpc.fetch({
                "method" : method,
                "params" : [params],
                "onSuccess": function(jsonRpcResponse){
                    var data = jsonRpcResponse.getData();
                    var cartResultObj = jsonRpcResponse.getCartResults();
                    //load data
                    if (data && data["trans_data"]) { 
                        self._updateCartData(data["trans_data"]);
                    }
                    if (args.params.itemType == 'cart') {
	                    document.fire("cart:updated", cartResultObj);
	                };
	                if (args.params.itemType == 'favorites') {
	                	document.fire("favorites:updated", jsonRpcResponse);
	                };
	                if (args.params.itemType == 'kit') {
	                	document.fire("kit:updated", jsonRpcResponse);
	                };
	                if (args.params.itemType == 'replenishment') {
	                	document.fire("cart:updated", cartResultObj);
	                };
                    onSuccess(jsonRpcResponse);
                },
                "onFailure": function(jsonRpcResponse){
                    onFailure(jsonRpcResponse);
                }
            });
 
            return id;
        }, 
    
        getItemQty : function(baseSkuId) {  
            if (!this.order.items) return 0;
            var lineItem = this.order.items.find( function (line) {
                return line['sku.SKU_BASE_ID'] ==  baseSkuId;
              });  
            if (!lineItem) {
                return 0; 
            }                
            return lineItem.ITEM_QUANTITY;
        },
    
        getBaseSkuIds: function() {  //MK: what is this used for?
            //console.log("generic.cart.getBaseSkuIds: "+this.order.items);
            if (!this.order.items) return new Hash();
            var baseSkuIds = this.order.items.pluck( 'sku.SKU_BASE_ID' ); //MK what about giftcards/collections?  
            return baseSkuIds; 
        },  
    
        getSubtotal: function() {
            var lineItems = this.order.items;
            if (!this.order.items) return 0;
            var subtotal = 0;
            for (var i=0, len = lineItems.length; i<len; i++) {
                var lineItem = lineItems[i];
                subtotal += (lineItem.UNIT_PRICE + lineItem.UNIT_TAX) * lineItem.ITEM_QUANTITY;
            }
            return subtotal;
        },
     
        getTotalShoppedItems: function(){ //products and gift cards
           /** var ttl = 0;
            var items = this.order.items;
            if (items != null) {
                items.each(function(item){
                    if (item && item.ITEM_QUANTITY) {
                        ttl += item.ITEM_QUANTITY;
                    }
                });
            } 
            return ttl;**/
            return this.totalShoppedItems;
        },         
        
        getTotalSamples: function() {
             var ttl = 0;
             var samples = this.order.samples;
                if (samples != null) {
                    samples.each(function(item){
                        ttl += item.ITEM_QUANTITY;
                    });
            } 
            return ttl;
        }, 
    
        getTotalItems: function(){ 
           // return this.getTotalShoppedItems() + this.getTotalSamples();
           return this.totalItems;
         }    
     };
}() ) ;

