context = window
rest = new context.JK.Rest()
ChatActions = @ChatActions
SessionStore = @SessionStore


@ChatWindow = React.createClass({
  mixins: [Reflux.listenTo(@AppStore, "onAppInit"), Reflux.listenTo(@UserStore, "onUserChanged"),
           Reflux.listenTo(@ChatStore, "onChatChanged")]

  lastChannel: null

  getInitialState: () ->
    state = context.ChatStore.getState()
    state

  getInitialProps: () ->
    {newFormat:true}

  onChatChanged: (chatState) ->
    @setState(chatState)

  onUserChanged: (userState) ->
    @setState(userState)

  onAppInit: (app) ->
    @app = app

  activateChannel: (channel, e) ->
    e.preventDefault()
    ChatActions.activateChannel(channel);

  convertPurpose: (purpose) ->
    if !purpose?
      return ''

    switch purpose
      when 'Lesson Requested' then 'requested lesson'
      when 'Lesson Canceled' then 'canceled lesson'
      when 'Lesson Approved' then 'approved lesson'
      when 'All Lesson Times Updated' then 'updated all lesson times'
      when 'Lesson Updated Time Approved' then 'updated lesson time'
      when 'New Time Proposed' then 'proposed new time'
      when 'Lesson Declined' then 'declined lesson'
      when 'Notation File' then 'attached a notation file'
      when 'Audio File' then 'attached an audio file'
      when 'JamKazam Recording' then 'attached a recording'
      when 'Lesson Timeout' then 'canceled by system'
      when 'Video Uploaded' then 'uploaded video'
      else purpose

  notationClicked: (music_notation, e) ->
    e.preventDefault()

    rest.getMusicNotation(music_notation.id).done((response) =>
      context.JK.popExternalLink(response.url)
    )
    .fail((jqXHR) =>
      context.JK.Banner.showAlert('Unable to fetch URL for music notation. Error: ' + jqXHR.responseText)
    )

  audioClicked: (music_notation, e) ->
    e.preventDefault()

    rest.getMusicNotation(music_notation.id).done((response) =>
      context.JK.popExternalLink(response.url)
    )
    .fail((jqXHR) =>
      context.JK.Banner.showAlert('Unable to fetch URL for audio. Error: ' + jqXHR.responseText)
    )
    
  recordingClicked: (recording, e) ->
    e.preventDefault()
    context.JK.popExternalLink("/recordings/#{recording.id}")

  videoClicked: (recording, e) ->
    e.preventDefault()
    context.JK.popExternalLink("https://www.youtube.com/watch?v=#{recording.video_id}")

  openMenu: (lesson, e) ->
    $this = $(e.target)
    if !$this.is('.lesson-session-actions-btn')
      $this = $this.closest('.lesson-session-actions-btn')
    $this.btOn()

  render: () ->

    if @state.channel == 'lesson'
      chatTabs = `<div className="chat-tabs">
        <a data-lesson-id={this.state.lessonSessionId} className="lesson-session-actions-btn"
           onClick={this.openMenu.bind(this, {id: this.state.lessonSessionId})}>attach file
          <div className="details-arrow arrow-down"/>
        </a>
      </div>`
    else if !this.props.hideHeader
      tabs = []
      for channel of @state.msgs
        classes = {}
        classes[channel] = true
        classes['chat-tab'] = true
        classes['active'] = channel == @state.channel

        if channel == 'global'
          display = 'Global'
        else if channel == 'session'
          display = 'Session'
        else if channel == 'lesson'
          display = 'Lesson'
        else if !channel?
          display = 'Global'
        else
          display = 'Unknown'

        if display == 'Unknown'
          continue

        tabs.push(`<div key={channel} className={classNames(classes)}><a onClick={this.activateChannel.bind(this, channel)}>{display}</a></div>`)
      chatTabs = `<div className="chat-tabs">
        {tabs}
      </div>`

    msgs = []

    openBig = null

    if @activeChannelType() == 'lesson'
      activeChannel = @state.lessonSessionId
    else
      activeChannel = @state.channel

    if activeChannel == 'global'
      openBig = `<a className="make-big" href="#" onClick={this.openChatDialog.bind(this)}>Expand</a>`

    activeMsgs = @state.msgs[activeChannel] || []

    for msg in activeMsgs

      timeago = $.timeago(msg.created_at)
      if msg.sender_id == context.JK.currentUserId
        sender = "me"
      else
        sender = msg.sender_name

      if msg.purpose
        purpose = `<div className="chat-message-purpose">{this.convertPurpose(msg.purpose)}</div>`
      else
        purpose = null

      additional = null
      if msg.purpose == 'Notation File'
        additional = `<a className="additional" onClick={this.notationClicked.bind(this, msg.music_notation)}>{msg.music_notation.file_name}</a>`
      else if msg.purpose == 'Audio File'
        additional = `<a className="additional" onClick={this.audioClicked.bind(this, msg.music_notation)}>{msg.music_notation.file_name}</a>`
      else if msg.purpose == 'JamKazam Recording'
        additional = `<a className="additional" onClick={this.recordingClicked.bind(this, msg.claimed_recording)}>{msg.claimed_recording.name}</a>`
      else if msg.purpose == 'Video Uploaded'
        additional = `<a className="additional" onClick={this.videoClicked.bind(this, msg.claimed_recording)}>Watch on YouTube</a>`

      msgs.push(`<div key={msg.msg_id} className="chat-message">
        <span className="chat-message-sender">{sender}</span>{purpose}<time className="chat-message-timestamp timeago">{timeago}</time>
        <span className="chat-message-text">{msg.msg}</span>
        {additional}
      </div>`)



    if this.props?.showEmailNotice
      otherName = this.props?.other?.name
      emailSentNotice = `<div className="email-notice">an email will be sent if {otherName} is offline</div>`
    if this.props?.showClose
      closeBtn = `<a className="button-grey btn-close-chat" onClick={this.handleCloseMessage}>CLOSE</a>`

    topClasses = {ChatWindow: true}
    if this.props?.rootClass?
      topClasses[this.props.rootClass] = true

    if this.props.rootClass == 'ChatDialog'
      attachFiles = `<a id="attach-files-chat-dialog" data-lesson-id={this.state.lessonSessionId} className="lesson-session-actions-btn"
          onClick={this.openMenu.bind(this, {id: this.state.lessonSessionId})}>attach file
        <div className="details-arrow arrow-down"/>
      </a>`

    `<div className={classNames(topClasses)}>
      {openBig}
      {chatTabs}
      <div className="active-tab">
        <div className="chat-list-scroller">
          {msgs}
        </div>
      </div>
      <div className="chat-sender">
        <form onSubmit={this.handleSendMessage} className="chat-message-form">
          <textarea onKeyDown={this.handleEnter} name="chat-message" id="new-chat-message" placeholder="enter message"></textarea>

          <a className="button-orange btn-send-chat-message" onClick={this.handleSendMessage}>SEND</a>
          {closeBtn}
          {emailSentNotice}
          {attachFiles}
        </form>

      </div>
    </div>`

  openChatDialog: () ->
    @app.layout.showDialog('chat-dialog', {d1: 'global'})

  activeChannelType: () ->
    @state.channelType

  sendMessage:()->
    if !context.JK.JamServer.connected
      return false

    msg = @textBox.val()
    if !msg? || msg == ''
      # don't bother the server with empty messages
      return false;

    if !@sendingMessage
      @sendingMessage = true
      target_user_id = this.props?.other?.id
      ChatActions.sendMsg(msg, @sendMsgDone, @sendMsgFail, target_user_id, @activeChannelType())

  sendMsgDone: () ->
    @textBox.val('')
    @sendingMessage = false

  sendMsgFail: (jqXHR) ->
    if jqXHR.status == 404
      @app.notifyServerError(jqXHR, 'Session chat is only available while in session.')
    else
      @app.notifyServerError(jqXHR, 'Unable to Send Chat Message')
    @sendingMessage = false

  handleSendMessage: (e) ->
    e.preventDefault()
    @sendMessage()


  handleCloseMessage: (e) ->
    e.preventDefault()
    this.props.onCloseClicked()

  componentDidMount: () ->
    @root = $(@getDOMNode())
    @textBox = @root.find('textarea')

  componentDidUpdate: () ->
    if @lastChannel != @state.channel
      speed = 0
    else
      speed = 'slow'
    @lastChannel = @state.channel

    #speed = 0 #slow
    $scroller = @root.find('.chat-list-scroller')
    $scroller.animate({scrollTop: $scroller[0].scrollHeight}, speed)

    items = @root.find('.chat-tabs .lesson-session-actions-btn')
    @hookupMenu(items)

    items = @root.find('#attach-files-chat-dialog')
    @hookupMenu(items)


  hookupMenu: (items) ->
    $.each(items, (i, node) => (
      $node = $(node)

      chat_dialog = this.props.rootClass == 'ChatDialog'
      lesson = {id: $node.attr('data-lesson-id'), attachments_only: true, chat_dialog: chat_dialog}

      $node.lessonSessionActions(lesson).off(context.JK.EVENTS.LESSON_SESSION_ACTION).on(context.JK.EVENTS.LESSON_SESSION_ACTION, @lessonSessionActionSelected)
    ))

  lessonSessionActionSelected: (e, data) ->
    lessonId = data.options.id

    if data.lessonAction == 'attach-recording'
      window.AttachmentActions.startAttachRecording.trigger(lessonId, SessionStore.id())
    else if data.lessonAction == 'attach-notation'
      window.AttachmentActions.startAttachNotation.trigger(lessonId, SessionStore.id())
    else if data.lessonAction == 'attach-audio'
      window.AttachmentActions.startAttachAudio.trigger(lessonId, SessionStore.id())

  pasteIntoInput: (el, text) ->
    el.focus();
    if typeof el.selectionStart == "number" && typeof el.selectionEnd == "number"
      val = el.value
      selStart = el.selectionStart
      el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd)
      el.selectionEnd = el.selectionStart = selStart + text.length
    else if typeof document.selection != "undefined"
      textRange = document.selection.createRange()
      textRange.text = text
      textRange.collapse(false)
      textRange.select()

  handleEnter: (evt) ->
    if evt.keyCode == 13 && evt.shiftKey
      evt.preventDefault()
      @pasteIntoInput($(evt.target).get(0), "\n")
    else if evt.keyCode == 13 && !evt.shiftKey
      @sendMessage()
})