(function (context, $) {

  "use strict";


  context.JK = context.JK || {};
  context.JK.AccountSessionDetail = function (app) {
    var EVENTS = context.JK.EVENTS;
    var logger = context.JK.logger;
    var rest = context.JK.Rest();
    var sessionUtils = context.JK.SessionUtils;
    var helpBubble = context.JK.HelpBubbleHelper;
    var ui = new context.JK.UIHelper(app);
    var sessionId = null;
    var sessionData = null;
    var rsvpData = null;
    var $screen = null;
    var $cancelRsvpBtn = null;
    var $inviteOthersBtn = null;
    var $sessionPageBtn = null;
    var $sessionDetail = null;
    var $shareUrl = null;
    var $spinner = null;
    var $templateOpenSlots = null;
    var $templateAccountPendingRsvp = null;
    var $templateAccountSessionDetail = null;
    var invitationDialog = null;
    var inviteMusiciansUtil = null;
    var friendInput=null;

    function beforeShow(data) {
      sessionId = data.id;
      loadSessionData();
    }

    function afterShow(data) {
    }

    function inviteMusicians(e) {
      e.preventDefault();

      friendInput = inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians', sessionId);
      inviteMusiciansUtil.loadFriends();
      $(friendInput).show();
      // invitationDialog.showEmailDialog();
    }

    function openSessionPage(e) {

      context.JK.popExternalLink('/sessions/' + sessionId + '/details')
      return false;
    }


    function buildRsvpRequestActionParams(request_id, action) {
      var params = {};
      params.session_id = sessionData.id;

      $.each(rsvpData, function(index, rsvp) {
        if (rsvp.id == request_id) {
          params.rsvp_responses = [];

          $.each(rsvp.rsvp_requests_rsvp_slots, function(index, rsvp_slot) {
            params.rsvp_responses.push({request_slot_id: rsvp_slot.id, accept: action});
          })
        }
      });

      return params;
    }

    function reset() {
      $sessionDetail.html("");
    }

    function refreshSessionDetail(response) {
      reset();
      loadSessionData();
    }

    function approveRsvpRequest(e) {
      e.preventDefault();

      var rsvpId = $(e.target).attr('request-id');
      var userName = $(e.target).attr('user-name');
      var instrumentIds = $(e.target).attr('data-instrument-text');
      var params = buildRsvpRequestActionParams(rsvpId, true);

      if (sessionData['is_unstructured_rsvp?']) {
        approve(rsvpId, params);
      }

      // check if any open slots exist for these instruments
      else {
        rest.getOpenSessionSlots(sessionData.id, true)
          .done(function(openSlots) {
            if (openSlots) {
              if (openSlots.length === 0) {
                ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
                    approve(rsvpId, params);
                }); 
              }
              else {
                var arrInstrumentIds = instrumentIds.split('|');
                var openSlotInstrumentIds = [];
                var unavailableSlotInstrumentIds = [];

                // ensure each instrument in the user's list is available in the open slots list
                $.each(openSlots, function(index, slot) {
                  openSlotInstrumentIds.push(slot.instrument_id);
                });

                // build list of instrument IDs in the RSVP request for which there are no open slots
                for (var i=0; i < arrInstrumentIds.length; i++) {
                  if ($.inArray(arrInstrumentIds[i], openSlotInstrumentIds) === -1) {
                    unavailableSlotInstrumentIds.push(arrInstrumentIds[i]);
                  }
                }

                if (unavailableSlotInstrumentIds.length > 0) {
                  ui.launchRsvpCreateSlotDialog(sessionData.id, unavailableSlotInstrumentIds, userName, function() {
                    approve(rsvpId, params);
                  });
                }
                else {
                  approve(rsvpId, params);
                }
              }
            }
            else {
              ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
                approve(rsvpId, params);
              });
            }
          });
      }
    }

    function approve(rsvpId, params) {
      rest.updateRsvpRequest(rsvpId, params)
        .done(refreshSessionDetail)
        .fail(function(jqXHR, textStatus, errorMessage) {
          if (jqXHR.status === 409) {
            app.notify(
              {
                title: "Unable to Approve RSVP",
                text: jqXHR.responseJSON.message
              });
          }
          else {
            app.ajaxError(jqXHR, textStatus, errorMessage);
          }
        });
    }

    function cancelRsvpRequest(e) {
      ui.launchRsvpCancelDialog(sessionData.id, rsvpData[0].id)
        .one(EVENTS.RSVP_CANCELED, function() {
          rest.getSessionHistory(sessionData.id)
            .done(function(response) {
              refreshSessionDetail();
            });
        })
        .one(EVENTS.DIALOG_CLOSED, function() {
          $(this).unbind(EVENTS.RSVP_CANCELED);
        });

      return false;
    }

    function declineRsvpRequest(e) {
      e.preventDefault();

      var rsvpId = $(e.target).attr('request-id');
      var params = buildRsvpRequestActionParams(rsvpId, false);

      rest.updateRsvpRequest(rsvpId, params)
        .done(refreshSessionDetail)
        .fail(app.ajaxError);
    }

    function events() {
      $inviteOthersBtn.on('click', inviteMusicians);
      $cancelRsvpBtn.on('click', cancelRsvpRequest);
      $sessionPageBtn.on('click', openSessionPage);
      $screen.find(".approveRsvpRequest").on('click', approveRsvpRequest);
      $screen.find(".declineRsvpRequest").on('click', declineRsvpRequest);
      $(friendInput).focus(function() { $(this).val(''); })

      $screen.find(".cancelSessionRsvp").on('click', function(e) {
        ui.launchRsvpCancelDialog(sessionData.id, $(this).attr('request-id'))
        .one(EVENTS.RSVP_CANCELED, function() {
          rest.getSessionHistory(sessionData.id)
            .done(function(response) {
              refreshSessionDetail();
            });
        })
        .one(EVENTS.DIALOG_CLOSED, function() {
          $(this).unbind(EVENTS.RSVP_CANCELED);
        });

        return false;
      });

      context.JK.bindHoverEvents();
      // context.JK.bindInstrumentHover($('#pendingRSVPs'));
      // context.JK.bindInstrumentHover($('#session-rsvps'));
      // context.JK.bindInstrumentHover($('#still-needed'));
    }

    function loadSessionData() {
      rest.getSessionHistory(sessionId, true)
        .done(function(response) {
          sessionData = response;

          rest.getRsvpRequests(sessionId)
            .done(function(rsvpResponse) {
              rsvpData = rsvpResponse;

              app.user()
                .done(function(userMe) {
                  renderSession(userMe);
                })
            })
            .fail(app.ajaxError);
        })
        .fail(app.ajaxError)
        .always(function() {
          $spinner.hide();
        });
    }

    function renderSession(userMe) {
      var hasPending = false;
      var isOwner = false;
      var isCancelled = false;

      // initialize to visible
      $inviteOthersBtn.show();
      $cancelRsvpBtn.show();

      if (sessionData.user_id == context.JK.currentUserId) {
        if (sessionData.pending_rsvp_requests.length > 0) {
          hasPending = true;
        }
        if (hasPending) {
          sessionData.notification_msg = "You have new RSVPs to review and approve, see details.";
        }
        else {
          sessionData.notification_msg = "";
        }

        isOwner = true;
      }
      else {
        $.each(sessionData.pending_rsvp_requests, function(index, request) {
          if (request.user_id == context.JK.currentUserId) {
            hasPending = true;
            sessionData.rsvpId = request.id;
          }
        });
        if (hasPending) {
          sessionData.notification_msg = "Your RSVP has not been processed by session organizer yet";
        }
        else {
          sessionData.notification_msg = "";
        }

        isOwner = false;
      }

      if (rsvpData && rsvpData.length > 0) {
        if (rsvpData[0].canceled) {
          isCancelled = true;
        }
      }

      sessionData.isOwner = isOwner;

      if (isOwner) {
        $inviteOthersBtn.show();
        $cancelRsvpBtn.hide();
      }
      else {
        $inviteOthersBtn.hide();
        $cancelRsvpBtn.show();
      }

      if (isCancelled) {
        $cancelRsvpBtn.hide();
      }

      $shareUrl.text(sessionData.share_url);

      var pendingRsvpHtml = "";
      if (isOwner) {
        pendingRsvpHtml = generatePendingRsvps();
      }
      var sessionRsvpsHtml = generateSessionRsvps();
      var sessionNeededHtml = generateSessionNeeded();
      var sessionInvitedHtml = generateSessionInvited();
      var sessionPropertiesHtml = generateSessionProperties();

      var $template = $(context._.template(
        $templateAccountSessionDetail.html(),
        { has_pending: hasPending, is_owner: isOwner, notification_msg: sessionData.notification_msg,
          pending_rsvps: pendingRsvpHtml, session_rsvps: sessionRsvpsHtml, still_needed: sessionNeededHtml,
          invited_users: sessionInvitedHtml, session_properties: sessionPropertiesHtml, id: sessionData.id},
        {variable: 'data'}
      ));

      var $offsetParent = $($sessionDetail).closest('.content-body');

      $.each($template.find('.latency'), function(index, latencyBadge) {
        var $latencyBadge = $(latencyBadge);
        var full_score = $latencyBadge.attr('data-full-score') || null;
        var internet_score = $latencyBadge.attr('data-internet-score') || null;
        var audio_latency = $latencyBadge.attr('data-audio-latency') || null;
        var latencyBadgeUserId = $latencyBadge.attr('data-user-id');
        var scoreOptions = {offsetParent: $offsetParent};
        helpBubble.scoreBreakdown($latencyBadge, context.JK.currentUserId == latencyBadgeUserId, full_score, userMe.last_jam_audio_latency, audio_latency, internet_score, scoreOptions);

      });

      $sessionDetail.html($template);

      events();
    }

    function generatePendingRsvps() {
      var resultHtml = "";
      var rsvpHtml = "";
      var instrumentLogoHtml = "";
      var latencyHtml = "";
      $.each(sessionData.pending_rsvp_requests, function(index, pending_rsvp_request) {
        if (pending_rsvp_request.user_id != context.JK.currentUserId) {
          var instrumentDesc = [];

          if ("instrument_list" in pending_rsvp_request && pending_rsvp_request.instrument_list != null) {
            $.each(pending_rsvp_request.instrument_list, function (index, instrument) {
              var instrumentId;

              if (instrument) {
                instrumentId = context.JK.getInstrumentId(instrument.id);
              }
              else {
                instrumentId = 'other';
              }
              var inst = context.JK.getInstrumentIcon24(instrumentId);
              instrumentLogoHtml += '<img title="' + instrumentId + '" hoveraction="instrument" data-instrument-id="' + instrumentId + '" src="' + inst + '" width="24" height="24" />&nbsp;';
              instrumentDesc.push(instrumentId);
            })
          }

          latencyHtml = context._.template(
            $("#template-account-session-latency").html(),
            $.extend(sessionUtils.createLatency(pending_rsvp_request.user), pending_rsvp_request.user),
            {variable: 'data'}
          );

          var avatar_url = context.JK.resolveAvatarUrl(pending_rsvp_request.user.photo_url);

          rsvpHtml = context._.template(
            $templateAccountPendingRsvp.html(),
            {user_id: pending_rsvp_request.user_id, avatar_url: avatar_url,
              user_name: pending_rsvp_request.user.name, instruments: instrumentLogoHtml,
              latency: latencyHtml, request_id: pending_rsvp_request.id, instrument_text: instrumentDesc.join('|')},
            {variable: 'data'}
          );

          resultHtml += rsvpHtml;
          instrumentLogoHtml = "";
        }
      });

      return resultHtml;
    }

    function generateSessionRsvps() {
      var resultHtml = "";
      var rsvpHtml = "";
      var instrumentLogoHtml = "";
      var latencyHtml = "";
      $.each(sessionData.approved_rsvps, function(index, approved_rsvp) {
        if ("instrument_list" in approved_rsvp) {
          $.each(approved_rsvp.instrument_list, function(index, instrument) {
            var instrumentId;
            
            if (instrument) {
              instrumentId = context.JK.getInstrumentId(instrument.id);
            }
            else {
              instrumentId = 'other';
            }
            var inst = context.JK.getInstrumentIcon24(instrumentId);
            instrumentLogoHtml += '<img title="' + instrumentId + '" hoveraction="instrument" data-instrument-id="' + instrumentId + '" src="' + inst + '" width="24" height="24" />&nbsp;';
          });
        }

        latencyHtml = context._.template(
          $("#template-account-session-latency").html(),
          $.extend(sessionUtils.createLatency(approved_rsvp), approved_rsvp),
          {variable: 'data'}
        );

        var avatar_url = approved_rsvp.resolved_photo_url;

        var request_id = null;

        $.each(rsvpData, function(index, rsvp) {
          if (rsvp.user_id == approved_rsvp.id) {
            var approved = true;
            $.each(rsvp, function(index, rsvp_slot) {
              if (rsvp_slot.approved == false) {
                approved = false;
              }
            });

            if (approved) {
              request_id = rsvp.id;
            }
          }
        });

        rsvpHtml = context._.template(
          $("#template-account-session-rsvp").html(),
          {id: approved_rsvp.id, avatar_url: avatar_url,
            user_name: approved_rsvp.name, instruments: instrumentLogoHtml,
            latency: latencyHtml, is_owner: sessionData.isOwner, request_id: request_id},
          {variable: 'data'}
        );

        resultHtml += rsvpHtml;
        instrumentLogoHtml = "";
      });

      return resultHtml;
    }

    function generateSessionNeeded() {
      var resultHtml = "";
      if(sessionData['is_unstructured_rsvp?']) {
        resultHtml += sessionUtils.createOpenSlot($templateOpenSlots, {description: 'Any Instrument'});
      }

      $.each(sessionData.open_slots, function(index, slot) {
        resultHtml += sessionUtils.createOpenSlot($templateOpenSlots, slot);
      });

      return resultHtml;
    }

    function generateSessionInvited() {
      var resultHtml = "";
      var avatar_url = "";
      $.each(sessionData.invitations, function(index, invitation) {
        avatar_url = invitation.receiver_avatar_url;

        resultHtml += context._.template(
          $("#template-account-invited").html(),
          {avatar_url: avatar_url, user_id: invitation.receiver_id},
          {variable: 'data'}
        );
      });

      return resultHtml;
    }

    function generateSessionProperties() {
      var resultHtml = "";
      resultHtml = context._.template(
        $("#template-account-session-properties").html(),
        sessionData,
        {variable: 'data'}
      );
      return resultHtml;
    }

    function initialize(invitationDlg) {
      var screenBindings = {
        'beforeShow': beforeShow,
        'afterShow': afterShow
      };

      app.bindScreen('account/sessionDetail', screenBindings);
      app.bindScreen('account/sessionDetail', screenBindings);

      $screen = $(".account-session-detail");
      $inviteOthersBtn = $screen.find(".sessions-header .invite-others");
      $cancelRsvpBtn = $screen.find(".sessions-header .cancel-rsvp");
      $sessionPageBtn = $screen.find(".sessions-header .session-detail-page");
      $sessionDetail = $screen.find("#account-session-detail-div");
      $shareUrl = $screen.find('.share-url');
      $spinner = $screen.find('.paginate-wait');
      invitationDialog = invitationDlg;

      inviteMusiciansUtil = new JK.InviteMusiciansUtil(JK.app);
      inviteMusiciansUtil.initialize(JK.FriendSelectorDialogInstance);

      $templateOpenSlots = $('#template-open-slots');
      $templateAccountPendingRsvp = $("#template-account-pending-rsvp");
      $templateAccountSessionDetail = $('#template-account-session-detail');
    }

    this.initialize = initialize;
    this.beforeShow = beforeShow;
    this.afterShow = afterShow;

    return this;
  };

})(window, jQuery);