$ = jQuery
context = window
logger = context.JK.logger
rest = context.JK.Rest();

VideoUploaderActions = @VideoUploaderActions


@VideoUploaderStore = Reflux.createStore(
  {
    listenables: VideoUploaderActions
    logger: context.JK.logger
    preparingUpload: false
    uploading: false
    paused: false
    recordingId: null
    videoUrl: null
    bytesSent: 0
    bytesTotal: 1
    errorReason: null
    errorDetail: null
    state: null
    done: false

    init: ->
        # Register with the app store to get @app
      this.listenTo(context.AppStore, this.onAppInit)
      @state = {uploading: @uploading, recordingId: @recordingId, videoUrl: @videoUrl, paused: @paused, preparingUpload: @preparingUpload, bytesSent: @bytesSent, bytesTotal: @bytesTotal, errorReason: @errorReason, errorDetail: @errorDetail, done: @done }

    onAppInit: (app) ->
      @app = app

    triggerState: () ->
      @state = {uploading: @uploading, recordingId: @recordingId, videoUrl: @videoUrl, paused: @paused, preparingUpload: @preparingUpload, bytesSent: @bytesSent, bytesTotal: @bytesTotal, errorReason: @errorReason, errorDetail: @errorDetail, done: @done}
      @trigger(@state)

    getState: () ->
      @state

    onPause: () ->
      if @uploading
        @uploading = false
        @paused = true
        context.jamClient.pauseVideoUpload()
        @triggerState()

    onResume: () ->
      if @paused && @recordingId?
        @uploading = true
        @paused = false
        context.jamClient.resumeVideoUpload()
        @triggerState()
      else
        if @uploading
          @app.layout.notify({title: 'Already uploading', text: "A video is already being uploaded."})
        else
          @app.layout.notify({title: 'Nothing to resume', text: "No upload to resume."})

    onCancel: () ->
      if @uploading
        @uploading = false
        context.jamClient.cancelVideoUpload()
        @triggerState()

    onDelete: (recordingId) ->
      context.jamClient.deleteVideo(recordingId);

    onNewVideo: (recordingId) ->

      @onCancel(recordingId)

      @done = false
      @paused = false
      @bytesSent = 0
      @bytesTotal = 1
      @errorReason = null
      @errorDetail = null
      @videoUrl = null
      @triggerState()

    onShowUploader: (recordingId) ->

      if @childWindow?
        logger.debug("showUploader popup being closed automatically")
        @childWindow.close()
        @childWindow = null

      @childWindow = window.open("/popups/video/upload/" + recordingId, 'Video Uploader', 'scrollbars=yes,toolbar=no,status=no,height=155,width=350')

    onUploaderClosed: () ->

      if @childWindow?
        @childWindow = null

    onUploadVideo: (recordingId) ->

      if @uploading || @preparingUpload
        logger.debug("ignoring upload request")
        return

      @preparingUpload = true
      @onNewVideo()

      rest.getRecording({id:recordingId})
      .done((response) =>
        claim = response.my

        privateStatus = 'private'
        privateStatus = 'public' if claim.is_public

        if claim?
          videoInfo = {
            "snippet": {
              "title": claim.name,
              "description": claim.description,
              "tags": ["JamKazam"],
              "categoryId": 10 # music
            },
            "status": {
              "privacyStatus": privateStatus,
              "embeddable": true,
              "license": "youtube"
            }
          }

          rest.getUserAuthorizations()
          .done((response) =>

            # http://localhost:3000/popups/video/upload/d25dbe8e-a066-4ea0-841d-16872c713fc9
            youtube_auth = null
            for authorization in response.authorizations
              if authorization.provider == 'google_login'
                youtube_auth = authorization.token
                break

            if youtube_auth?
              logger.debug("calling uploadVideo(#{recordingId}, #{youtube_auth}, #{videoInfo})")
              result = context.jamClient.uploadVideo(recordingId, youtube_auth, JSON.stringify(videoInfo),
              "VideoUploaderStore.clientUploadCallback",
              "VideoUploaderStore.clientDoneCallback",
              "VideoUploaderStore.clientFailCallback")

              if result.error
                @preparingUpload = false
                @triggerState()
                @app.layout.notify({title: 'Unable to upload video', text: 'Application error: ' + result.error})
              else
                @preparingUpload = false
                @videoUrl = null
                @uploading = true
                @recordingId = recordingId
                @triggerState()


            else
              @preparingUpload = false
              @triggerState()
              @app.layout.notify({title: 'No Authorization Yet for YouTube', text: 'Youtube authorization still needed'})

          )
          .fail((jqXHR) =>
            @preparingUpload = false
            @triggerState()
            @app.layout.notifyServerError(jqXHR, 'Unable to fetch user authorizations')
          )

        else
          @preparingUpload = false
          @triggerState()
          @app.layout.notify({title: "You do not have a claim to this recording", text: "If this is in error, contact support@jamkazam.com."})

      )
      .fail((jqXHR) =>
        @preparingUpload = false
        @triggerState()
        @app.layout.notifyServerError(jqXHR, 'Unable to fetch recording information')
      )

    clientUploadCallback: (bytesSent, bytesTotal) ->
      logger.debug("bytesSent: #{bytesSent} bytesTotal: #{bytesTotal}")

      # backend will report 0 bytes total sometimes as the upload is failing. just ignore it; we'll get an error message soon
      return if bytesTotal == 0

      VideoUploaderStore.bytesSent = Number(bytesSent)
      VideoUploaderStore.bytesTotal = Number(bytesTotal)
      VideoUploaderStore.triggerState()

    clientDoneCallback: (video_id) ->
      console.log
      logger.debug("client uploaded video successfully to #{video_id}")
      VideoUploaderStore.uploading = false

      VideoUploaderStore.videoUrl = "https://www.youtube.com/watch?v=#{video_id}"

      rest.addRecordingVideoData(VideoUploaderStore.recordingId, {video_id: video_id})
      .fail(() =>
        VideoUploaderStore.app.layout.notify({title: 'Sync Error', text:'Unable to notify server about uploaded video'})
      )

      VideoUploaderStore.recordingId = null
      VideoUploaderStore.done = true
      VideoUploaderStore.triggerState()

    clientFailCallback: (reason, detail) =>
      logger.warn("client failed to video upload #{reason}, #{detail}")
      VideoUploaderStore.uploading = false
      VideoUploaderStore.errorReason = reason
      VideoUploaderStore.errorDetail = detail

      # if reason == "create_video_failed" && errorDetail = "401"
      # then don't trigger state, instead ask server for a fresh token
      #

      VideoUploaderStore.triggerState()
  }
)

@VideoUploaderStore