var ChooseBox = {

    config: {
        successRedirect: null,
        defaultChoices: null
    },

    lang: {
        noDaysSelected: 'no days selected', //#Lang
        noPrice: '&nbsp;n/a', //#Lang
        noType: 'n/a', //#Lang
        promocodeNotFound: 'sorry, we couldn\'t find that code'//#Lang
    },

    boxType: null,

    scrolled: false,

    daysInput: null,
    daysHasUserChanges: false,
    
    nutritionPlan: null,
    nutritionPlanWizard: null,

    submitButton: null,
    promotionCodeInput: null,

    initialise: function(config)
    {
        Object.extend(this.config, config || {});

        // Set up promotion code
        this.promotionCodeInput = $('chooseBoxPrice').down('input');

        if (this.promotionCodeInput) {
            this.promotionCodeInput.observe('focus', function(){
                this.promotionCodeInput.setValue('');
            }.bind(this));

            this.promotionCodeInput.observe('blur', function(){
                this.submitPromocode();
            }.bind(this));

            this.promotionCodeInput.observe('keypress', function(e){
                if (e.keyCode == 13) {
                    this.promotionCodeInput.blur();
                }
            }.bind(this));
        }

        // Set up box choices radio buttons
        $$('.chooseBoxTypeOption').each(function(boxTypeOption){
            var type = boxTypeOption.readAttribute('id') == 'chooseBoxTypeNibble' ? 'nibble' : 'nutrition';

            var hoverElements = boxTypeOption.select('.chooseBoxFader');
            
            boxTypeOption.select('.chooseBoxTypeLink').each(function(element){
                element.observe('click', function(e){
                    e.stop();

                    // If we're already on nutrition and it's clicked again,
                    // launch modal
                    if (type == 'nutrition' && this.boxType == 'nutrition') {
                        this.showNutritionPlanModal();
                    }

                    this.selectBoxType(type);

                    if (!this.config.defaultChoices && (type == 'nibble' || this.nutritionPlan)) {
                        // Scroll on click so it still works if preselected
                        // as default
                        this.scrollToDays();
                    }
                }.bind(this));

                element.setStyle({cursor: 'pointer'});

                // If a nutrition plan has never been chosen, light up the
                // text on hover
                element.observe('mouseover', function(){
                    if (type != this.boxType && ! this.nutritionPlan) {
                        hoverElements.each(function(anotherElement){
                            anotherElement.setOpacity(0.8);
                        });
                    }
                }.bind(this));
                element.observe('mouseout', function(){
                    if (type != this.boxType && ! this.nutritionPlan) {
                        hoverElements.each(function(anotherElement){
                            anotherElement.setOpacity(0.3);
                        });
                    }
                }.bind(this));
            }.bind(this));

            boxTypeOption.down('input').observe('focus', function(){
                boxTypeOption.down('input').blur();
            });
        }.bind(this));

        // Set up the week day checkboxes
        this.daysInput = new CheckBoxGroup($('chooseBoxDays'), {
            onChange: function() {
                this.daysHasUserChanges = true;
                
                this.updateSummaryDays();
                this.updateDisablers();
            }.bind(this)
        });

        this.submitButton = $('chooseBoxButtons').down('input.submit');
        this.submitButton.observe('click', function(e){
            e.stop();
            this.submit();
        }.bind(this));

        $('chooseBoxNutritionSelection').down('a').observe('click', function(e){
            e.stop();
            this.showNutritionPlanModal();
        }.bind(this));

        if (this.config.defaultChoices) {
            this.setAll(this.config.defaultChoices);
        }
        else {
            this.selectBoxType('nibble');
            this.updateSummaryDays();
        }

        var pageLoc = new String(document.location);
        if (pageLoc.endsWith('#days')) {
            this.scrollToDays(true);
        }
    },

    selectBoxType: function(type)
    {
        if (this.boxType == type) {
            return;
        }
        
        this.boxType = type;
        
        var selectElement = type == 'nibble' ? $('chooseBoxTypeNibble') : $('chooseBoxTypeNutrition');
        var deselectElement = type == 'nibble' ? $('chooseBoxTypeNutrition') : $('chooseBoxTypeNibble');

        selectElement.select('.chooseBoxFader').each(function(fadeElement){
            fadeElement.setOpacity(1);
        });
        selectElement.down('.radioButton').setOpacity(1);
        selectElement.down('.radioButton').addClassName('checked');
        selectElement.down('.chooseBoxTypeButton').addClassName('chooseBoxTypeButtonSelected');

        deselectElement.select('.chooseBoxFader').each(function(fadeElement){
            fadeElement.setOpacity(0.3);
        });
        deselectElement.down('.radioButton').setOpacity(0.5);
        deselectElement.down('.radioButton').removeClassName('checked');
        deselectElement.down('.chooseBoxTypeButton').removeClassName('chooseBoxTypeButtonSelected');

        this.updateDefaultDays();
        this.updateSummaryPrice();
        this.updateDisablers();
        this.updateNutritionPlanDisplay();

        if (type == 'nutrition' && ! this.nutritionPlan) {
            this.showNutritionPlanModal();
        }
        
        this.updateSummaryBoxType();
    },

    scrollToDays: function(ignoreViewport)
    {
        if (this.scrolled) {
            return;
        }
        
        this.scrolled = true;
        
        if (! ignoreViewport && $('chooseBoxDays').isWithinViewport()) {
            return;
        }

        Effect.ScrollTo($('chooseBoxDays'), {
            duration: 0.6,
            offset: -100
        });
    },

    setAll: function(data)
    {
        if (data.days) {
            data.days.each(function(day){
                this.daysInput.checkByValue(day);
            }.bind(this));
        }

        this.setNutritionPlan(data.nutritionPlan, true);
    },

    getBoxProfileById: function(id)
    {
        for (var boxProfileName in this.config.boxProfiles) {
            var boxProfile = this.config.boxProfiles[boxProfileName];
            if (boxProfile.id == id) {
                return boxProfile;
            }
        }
        return null;
    },

    getNutritionPlanById: function(id)
    {
        for (var nutritionPlanName in this.config.nutritionPlans) {
            var nutritionPlan = this.config.nutritionPlans[nutritionPlanName];
            if (nutritionPlan.id == id) {
                return nutritionPlan;
            }
        }
        return null;
    },

    getPromotionalPrices: function()
    {
        new AjaxRequest('/choosebox/ajaxpromotionalprices', {
            onSuccess: function(json){
                for (var boxProfileId in json.prices) {
                    var priceData = json.prices[boxProfileId];

                    var boxProfileInternalName = this.getBoxProfileById(boxProfileId).internalName;
                    this.config.boxProfiles[boxProfileInternalName].price = priceData.fullPrice;
                    this.config.boxProfiles[boxProfileInternalName].promotionalPriceStrings = priceData.promotionalPriceStrings;
                }
                
                this.updateSummaryPrice();
            }.bind(this)
        })
    },

    updateSummaryBoxType: function()
    {
        var element = $('chooseBoxSummaryType');

        var boxName = this.lang.noType;

        switch (this.boxType) {
            case 'nibble':
                boxName = this.config.boxProfiles.dry.nameStyled;
                break;

            case 'nutrition':
                if (this.nutritionPlan) {
                    boxName = this.getNutritionPlanById(this.nutritionPlan).nameStyledBox;
                }
                break;
        }

        element.update(boxName);
    },

    updateSummaryPrice: function()
    {
        var priceData = {};

        if (this.boxType) {
            var boxProfile = this.config.boxProfiles.dry;

            priceData = {
                fullPrice: boxProfile.price,
                promotionalPriceStrings: boxProfile.promotionalPriceStrings
            };
        }
        else {
            priceData = {fullPrice: -1};
        }

        var priceElement = $('chooseBoxSummaryPrice');
        
        if (priceData.fullPrice == -1) {
            priceElement.update(this.lang.noPrice);
            priceElement.addClassName('chooseDaysSummaryNone');
        }
        else {
            priceElement.update(priceData.fullPrice);
            priceElement.removeClassName('chooseDaysSummaryNone');
        }

        $('chooseBoxSummaryPromotion').update();
        if (priceData.promotionalPriceStrings && priceData.promotionalPriceStrings.length > 0) {
            priceData.promotionalPriceStrings.each(function(priceString){
                var priceStringElement = new Element('div').insert(priceString.priceString);

                if (priceString.showLimitedOffer) {
                    priceStringElement.insert($('limitedTimeOfferGraphic').innerHTML);
                }

                $('chooseBoxSummaryPromotion').insert(priceStringElement);
            }.bind(this));
            
            if (!$($('chooseBoxSummaryPromotion').parentNode).visible()) {
                new Effect.Appear($('chooseBoxSummaryPromotion').parentNode, {duration: 0.3});
            }
        }
        else if ($($('chooseBoxSummaryPromotion').parentNode).visible()) {
            new Effect.Fade($('chooseBoxSummaryPromotion').parentNode, {duration: 0.3});
        }
    },

    updateSummaryDays: function()
    {
        var days = this.daysInput.getChecked().sort();

        if (days.length == 0) {
            daysSummary = new Element('span', {'class':'chooseDaysSummaryNone'}).insert(this.lang.noDaysSelected);
        }
        else {
            var daysSummary = '';

            for (var i = 0; i < days.length; i++) {
                daysSummary += Utils.dayName(parseInt(days[i])).toLowerCase()+'s';
                if (i == (days.length - 2)) {
                    daysSummary += ' & ';
                }
                else if (i < (days.length - 2)) {
                    daysSummary += ', ';
                }
            }
            
            daysSummary = daysSummary.escapeHTML();
        }

        $('chooseBoxSummaryDays').update(daysSummary);
    },

    updateDefaultDays: function()
    {
        if (this.daysHasUserChanges) {
            return;
        }

        this.daysInput.uncheckAll(true);
        
        this.config.defaultDays.each(function(day){
            this.daysInput.checkByValue(day, true);
        }.bind(this));
        
        this.updateSummaryDays();
    },

    updateDisablers: function()
    {
        if (!this.boxType) {
            $('noBoxTypeFader').setOpacity(0.3);
        }
        else {
            $('noBoxTypeFader').setOpacity(1);

            if (this.daysInput.getChecked().length > 0) {
                $('chooseBoxButtons').setOpacity(1);
            }
            else {
                $('chooseBoxButtons').setOpacity(0.3);
            }
        }
    },

    updateNutritionPlanDisplay: function()
    {
        var element = $('chooseBoxNutritionSelection');

        if (! this.nutritionPlan) {
            element.hide();
            return;
        }

        element.show();

        element.down('span').update(this.getNutritionPlanById(this.nutritionPlan).nameStyled);
    },

    getRequestParams: function()
    {
        // Set up the submit url params
        var params = {
            boxProfile: this.config.boxProfiles.dry.id,
            days: this.daysInput.getValue(),
            nutritionPlan: this.boxType == 'nutrition' && this.nutritionPlan ? this.nutritionPlan : null
        };
        
        return params;
    },

    submit: function()
    {
        // Show a loader
        var loader = new Loader({elementToOverlay:this.submitButton});
        loader.show();

        // Set up the submit url params
        var params = this.getRequestParams();
        params.submitted = 1;

        new AjaxRequest(location.href, {
            parameters: params,
            onSuccess: function(json){
                if (json.valid) {
                    this.successRedirect();
                }
            }.bind(this),
            onFailure: function(){
                loader.hide();
            }.bind(this)
        });
    },

    /**
     * Redirect to the next page based on a successful Choose Box page submission
     */
    successRedirect: function()
    {
        if (this.config.successRedirect) {
            document.location = this.config.successRedirect;
        }
    },

    enterPromocode: function()
    {
        Promocode.config.onSuccessClose = function(){
            this.promocodeSuccess(Promocode.promotionName);
        }.bind(this);

        Promocode.enterCode();
    },

    promocodeSuccess: function(promotionName)
    {
        $$('.chooseBoxPromotionName').each(function(element){
            element.update(promotionName.escapeHTML());
        });

        $$('.chooseBoxEnterPromocode').each(function(element){
            element.hide();
        });

        $$('.chooseBoxPromocodeEntered').each(function(element){
            element.show();
        });

        this.getPromotionalPrices();
    },

    showNutritionPlanModal: function()
    {
        if (this.nutritionPlanWizard && this.nutritionPlanWizard.modal.isOpen()) {
            return;
        }
        
        this.nutritionPlanWizard = new Wizard({
            requestUrl: '/choosebox/nutrition-plan',
            basicRequestParameters: {
                npid: this.nutritionPlan
            },
            modalOptions: {
                width: 420
            }
        });

        GoogleAnalytics.track('signup/nutritionPlans');
    },

    setNutritionPlan: function(nutritionPlan, noScroll)
    {
        this.nutritionPlan = nutritionPlan;
        this.updateSummaryBoxType();
        this.updateNutritionPlanDisplay();

        if (nutritionPlan && nutritionPlan != this.config.nutritionPlans.none.id) {
            this.selectBoxType('nutrition');
        }
        else {
            this.selectBoxType('nibble');
        }

        if (! noScroll) {
            this.scrollToDays();
        }
    },

    submitPromocode: function()
    {
        if (! this.promotionCodeInput.getValue() || this.promotionCodeInput.getValue() == this.promotionCodeInput.defaultValue) {
            this.promotionCodeInput.setValue(this.promotionCodeInput.defaultValue);
            return;
        }

        var promotionCodeLoader = new Loader({elementToOverlay:$('chooseBoxPrice'),zIndex:1000});
        promotionCodeLoader.show();

        var onComplete = function(){
            promotionCodeLoader.hide();
        }

        var onSuccess = function(json){
            if (json.promocodeValid) {
                this.promocodeSuccess(json.promotionName);
            }
            else {
                $('chooseBoxPrice').down('.chooseBoxEnterPromocode span').update(this.lang.promocodeNotFound);
                $('chooseBoxPrice').down('.chooseBoxEnterPromocode img').show();
            }
        }.bind(this);

        Promocode.request(this.promotionCodeInput.getValue(), onComplete, onSuccess);
    }
};
