(function (context, $) {

  "use strict";

  context.JK = context.JK || {};

  // TODO: MUCH OF THIS CLASS IS REPEATED IN THE FOLLOWING FILES:
  // createSession.js.erb
  // accounts_profiles.js

  context.JK.BandSetupScreen = function (app) {
    var NONE_SPECIFIED = 'None specified'
    var GENRE_STEP  = 1
    var SAMPLE_STEP = 3
    var STEPS_COUNT = 5
    var currentStep = 0
    var ui = new context.JK.UIHelper(JK.app)
    var logger = context.JK.logger
    var profileUtils = context.JK.ProfileUtils
    var rest = context.JK.Rest()
    var inviteMusiciansUtil = null
    var invitationDialog = null
    var autoComplete = null
    var userNames = []
    var userIds = []
    var userPhotoUrls = []
    var selectedFriendIds = {}
    var nilOptionStr = '<option value=""></option>'
    var nilOptionText = 'n/a'
    var bandId = ''
    var friendInput=null
    var bandType=null
    var bandStatus=null
    var concertCount=null


    var $screen=$("#band-setup")
    var $samples = $screen.find(".account-profile-samples")
    var $selectedInstruments=[]

    var accountProfileSamples = new JK.AccountProfileSamples(app, $screen, loadBandCallback, rest.updateBand)
    accountProfileSamples.initialize()

    function navBack() {
      var band = buildBand()
      if (currentStep>0) {
        saveBand(band, function() {
          currentStep--
          renderCurrentPage()
        })
      }
    }

    function navCancel() {
      resetForm()
      window.history.go(-1)
      return false
    }

    function navNext() {
      var band = buildBand()
      if (currentStep==GENRE_STEP) {
        band.genres = getSelectedGenres();
        band.validate_genres = true
      } else {
        band.validate_genres = false
      }

      if (currentStep<STEPS_COUNT-1) {
        saveBand(band, function(band) {
          currentStep++
          renderCurrentPage()
        })
      } else {
        saveBand(band, function(band) {
          resetForm()
          showProfile(band.id);
        })
      }
    }

    function renderCurrentPage() {
      $screen.find($(".band-step")).addClass("hidden")
      $("#band-setup-step-" + currentStep).removeClass("hidden")
      if(currentStep==0) {
        $("#btn-band-setup-back").addClass("hidden")
        $("#btn-band-setup-next").removeClass("hidden").html("SAVE & NEXT")
      } else if(currentStep<STEPS_COUNT-1) {
        // if(currentStep==SAMPLE_STEP) {
        //   accountProfileSamples.renderPlayer(band)
        // }
        $("#btn-band-setup-back").removeClass("hidden")
        $("#btn-band-setup-next").removeClass("hidden").html("SAVE & NEXT")
      } else {
        $("#btn-band-setup-back").removeClass("hidden")
        $("#btn-band-setup-next").removeClass("hidden").html("SAVE & FINISH")
      }
      renderOptionalControls()
    }

    function renderOptionalControls(e) {
      if(e){e.stopPropagation()}

      // Is new member selected?
      if ($screen.find($('input[name="add_new_members"]:checked')).val()=="yes") {
        $screen.find($(".new-member-dependent")).removeClass("hidden")
      } else {
        $screen.find($(".new-member-dependent")).addClass("hidden")
      }

      // Is paid gigs selected?
      if ($('input[name="paid_gigs"]:checked').val()=="yes") {
        $screen.find($(".paid-gigs-dependent")).removeClass("hidden")
      } else {
        $screen.find($(".paid-gigs-dependent")).addClass("hidden")
      }
      return false;
    }

    function isNewBand() {
      return bandId==null || typeof(bandId)=='undefined' || bandId.length == 0;
    }

    function removeErrors() {
      $('#band-setup-form .error-text').remove()
      $('#band-setup-form .error').removeClass("error")

    }

    function resetForm() {

      removeErrors();
      accountProfileSamples.resetForm()

      // name
      $("#band-name").val('');

      // country
      $("#band-country").empty();
      $("#band-country").val('');

      // region
      $("#band-region").empty();
      $("#band-region").val('');

      // city
      $("#band-city").empty();
      $("#band-city").val('');

      // description
      $("#band-biography").val('');

      // website
      $('#band-website').val('');

      $("#new-member-no").iCheck('check').attr('checked', 'checked')
      $("#paid-gigs-no").iCheck('check').attr('checked', 'checked')
      $("#free-gigs-no").iCheck('check').attr('checked', 'checked')
      $('#touring-option').val('no')


      $("#play-commitment").val('1')
      $screen.find("#hourly-rate").val("0")
      $screen.find("#gig-minimum").val("0")
      resetGenres();
      renderDesiredExperienceLabel([])

      $(friendInput)
        .unbind('blur')
        .attr("placeholder", "Looking up friends...")
        .prop('disabled', true)
    }

    function resetGenres() {
      $('input[type=checkbox]:checked', '#band-genres').each(function (i) {
        $(this).removeAttr("checked");
      });

      var $tdGenres = $("#tdBandGenres");
    }

    function getSelectedGenres() {
      var genres = [];
      $('input[type=checkbox]:checked', '#band-genres').each(function (i) {
        var genre = $(this).val();
        genres.push(genre);
      });

      return genres;
    }

    function validateGeneralInfo() {
      removeErrors();

      var band = buildBand();
      return rest.validateBand(band);
    }

    function renderErrors(errors) {
      logger.debug("Band setup errors: ", errors)
      var name        = context.JK.format_errors("name", errors);
      var country     = context.JK.format_errors("country", errors);
      var state       = context.JK.format_errors("state", errors);
      var city        = context.JK.format_errors("city", errors);
      var biography   = context.JK.format_errors("biography", errors);
      var website     = context.JK.format_errors("website", errors);
      var genres      = context.JK.format_errors("genres", errors);

      if(name)      $("#band-name").closest('div.field').addClass('error').end().after(name);
      if(country)   $("#band-country").closest('div.field').addClass('error').end().after(country);
      if(state)     $("#band-region").closest('div.field').addClass('error').end().after(state);
      if(city)      $("#band-city").closest('div.field').addClass('error').end().after(city);
      if(biography) $("#band-biography").closest('div.field').addClass('error').end().after(biography);
      if(website)   $("#band-website").closest('div.field').addClass('error').end().after(website);
      if(genres)    $("#band-genres").closest('div.field').addClass('error').end().after(genres);
    }

    function buildBand() {
      var band = {instruments:[]};
      band.id = (isNewBand()) ? null : bandId;
      band.name = $("#band-name").val();
      band.website = $("#band-website").val();
      band.biography = $("#band-biography").val();
      band.city = $("#band-city").val();
      band.state = $("#band-region").val();
      band.country = $("#band-country").val();

      band.band_type = bandType.val();
      band.band_status= bandStatus.val();
      band.concert_count= concertCount.val();

      band.add_new_members = $('input[name="add_new_members"]:checked').val()=="yes"
      band.paid_gigs = $('input[name="paid_gigs"]:checked').val()=="yes"
      band.free_gigs=$('input[name="free_gigs"]:checked').val()=="yes"
      band.touring_option=$('#touring-option').val()=="yes"


      if ($screen.find("#play-commitment").length == 0) {
        logger.error("MISSING PLAY COMMITMENT")
      }

      band.play_commitment = $screen.find("#play-commitment").val()
      band.hourly_rate = profileUtils.normalizeMoneyForSubmit($screen.find("#hourly-rate").val())
      band.gig_minimum = profileUtils.normalizeMoneyForSubmit($("#gig-minimum").val())

      $.each($selectedInstruments, function(index, instrument) {
        var h = {}
        h.instrument_id = instrument.id
        h.proficiency_level = instrument.level
        band.instruments.push(h)
      })

      if(!isNewBand()) {
        mergePerformanceSamples(band)
      }

      return band;
    }

    function mergePerformanceSamples(band) {
      // Collect and merge data from this sub-widget:
      var performanceSampleData = accountProfileSamples.buildPlayer()
      band.website=performanceSampleData.website
      band.online_presences=performanceSampleData.online_presences
      band.performance_samples=performanceSampleData.performance_samples

      // Change player id to that of band.  Widget currently hardwires current user id:
      if(band.online_presences) {
        for (var i=0; i<band.online_presences.length; ++i) {
          band.online_presences[i].player_id = band.id
        }
      }

      // Change player id to that of band.  Widget currently hardwires current user id:
      if(band.performance_samples) {
        for (var i=0; i<band.performance_samples.length; ++i) {
          band.performance_samples[i].player_id = band.id
        }
      }

      return band
    }

    function renderDesiredExperienceLabel(selectedInstruments) {
      $selectedInstruments=selectedInstruments
      var instrumentText=""
      $.each($selectedInstruments, function(index, instrument) {
        if (instrumentText.length!=0) {instrumentText += ", "}
        instrumentText += instrument.name
      })

      $("#desired-experience-label").html(($selectedInstruments && $selectedInstruments.length > 0) ? instrumentText : NONE_SPECIFIED)
    }

    function showProfile(band_id) {
      context.location = "/client#/bandProfile/" + band_id;
    }

    function saveInvitations(response) {
      if (0 < $('#selected-friends-band .invitation').length) {
        createBandInvitations(response.id, function () {
          showProfile(response.id);
        });
      }
    }

    function saveBand(band, saveBandSuccessFn) {

      unbindNavButtons()
      removeErrors()      

      var saveBandFn = (isNewBand()) ? rest.createBand : rest.updateBand
      saveBandFn(band)
        .done(function (response) {
          bandId = response.id
          saveInvitations(response)
          if(saveBandSuccessFn) {
            saveBandSuccessFn(band)
          }
        })
        .fail(function (jqXHR) {
          if(jqXHR.status == 422) {
            renderErrors(JSON.parse(jqXHR.responseText))
          } else {
            app.notifyServerError(jqXHR, "Unable to create band")
          }
        })
        .always(function (jqXHR) {
          bindNavButtons()
        })
    }

    function createBandInvitations(bandId, onComplete) {
      var callCount = 0;
      var totalInvitations = 0;
      $('#selected-friends-band .invitation').each(function (index, invitation) {
        callCount++;
        totalInvitations++;
        var userId = $(invitation).attr('user-id');
        rest.createBandInvitation(bandId, userId)
          .done(function (response) {
            callCount--;
          }).fail(app.ajaxError);
      });

      function checker() {
        if (callCount === 0) {
          onComplete();
        } else {
          context.setTimeout(checker, 10);
        }
      }

      checker();
      return totalInvitations;
    }

    function beforeShow(data) {
      inviteMusiciansUtil.clearSelections();
      bandId = data.id == 'new' ? '' : data.id;
      currentStep=0
      if (data['d']) {
        var stepNum = data['d'].substring(4)
        if(stepNum) {
          currentStep=stepNum
          delete data['d'];
        }
      }
      resetForm();
    }

    function afterShow(data) {
      inviteMusiciansUtil.loadFriends();

      if (!isNewBand()) {
        $("#band-change-photo").html('Upload band photo.');
        $('.band-photo').removeClass("hidden")

        // retrieve and initialize band profile data points
        loadBandDetails();
      } else {
        loadGenres();

        // Load geo settings:
        rest.getResolvedLocation().done(function (location) {
          loadCountries(location.country, function () {
            loadRegions(location.region, function () {
              loadCities(location.city);
            });
          });
        });

        $('.band-photo').addClass("hidden")
      }
      renderCurrentPage()
    }

    function loadDesiredExperience() {

    }


    function loadBandDetails() {
      rest.getBand(bandId).done(function (band) {
        $("#band-name").val(band.name);
        $("#band-website").val(band.website);
        $("#band-biography").val(band.biography);

        bandType.val(band.band_type)
        bandStatus.val(band.band_status)
        concertCount.val(band.concert_count)

        if (band.add_new_members){
          $("#new-member-no").iCheck('check').attr('checked', 'checked')
        } else {
          $("#new-member-yes").iCheck('check').attr('checked', 'checked')
        }

        if (band.paid_gigs) {
          $("#paid-gigs-no").iCheck('check').attr('checked', 'checked')
        } else {
          $("#paid-gigs-yes").iCheck('check').attr('checked', 'checked')
        }

        if (band.free_gigs) {
          $("#free-gigs-no").iCheck('check').attr('checked', 'checked')
        } else {
          $("#free-gigs-yes").iCheck('check').attr('checked', 'checked')
        }

        $('#touring-option').val(band.touring_option ? 'yes' : 'no')
        $("#play-commitment").val(band.play_commitment)
        $("#hourly-rate").val(profileUtils.normalizeMoneyForDisplay(band.hourly_rate))
        $("#gig-minimum").val(profileUtils.normalizeMoneyForDisplay(band.gig_minimum))

        // Initialize avatar
        if (band.photo_url) {
          $("#band-avatar").attr('src', band.photo_url);
        }

        loadGenres(band.genres);

        loadCountries(band.country, function () {
          loadRegions(band.state, function () {
            loadCities(band.city);
          });
        });

        renderOptionalControls();

        $.each(band.instruments, function(index, instrument) {
          var h = {}
          h.id = instrument.instrument_id
          h.level = instrument.proficiency_level
          h.approve = true
          $selectedInstruments.push(h)
        })

        renderDesiredExperienceLabel($selectedInstruments)

        accountProfileSamples.renderPlayer(band)

      });
    }

    function loadGenres(selectedGenres) {
      $("#band-genres").empty();

      rest.getGenres().done(function (genres) {
        $.each(genres, function (index, genre) {
          var genreTemplate = $('#template-band-setup-genres').html();
          var selected = '';

          if (selectedGenres) {
            var genreMatch = $.grep(selectedGenres, function (n, i) {
              return n.id === genre.id;
            });

            if (genreMatch.length > 0) {
              selected = "checked";
            }
          }
          var genreHtml = context.JK.fillTemplate(genreTemplate, {
            id: genre.id,
            description: genre.description,
            checked: selected
          });

          $('#band-genres').append(genreHtml);
        });
      });
    }

    function loadCountries(initialCountry, onCountriesLoaded) {
      var countrySelect = $("#band-country");

      var nilOption = $(nilOptionStr);
      nilOption.text(nilOptionText);
        countrySelect.append(nilOption);

      rest.getCountries().done(function (response) {
        $.each(response["countriesx"], function (index, countryx) {
          if (!countryx.countrycode) return;
          var option = $(nilOptionStr);
          option.text(countryx.countryname);
          option.attr("value", countryx.countrycode);

          if (initialCountry === countryx.countrycode) {
            option.attr("selected", "selected");
          }

            countrySelect.append(option);
        });

        context.JK.dropdown(countrySelect);

        if (onCountriesLoaded) {
          onCountriesLoaded();
        }
      });
    }

    function loadRegions(initialRegion, onRegionsLoaded) {
      var $region = $("#band-region");
      var selectedCountry = $("#band-country").val();

      $region.empty();
      var nilOption = $(nilOptionStr);
      nilOption.text(nilOptionText);
      $region.append(nilOption);

      if (selectedCountry) {
        rest.getRegions({'country': selectedCountry}).done(function (response) {

          $region.empty();
          var nilOption = $(nilOptionStr);
          nilOption.text(nilOptionText);
          $region.append(nilOption);

          $.each(response["regions"], function (index, region) {
            if (!region) return;
            var option = $(nilOptionStr);
            option.text(region['name']);
            option.attr("value", region['region']);

            if (initialRegion === region['region']) {
              option.attr("selected", "selected");
            }

            $region.append(option);
          });

          context.JK.dropdown($region);
          if (onRegionsLoaded) {
            onRegionsLoaded();
          }
        }).error(function(err) {
          context.JK.dropdown($region);
          if (onRegionsLoaded) {
            onRegionsLoaded();
          }
        });
      }
    }

    function loadCities(initialCity) {
      var $city = $("#band-city");
      $city.empty();
      var selectedCountry = $("#band-country").val();
      var selectedRegion = $("#band-region").val();

      var nilOption = $(nilOptionStr);
      nilOption.text(nilOptionText);
      $city.append(nilOption);
      nilOption.attr('selected','selected');

      if (selectedCountry && selectedRegion) {
        rest.getCities({'country': selectedCountry, 'region': selectedRegion}).done(function (response) {
          $.each(response["cities"], function (index, city) {
            if (!city) return;
            var option = $(nilOptionStr);
            option.text(city);
            option.attr("value", city);

            if (initialCity === city) {
              option.attr("selected", "selected");
            }

            $city.append(option);
          });

          context.JK.dropdown($city);
        }).error(function(err) {
            context.JK.dropdown($city);
        });
      } else {
        context.JK.dropdown($city);
      }
    }

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

    function navigateToBandPhoto(evt) {
        evt.stopPropagation();
        context.location = '/client#/band/setup/photo/' + bandId;
        return false;
    }

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

    function bindNavButtons() {
      $('#btn-band-setup-back').on("click", function (e) {
        e.stopPropagation()
        navBack()
        return false
      })

      $('#btn-band-setup-cancel').on("click", function (e) {
        e.stopPropagation()
        navCancel()
        return false
      })

      $('#btn-band-setup-next').on("click", function (e) {
        e.stopPropagation()
        navNext()
        return false
      })

      $('#btn-band-setup-back').removeClass("disabled")
      $('#btn-band-setup-cancel').removeClass("disabled")
      $('#btn-band-setup-next').removeClass("disabled")
    }

    function unbindNavButtons() {
      $('#btn-band-setup-back').off("click")
      $('#btn-band-setup-cancel').off("click")
      $('#btn-band-setup-next').off("click")
      $('#btn-band-setup-back').addClass("disabled")
      $('#btn-band-setup-cancel').addClass("disabled")
      $('#btn-band-setup-next').addClass("disabled")
    }

    function events() {
      $('#selected-band-invitees').on("click", ".invitation a", removeInvitation);

      bindNavButtons();

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

      $('#band-country').on('change', function (evt) {
        evt.stopPropagation();
        loadRegions();
        loadCities();
        return false;
      });

      $('#band-region').on('change', function (evt) {
        evt.stopPropagation();
        loadCities();
        return false;
      });

      $('#band-change-photo').click(navigateToBandPhoto);
      $('#band-setup .band-avatar-profile').click(navigateToBandPhoto);

      $('div[layout-id="band/setup"] .btn-email-invitation').click(function () {
        invitationDialog.showEmailDialog();
      });

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

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

      $('a#choose-desired-experience').on("click", chooseExperience)

      $('#band-setup').on('ifToggled', 'input[type="radio"].dependent-master', renderOptionalControls);

      $(friendInput).focus(function() { $(this).val(''); })
    }

    function chooseExperience(e) {
      e.stopPropagation()
      ui.launchInstrumentSelectorDialog("new member(s)", $selectedInstruments, function(selectedInstruments) {
        $selectedInstruments = selectedInstruments
        renderDesiredExperienceLabel($selectedInstruments)
        return false
      })
      return false
    }

    function loadBandCallback() {
      return (isNewBand()) ? {} : rest.getBand(bandId)
    }

    function initialize(invitationDialogInstance, friendSelectorDialog) {
      inviteMusiciansUtil = new JK.InviteMusiciansUtil(app)
      inviteMusiciansUtil.initialize(friendSelectorDialog)

      friendInput = inviteMusiciansUtil.inviteBandCreate('#band-setup-invite-musicians', "<div class='left w70'>If your bandmates are already on JamKazam, start typing their names in the box below, or click the Choose Friends button to select them.</div>")
      invitationDialog = invitationDialogInstance
      events()

      var screenBindings = {
        'beforeShow': beforeShow,
        'afterShow': afterShow
      }

      bandType=$("#band-type")
      bandStatus=$("#band-status")
      concertCount=$("#concert-count")

      app.bindScreen('band/setup', screenBindings)

      $screen.find('input[type=radio]').iCheck({
        checkboxClass: 'icheckbox_minimal',
        radioClass: 'iradio_minimal',
        inheritClass: true
      })

      profileUtils.initializeHelpBubbles()
    }

    this.initialize = initialize;
    this.afterShow = afterShow;
    return this;
  };
})(window, jQuery);