$ = jQuery
context = window
logger = context.JK.logger
SessionStore = context.SessionStore

@ChatStore = Reflux.createStore(
  {
    listenables: @ChatActions

    limit: 20,
    currentPage: 0,
    next: null,
    channel: 'global',
    systemMsgId: 0
    msgs: {global:[], session:[]}
    max_global_msgs: 100
    channelType: null

    init: () ->
      # Register with the app store to get @app
      this.listenTo(context.AppStore, this.onAppInit)
      this.listenTo(context.UserActivityStore, this.onUserActivityChanged)

    onAppInit: (@app) ->
      if context.JK.currentUserId?
        @fetchHistory()

    onUserActivityChanged: (state) ->

      if !gon.chat_blast
        systemMsg = {}
        @systemMsgId = @systemMsgId + 1
        systemMsg.sender_name = 'System'
        systemMsg.sender_id = 'system'
        systemMsg.msg_id = @systemMsgId
        systemMsg.created_at = new Date().toISOString()
        systemMsg.channel = 'global'
        if state.active
          systemMsg.msg = "You've come back!"
        else
          systemMsg.msg = "You've become inactive.  Any global chat messages while away will be missed."

        @onMsgReceived(systemMsg)

    # after the animation to open the chat panel is done, do it!
    onFullyOpened: () ->
      @changed()

    # called from ChatPanel
    onSessionStarted: (sessionId, lessonId) ->
      logger.debug("ChatStore.sessionStarted sessionId: #{sessionId} lessonId: #{lessonId}")
      if lessonId?
        @lessonSessionId = lessonId
        #@msgs['session'] = []
        @channel = 'lesson'
        @channelType =  'lesson'
        @fetchHistory()
        @onEmptyChannel(@channel)
      else
        @msgs['session'] = []
        @channel = 'session'
        @channelType = null
        @fetchHistory()
        @onEmptyChannel(@channel)


    buildQuery: (channel = null) ->
      if !channel?
        channel = @channel


      query = {type: 'CHAT_MESSAGE', limit:@limit, page: @currentPage, channel: channel};

      if channel == 'session' && SessionStore.currentSessionId?
        query.music_session = SessionStore.currentSessionId

      if channel == 'lesson' && @lessonSessionId?
        query.lesson_session = @lessonSessionId

      if @next
        query.start = next
      return query

    initializeLesson: (lessonSessionId) ->
      @lessonSessionId = lessonSessionId
      @channelType = 'lesson'

      @fetchHistory('lesson')

    fetchHistory: (channel = null) ->

      if !channel?
        channel = @channel

      # load previous chat messages
      rest.getChatMessages(@buildQuery(channel))
      .done((response) =>
        @onLoadMessages(channel, response)
      ).fail((jqXHR) =>
        @app.notifyServerError(jqXHR, 'Unable to Load Session Conversations')
      )

    onEmptyChannel: (channel) ->
      @msgs[channel] = []
      @changed()

    convertServerMessages: (chats) ->
      converted = []
      for chat in chats
        convert = {}
        convert.sender_name = chat.user?.name
        convert.sender_id = chat.user_id
        convert.msg = chat.message
        convert.msg_id = chat.id
        convert.created_at = chat.created_at
        convert.channel = chat.channel
        convert.purpose = chat.purpose
        convert.music_notation = chat.music_notation
        convert.claimed_recording = chat.claimed_recording
        converted.push(convert)
      converted

    # called from ChatPanel
    onLoadMessages: (channel, msgs) ->

      if channel == 'lesson'
        channel = @lessonSessionId

      channelMsgs = @msgs[channel]

      if !channelMsgs?
        channelMsgs = []
        @msgs[channel] = channelMsgs

      history = @convertServerMessages(msgs.chats)

      for oldMsg in history
        skip = false
        for channelMsg in channelMsgs
          if oldMsg.msg_id == channelMsg.msg_id
            skip = true
            break

        if !skip
          channelMsgs.unshift(oldMsg)

      #totalMsgs = history.concat(channelMsgs)
      channelMsgs.sort((a, b) =>
        c = new Date(a.created_at)
        d = new Date(b.created_at)
        return  (c > d) - (c < d)
      )
      @msgs[channel] = channelMsgs

      @changed()

    onMsgReceived: (msg) ->

      effectiveChannel = msg.channel

      if msg.channel == 'lesson' || msg.channel == 'session'

        if msg.channel == 'session'
          'session'
        else
          effectiveChannel = msg.lesson_session_id


        if msg.attachment_type?
          console.log("attachment type seen")
          if msg.attachment_type == 'notation' || msg.attachment_type == 'audio'
            msg.music_notation = {id: msg.attachment_id, file_name: msg.attachment_name, attachment_type: msg.attachment_type}
          else
            msg.claimed_recording = {id: msg.attachment_id, name: msg.attachment_name}

      channelMsgs = @msgs[effectiveChannel]

      if !channelMsgs?
        channelMsgs = []
        @msgs[effectiveChannel] = channelMsgs

      channelMsgs.push(msg)

      # don't let the global channel grow indefinitely
      if effectiveChannel == 'global'
        while channelMsgs.length > @max_global_msgs
          channelMsgs.shift()

      @changed()

    buildMessage:(msg, target_user, channel) ->
      payload = {message: msg}
      if channel == 'session'
        payload.music_session = SessionStore.currentSessionId
      else if channel == 'lesson'
        payload.lesson_session = @lessonSessionId
      payload.channel = channel
      payload.client_id = @app.clientId
      payload.target_user = target_user
      payload

    onActivateChannel: (channel) ->
      logger.debug("onActivateChannel: " + channel)
      @channel = channel
      if @channel != 'lesson'
        @channelType = null
      if @channel == 'lesson'
        @fetchHistory()
      @changed()

    onSendMsg: (msg, done, fail, target_user = null, channel = null) ->
      if !channel?
        channel = @channel
      rest.createChatMessage(@buildMessage(msg, target_user, channel))
      .done((response) =>

        done(response)

        if response.channel == 'session'
          @onMsgReceived({
            sender_name: "me",
            sender_id: context.JK.currentUserId,
            msg: msg,
            msg_id: response.id,
            created_at: response.created_at,
            channel: response.channel
          })
        else if response.channel == 'lesson'
          @onMsgReceived({
            sender_name: "me",
            sender_id: context.JK.currentUserId,
            msg: msg,
            msg_id: response.id,
            created_at: response.created_at,
            channel: response.lesson_session_id
          })
      )
      .fail((jqXHR) =>
        fail(jqXHR)
      )

    # unused/untested. send direct to gateway
    onSendMsgInstant: (msg, channel = null) ->
      logger.debug("ChatStore.sendMsg", msg)

      if !channel?
        channel = @channel
      window.JK.JamServer.sendChatMessage(channel, msg)

    getState: () ->
      return {msgs: @msgs, channel: @channel, channelType: @channelType, lessonSessionId: @lessonSessionId}

    changed: () ->
      @trigger(@getState())
  }
)
