(function (context, $) {

  "use strict";

  context.JK = context.JK || {};
  context.JK.FindSessionScreen = function(app) {
    var CATEGORY = {
      ACTIVE: {index: 0, id: "table#sessions-active"},
      SCHEDULED: {index: 1, id: "table#sessions-scheduled"}
    };

    var $screen = null;
    var $dateFilter = $("#session-date-filter");
    var $sessionLanguageFilter = $('#session-language-filter');

    var logger = context.JK.logger;
    var rest = context.JK.Rest();
    var sessionList;

    var ACTIVE_SESSIONS_LIMIT = 50;
    var SCHEDULED_SESSIONS_LIMIT = 20;

    var currentActiveSessionsQuery = defaultActiveSessionsQuery();

    var $btnRefresh = null;
    var $asSpinner = null;
    var $ssNext = null;
    var $ssScroller = null;
    var $ssSpinner = null;
    var $noActiveSessionsMsgSelector = $('#no-active-sessions');
    var $noScheduledSessionsMsgSelector = $('#no-scheduled-sessions');
    var currentScheduledSessionsPage = 0;
    var currentScheduledSessionsQuery = defaultScheduledSessionsQuery();

    function getCategoryEnum() {
      return CATEGORY;
    }

    function search() {
      logger.debug("Searching for sessions...");
      clearResults();
      buildActiveSessionsQuery();
      buildScheduledSessionsQuery();
      loadSessions();
    }

    function loadSessions() {
      if($btnRefresh.is('disabled')) {
        return;
      }

      $btnRefresh.addClass('disabled')
      $asSpinner.show();
      $ssSpinner.show();
      $noActiveSessionsMsgSelector.hide();
      $noScheduledSessionsMsgSelector.hide();

      var doneCount = 0;

      // get active sessions
      rest.findActiveSessions(currentActiveSessionsQuery)
        .done(function(sessions) {
          renderActiveSessions(sessions);
        })
        .fail(function(xhr, textStatus, errorMessage) {
          if (xhr.status === 404) {
            logger.warn("unable to list active sessions (404) " + + JSON.stringify(xhr.responseText))
            // swallow 404
          }
          else {
            logger.warn("unable to list active sessions: " + JSON.stringify(xhr.responseText))
            app.ajaxError(xhr, textStatus, errorMessage);
          }
        })
        .always(function() {
          context.JK.bindHoverEvents();
          $asSpinner.hide();
          doneCount += 1;
          if(doneCount == 2) {
            $btnRefresh.removeClass('disabled')
          }
        });

      // get scheduled sessions
      rest.findInactiveSessions(currentScheduledSessionsQuery)
        .done(function(sessions) {
          renderScheduledSessions(sessions);
        })
        .fail(function(xhr, textStatus, errorMessage) {
          if (xhr.status === 404) {
            // swallow 404
          }
          else {
            app.ajaxError(xhr, textStatus, errorMessage);
          }
          logger.warn("unable to list scheduled sessions: " + JSON.stringify(xhr.responseText))
        })
        .always(function() {
          $ssSpinner.hide();
          doneCount += 1;
          if(doneCount == 2) {
            $btnRefresh.removeClass('disabled')
          }
        });

      // context.JK.bindInstrumentHover($(CATEGORY.ACTIVE.id));
      // context.JK.bindInstrumentHover($(CATEGORY.SCHEDULED.id));
    }

    /***************** ACTIVE SESSIONS *****************/
    function defaultActiveSessionsQuery() {
      return {offset:0, limit:SCHEDULED_SESSIONS_LIMIT, page:0};
    }

    function renderActiveSessions(sessions) {
      $.each(sessions.sessions, function(i, session) {
        sessionList.renderActiveSession(session, $(CATEGORY.ACTIVE.id), sessions.my_audio_latency);
      });

      afterLoadActiveSessions(sessions.sessions);
    }

    function buildActiveSessionsQuery() {
      currentActiveSessionsQuery = defaultActiveSessionsQuery();

      // genre filter
      var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#find-session-genre');
      if (genres !== null && genres.length > 0) {
        currentActiveSessionsQuery.genre = genres.join(',');
      }

      // date filter
      var date = $('#session-date-filter').val();
      if (date !== null && date.length > 0) {
        currentActiveSessionsQuery.day = context.JK.formatDateYYYYMMDD(date);
        currentActiveSessionsQuery.timezone_offset = (new Date().getTimezoneOffset()) / 60;
      }

      // language filter
      var language = $sessionLanguageFilter.val();
      if (language !== null && language.length > 0) {
        currentActiveSessionsQuery.lang = language;
      }

      // keyword filter
      var keyword = $('#session-keyword-srch').val();
      if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') {
        currentActiveSessionsQuery.keyword = $('#session-keyword-srch').val();
      }

      // always set client ID (required on server)
      currentActiveSessionsQuery.client_id = context.JK.clientId;

      console.log("currentActiveSessionsQuery = %o", currentActiveSessionsQuery);

      return currentActiveSessionsQuery;
    }

    function afterLoadActiveSessions(sessionList) {      
      if (sessionList.length === 0) {
        $noActiveSessionsMsgSelector.show();
      }
      else {
        $noActiveSessionsMsgSelector.hide();
      }

      buildActiveSessionsQuery();

      context.JK.GA.trackFindSessions(sessionList.length);
    }


    /***************** SCHEDULED SESSIONS *****************/
    function defaultScheduledSessionsQuery() {
      return {offset:currentScheduledSessionsPage * SCHEDULED_SESSIONS_LIMIT, limit:SCHEDULED_SESSIONS_LIMIT, page:currentScheduledSessionsPage};
    }

    function renderScheduledSessions(sessions) {
      $.each(sessions.sessions, function(i, session) {
        sessionList.renderInactiveSession(session, $(CATEGORY.SCHEDULED.id), undefined, sessions.my_audio_latency);
      });
      
      context.JK.bindHoverEvents();
      afterLoadScheduledSessions(sessions.sessions);
    }

    function buildScheduledSessionsQuery() {
      currentScheduledSessionsQuery = defaultScheduledSessionsQuery();

      // genre filter
      var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#find-session-genre');
      if (genres !== null && genres.length > 0) {
        currentScheduledSessionsQuery.genre = genres.join(',');
      }

      // date filter
      var date = $('#session-date-filter').val();
      if (date !== null && date.length > 0) {
        currentScheduledSessionsQuery.day = context.JK.formatDateYYYYMMDD(date);
        currentScheduledSessionsQuery.timezone_offset = (new Date().getTimezoneOffset()) / 60;
      }

      // language filter
      var language = $sessionLanguageFilter.val();
      if (language !== null && language.length > 0) {
        currentScheduledSessionsQuery.lang = language;
      }

      // keyword filter
      var keyword = $('#session-keyword-srch').val();
      if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') {
        currentScheduledSessionsQuery.keyword = $('#session-keyword-srch').val();
      }

      // always set client ID (required on server)
      currentScheduledSessionsQuery.client_id = context.JK.clientId;

      console.log("currentScheduledSessionsQuery = %o", currentScheduledSessionsQuery);

      return currentScheduledSessionsQuery;
    }

    function afterLoadScheduledSessions(sessionList) {

      if(sessionList.length < SCHEDULED_SESSIONS_LIMIT) {
        // if we retrieve less results than asked for, end searching
        $ssScroller.infinitescroll('pause');
        $noScheduledSessionsMsgSelector.show();
        $('.infinite-scroll-loader').remove();
      }
      else {
        $noScheduledSessionsMsgSelector.hide();
        currentScheduledSessionsPage++;
        buildScheduledSessionsQuery();
        registerScheduledSessionInfiniteScroll();
      }

      context.JK.GA.trackFindSessions(sessionList.length);
    }

    function registerScheduledSessionInfiniteScroll() {
      $ssScroller.infinitescroll({
        behavior: 'local',
        navSelector: '#sessions-scheduled .btn-next-wrapper',
        nextSelector: '#sessions-scheduled .btn-next',
        binder: $ssScroller,
        dataType: 'json',
        appendCallback: false,
        debug: true,
        prefill: false,
        bufferPx:100,
        loading: {
          msg: $('<div class="infinite-scroll-loader">Loading ...</div>'),
          img: '/assets/shared/spinner.gif'
        },
        path: function(page) {
          return '/api/sessions/inactive?' + $.param(buildScheduledSessionsQuery());
        }
      },function(json, opts) {
        renderScheduledSessions(json);
      });
    }

    function beforeShow(data) {
      context.JK.GenreSelectorHelper.render('#find-session-genre', 'Any Genre');
    }

    function afterShow(data) {
      if(!context.JK.JamServer.connected) {
        app.notifyAlert("Not Connected", 'To create or join a session, you must be connected to the server.');
        window.location = '/client#/home'
        return;
      }

      clearResults();
      buildActiveSessionsQuery();
      buildScheduledSessionsQuery();
      loadSessions();
    }

    function clearResults() {
      $('table#sessions-active').find("tr:gt(0)").remove();

      currentScheduledSessionsPage = 0;
      $ssScroller.infinitescroll('resume');
      $('table#sessions-scheduled').find("tr:gt(0)").remove();

      $('#no-active-sessions').hide();
      // $('#no-scheduled-sessions').hide();
    }

    function events() {

      $('#session-keyword-srch').focus(function () {
        $(this).val('');
      });

      $("#session-keyword-srch").keypress(function (evt) {
        if (evt.which === 13) {
          evt.preventDefault();
          search();
        }
      });

      $btnRefresh.on("click", search);
    }

    function initialize() {

      var screenBindings = {
        'beforeShow': beforeShow,
        'afterShow': afterShow
      };
      app.bindScreen('findSession', screenBindings);

      sessionList = new context.JK.SessionList(app);

      $screen = $('#findSession');
      $ssNext = $screen.find('#sessions-scheduled .btn-next')
      $ssScroller = $screen.find('.content-body-scroller');
      $ssSpinner = $screen.find('#sessions-scheduled .paginate-wait');

      $asSpinner = $screen.find('#sessions-active .paginate-wait');
      $btnRefresh = $('#btn-refresh')

      $dateFilter.datepicker({
          dateFormat: "D d MM yy",
          onSelect: toggleDate
        }
      );

      context.JK.dropdown($sessionLanguageFilter);

      events();
    }

    function toggleDate() {
      var selectedDate = new Date($dateFilter.val());
      var currentDate = new Date();
      var startIndex = 0;

      if (currentDate.getYear() == selectedDate.getYear() &&
          currentDate.getMonth() == selectedDate.getMonth() &&
          currentDate.getDate() == selectedDate.getDate()) {

        var timeString = getFormattedTime(currentDate, true);
        startIndex = defaultTimeArray.indexOf(timeString);
      }
    }

    this.initialize = initialize;
    this.afterShow = afterShow;
    this.clearResults = clearResults;
    this.getCategoryEnum = getCategoryEnum;

    return this;
  };

})(window, jQuery);