(function(context,$) {

    "use strict";

    context.JK = context.JK || {};
    context.JK.CreateSessionScreen = function(app) {
        var logger = context.JK.logger;
        var realtimeMessaging = context.JK.JamServer;
        var friendSelectorDialog = new context.JK.FriendSelectorDialog(app, friendSelectorCallback);
        var invitationDialog = new context.JK.InvitationDialog(app);
        var autoComplete = null;
        var userNames = [];
        var userIds = [];
        var userPhotoUrls = [];
        var MAX_GENRES = 1;
        var selectedFriendIds = {};
        var sessionSettings = {};

        function beforeShow(data) {
            userNames = [];
            userIds = [];
            userPhotoUrls = [];
            context.JK.GenreSelectorHelper.render('#create-session-genre');
            resetForm();
        }

        function afterShow(data) {
            $.ajax({
                type: "GET",
                url: "/api/users/" + context.JK.currentUserId + "/friends",
                async: false
            }).done(function(response) {
                $.each(response, function() {
                    userNames.push(this.name);
                    userIds.push(this.id);
                    userPhotoUrls.push(this.photo_url);
                });

                var autoCompleteOptions = {
                    lookup: { suggestions: userNames, data: userIds },
                    onSelect: addInvitation
                };
                if (!autoComplete) {
                    autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
                }
                else {
                    autoComplete.setOptions(autoCompleteOptions);
                }
            });

            // var autoCompleteOptions = {
            //     serviceUrl: "/api/users/" + context.JK.currentUserId + "/friends",
            //     minChars: 3,
            //     dataType: 'jsonp',
            //     transformResult: function(response) {
            //         logger.debug("transforming...");
            //         logger.debug("response.length=" + response.length);
            //         return {
            //             suggestions: $.map(response, function(dataItem) {
            //                 return { value: dataItem.id, data: dataItem.name };
            //             })
            //         };
            //     },
            //     onSelect: addInvitation
            // };

            // if (!autoComplete) {
            //     autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
            // }
            // else {
            //     logger.debug("here2");
            //     autoComplete.setOptions(autoCompleteOptions);
            // }
        }

        function friendSelectorCallback(newSelections) {
            var keys = Object.keys(newSelections);
            for (var i=0; i < keys.length; i++) {
                addInvitation(newSelections[keys[i]].userName, newSelections[keys[i]].userId);
            }
        }

        function addInvitation(value, data) {
            if ($('#selected-friends div[user-id=' + data + ']').length === 0) {
                var template = $('#template-added-invitation').html();
                var invitationHtml = context.JK.fillTemplate(template, {userId: data, userName: value});
                $('#selected-friends').append(invitationHtml);
                $('#friend-input').select();
                selectedFriendIds[data] = true;
            }
            else {
                $('#friend-input').select();
                context.alert('Invitation already exists for this musician.');
            }
        }

        function removeInvitation(evt) {
            delete selectedFriendIds[$(evt.currentTarget).parent().attr('user-id')];
            $(evt.currentTarget).closest('.invitation').remove();
        }

        function resetForm() {
            $('#intellectual-property').attr('checked', false);

            var $form = $('#create-session-form');
            var description = sessionSettings.hasOwnProperty('description') ? sessionSettings.description : '';
            $('textarea[name="description"]', $form).val(description);
            var genre = sessionSettings.hasOwnProperty('genres') && sessionSettings.genres.length > 0 ? sessionSettings.genres[0].id : '';
            context.JK.GenreSelectorHelper.reset('#create-session-genre', genre);

            var musician_access = sessionSettings.hasOwnProperty('musician_access') ? sessionSettings.musician_access : true;
            $('#musician-access option[value=' + musician_access + ']').attr('selected', 'selected');
            toggleMusicianAccess();

            if (musician_access) {
                var approval_required = sessionSettings.hasOwnProperty('approval_required') ? sessionSettings.approval_required : false;
                $('#musician-access-option-' + approval_required).attr('checked', 'checked');
            }

            var fan_access = sessionSettings.hasOwnProperty('fan_access') ? sessionSettings.fan_access : true;
            $('#fan-access option[value=' + fan_access + ']').attr('selected', 'selected');
            toggleFanAccess();

            if (fan_access) {
                var fan_chat = sessionSettings.hasOwnProperty('fan_chat') ? sessionSettings.fan_chat : false;
                $('#fan-chat-option-' + fan_chat).attr('checked', 'checked');
            }
            // Should easily be able to grab other items out of sessionSettings and put them into the appropriate ui elements.
        }

        function validateForm() {
            //var errors = [];
            var isValid = true;
            var $form = $('#create-session-form');

            // Description can't be empty
            var description = $('#description').val();
            if (!description) {
                $('#divDescription .error-text').remove();
                $('#divDescription').addClass("error");
                $('#description').after("<ul class='error-text'><li>Description is required</li></ul>");
                isValid = false;
            }
            else {
                $('#divDescription').removeClass("error");
            }

            var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre');

            if (genres.length === 0) {
                $('#divGenre .error-text').remove();
                $('#divGenre').addClass("error");
                $('#create-session-genre').after("<ul class='error-text'><li>You must select a genre.</li></ul>");
                isValid = false;
            }
            else {
                $('#divGenre').removeClass("error");
            }

            // if (genres.length > MAX_GENRES) {
            //     errors.push(['#genre-list', "No more than " + MAX_GENRES + "genres are allowed."]);
            // }

            var intellectualPropertyChecked = $('#intellectual-property').is(':checked');
            if (!intellectualPropertyChecked) {
                $('#divIntellectualProperty .error-text').remove();
                $('#divIntellectualProperty').addClass("error");
                $('#divTerms').after("<ul class='error-text'><li>You must accept the JamKazam Terms of Service.</li></ul>");
                isValid = false;
            }
            else {
                $('#divIntellectualProperty').removeClass("error");
            }

            return isValid;
        }

        function submitForm(evt) {
            evt.preventDefault();

            var isValid = validateForm();
            if (!isValid) {
                // app.notify({
                //     title: "Validation Errors",
                //     text: JSON.stringify(formErrors)
                // });
                return false;
            }

            var data = {};
            data.client_id = app.clientId;
            data.description = $('#description').val();
            data.as_musician = true;
            data.legal_terms = true; // this overrides the default of 'on', which isn't satisfying our concept of boolean
            data.intellectual_property = $('#intellectual-property').is(':checked');

            data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre');

            data.musician_access = $('#musician-access option:selected').val() === "true" ? true : false;
            data.approval_required = $("input[name='musician-access-option']:checked").val() === "true" ? true : false;

            data.fan_access = $('#fan-access option:selected').val() === "true" ? true : false;
            data.fan_chat = $("input[name='fan-chat-option']:checked").val() === "true" ? true : false;

            if ($('#band-list option:selected').val() !== '') {
                data.band = $('#band-list option:selected').val();
            }

            // 1. If no previous session data, a single stereo track with the
            //    top instrument in the user's profile.
            // 2. Otherwise, use the tracks from the last created session.
            // Defaulting to 1st instrument in profile always at the moment.
            data.tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);

            var jsonData = JSON.stringify(data);

            console.log("session data=" + jsonData);

            $('#btn-create-session').addClass('button-disabled');
            $('#btn-create-session').bind('click', false);

            var url = "/api/sessions";
            $.ajax({
                type: "POST",
                dataType: "json",
                contentType: 'application/json',
                url: url,
                processData:false,
                data: jsonData,
                success: function(response) {
                    var newSessionId = response.id;
                    var invitationCount = createInvitations(newSessionId, function() {
                        context.location = '#/session/' + newSessionId;
                    });
                    // Re-loading the session settings will cause the form to reset with the right stuff in it.
                    // This is an extra xhr call, but it keeps things to a single codepath
                    loadSessionSettings();
                    $('#btn-create-session').removeClass('button-disabled');
                    $('#btn-create-session').unbind('click', false);

                    context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);

                    context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
                },
                error: function() {
                    app.ajaxError(arguments);
                    $('#btn-create-session').removeClass('button-disabled');
                    $('#btn-create-session').unbind('click', false);
                }
            });
            return false;
        }

        function createInvitations(sessionId, onComplete) {
            var callCount = 0;
            var totalInvitations = 0;
            $('#selected-friends .invitation').each(function(index, invitation) {
                callCount++;
                totalInvitations++;
                var invite_id = $(invitation).attr('user-id');
                var invite = {
                    music_session: sessionId,
                    receiver: invite_id
                };
                $.ajax({
                    type: "POST",
                    url: "/api/invitations",
                    data: invite
                }).done(function(response) {
                    callCount--;
                }).fail(app.ajaxError);
            });
            // TODO - this is the second time I've used this pattern.
            // refactor to make a common utility for this.
            function checker() {
                if (callCount === 0) {
                    onComplete();
                } else {
                    context.setTimeout(checker, 10);
                }
            }
            checker();
            return totalInvitations;
        }

        function events() {
            $('#btn-create-session').on("click", submitForm);
            $('#selected-friends').on("click", ".invitation a", removeInvitation);
            $('#musician-access').change(toggleMusicianAccess);
            $('#fan-access').change(toggleFanAccess);

            $('#btn-choose-friends').click(function() {
                friendSelectorDialog.showDialog(selectedFriendIds);
            });

            $('.btn-email-invitation').click(function() {
                invitationDialog.showEmailDialog();
            });

            $('div[layout-id="createSession"] .btn-gmail-invitation').click(function() {
                invitationDialog.showGoogleDialog();
            });

            $('div[layout-id="createSession"] .btn-facebook-invitation').click(function() {
               invitationDialog.showFacebookDialog();
            });

            // friend input focus
            $('#friend-input').focus(function() {
                $(this).val('');
            });

            // friend input blur
            $('#friend-input').blur(function() {
                $(this).val('Type a friend\'s name');
            });
        }

        function toggleMusicianAccess() {
            var value = $("#musician-access option:selected").val();
            if (value == "false") {
                $("input[name='musician-access-option']").attr('disabled', 'disabled');
                $("input[name='musician-access-option']").parent().addClass("op50");
            }
            else {
                $("input[name='musician-access-option']").removeAttr('disabled');
                $("input[name='musician-access-option']").parent().removeClass("op50");
            }
        }

        function toggleFanAccess() {
            var value = $("#fan-access option:selected").val();
            if (value == "false") {
                $("input[name='fan-chat-option']").attr('disabled', 'disabled');
                $("input[name='fan-chat-option']").parent().addClass("op50");
            }
            else {
                $("input[name='fan-chat-option']").removeAttr('disabled');
                $("input[name='fan-chat-option']").parent().removeClass("op50");
            }
        }

        function loadBands() {
            var url = "/api/users/" + context.JK.currentUserId + "/bands";
            $.ajax({
                type: "GET",
                url: url,
                success: bandsLoaded
            });
        }

        function bandsLoaded(response) {
            $.each(response, function() {
                var template = $('#template-band-option').html();
                var bandOptionHtml = context.JK.fillTemplate(template, {value: this.id, label: this.name});
                $('#band-list').append(bandOptionHtml);
            });
        }

        function loadSessionSettings() {
            var url = "/api/users/" + context.JK.currentUserId + "/session_settings";
            $.ajax({
                type: "GET",
                url: url,
                success: sessionSettingsLoaded
            });
        }

        function sessionSettingsLoaded(response) {
            if (response != null)
            {
               sessionSettings = response;
            }
            resetForm();
        }

        function searchFriends(query) {
            if (query.length < 2) {
                $('#friend-search-results').empty();
                return;
            }
            var url = "/api/search?query=" + query + "&userId=" + context.JK.currentUserId;
            $.ajax({
                type: "GET",
                url: url,
                success: friendSearchComplete
            });
        }

        function friendSearchComplete(response) {
            // reset search results each time
            $('#friend-search-results').empty();

            // loop through each
            $.each(response.friends, function() {
                // only show friends who are musicians
                if (this.musician === true) {
                    var template = $('#template-friend-search-results').html();
                    var searchResultHtml = context.JK.fillTemplate(template, {userId: this.id, name: this.first_name + ' ' + this.last_name});
                    $('#friend-search-results').append(searchResultHtml);
                    $('#friend-search-results').attr('style', 'display:block');
                }
            });
        }

        function initialize() {
            friendSelectorDialog.initialize();
            invitationDialog.initialize();
            events();
            loadBands();
            loadSessionSettings();
            var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow };
            app.bindScreen('createSession', screenBindings);
        }

        // Expose publics
        this.initialize = initialize;
        this.resetForm = resetForm;
        this.submitForm = submitForm;
        this.validateForm = validateForm;
        this.loadBands = loadBands;
        this.searchFriends = searchFriends;
        this.addInvitation = addInvitation;

        return this;
    };

 })(window,jQuery);
