context = window
MIX_MODES = context.JK.MIX_MODES


@JamTrackSearchScreen = React.createClass({

  mixins: [Reflux.listenTo(@AppStore,"onAppInit"), Reflux.listenTo(@UserStore,"onUserChanged")]

  LIMIT: 10
  instrument_logo_map: context.JK.getInstrumentIconMap24()
  input: null
  MAX_ARTIST_SHOW: 3

  filterOption:() ->
    true

  render: () ->

    searchText = if @state.first_search then 'SEARCH' else 'SEARCH AGAIN'

    uiJamTracks = []
    for jamtrack in @state.jamtracks
      trackRow = context._.clone(jamtrack)
      trackRow.track_cnt = jamtrack.tracks.length
      trackRow.tracks = []

      # if an instrument is selected by the user, then re-order any jam tracks with a matching instrument to the top

      ###instrument = @instrument.val()
      if instrument?
        jamtrack.tracks.sort((a, b) =>
          aWeight = @computeWeight(a, instrument)
          bWeight = @computeWeight(b, instrument)
          return aWeight - bWeight
        )
###
      for track in jamtrack.tracks

        if track.track_type == 'Master' || track.track_type == 'Track'
          trackRow.tracks.push(track)

          if track.track_type == 'Master'
            track.instrument_desc = "Master"
          else if track.track_type == 'Track'
            inst = '../assets/content/icon_instrument_default24.png'
            if track.instrument?
              if track.instrument.id in @instrument_logo_map
                inst = @instrument_logo_map[track.instrument.id].asset
              track.instrument_desc = track.instrument.description
            track.instrument_url = inst

            if track.part != ''
              track.instrument_desc += ' (' + track.part + ')'

      trackRow.free_state = if (@state.is_free && jamtrack.allow_free) then 'free' else 'non-free'

      trackRow.is_free = @state.is_free && jamtrack.allow_free

      uiJamTracks.push trackRow

    artists = []
    artistsShown = 0
    for artist in @state.artists

      if @state.show_all_artists || artistsShown < @MAX_ARTIST_SHOW
        artists.push `<div key={artist.original_artist}><a className="show-artist" onClick={this.artistNavSelected} data-artist={artist.original_artist}>{artist.original_artist}</a></div>`

      artistsShown += 1


    artists.push `<div key="no-results" className="no-results">No matching artists</div>` if artists.length == 0

    if !@state.show_all_artists && @state.artists.length > @MAX_ARTIST_SHOW
      artists.push `<div key="show-hide-artists"><a onClick={this.showAllArtists} className="show-hide-artists">show all <div className="details-arrow arrow-down" /></a></div>`
    else if @state.show_all_artists
      artists.push `<div key="show-hide-artists"><a onClick={this.hideExtraArtists} className="show-hide-artists">hide artists <div className="details-arrow arrow-up" /></a></div>`

    jamtracks = []


    for jamtrack in uiJamTracks

      jamtrackPricesClasses = { "jamtrack-price" : true }
      jamtrackPricesClasses[jamtrack.free_state] = true
      jamtrackPricesClasses = classNames(jamtrackPricesClasses)

      tracks = []
      for track in jamtrack.tracks
        tracks.push `<div className="jamtrack-track hidden" key={track.id} data-jamtrack-track-id={track.id}>
          <div className="jamtrack-preview">
            <JamTrackPreview jamTrack={jamtrack} jamTrackTrack={track} options={{master_shows_duration: true, color:'gray'}} />
            <div className="clearall" />
          </div>
        </div>`

      actionBtn = null
      if jamtrack.purchased
        if jamtrack.can_download
          actionBtn = `<a className="jamtrack-add-cart-disabled button-grey button-disabled" href="javascript:void(0)">PURCHASED</a>`
        else
          priceNotice = `<div className={jamtrackPricesClasses}>$ {Number(jamtrack.upgrade_price).toFixed(2)}</div>`
          actionBtn = `<div>
            <div className="jamtrack-add-zone">
              {priceNotice}
              <a className="jamtrack-add-cart button-orange" href="#" data-jamtrack-id={jamtrack.id} data-variant="download">UPGRADE TO FULL</a>
            </div>
            <a className="jamtrack-upgrade-help" href='#'>HELP</a>
          </div>`


      else if jamtrack.is_free
        actionBtn = `<a className="jamtrack-add-cart button-orange is_free" href="#" data-jamtrack-id={jamtrack.id} data-variant="full">GET IT FREE!</a>`
      else if jamtrack.added_cart
        actionBtn = `<a className="jamtrack-add-cart-disabled button-grey button-disabled" href="client#/shoppingCart">ALREADY IN CART</a>`
      else
        priceNotice = `<div className={jamtrackPricesClasses}>$ {jamtrack.price}</div>`
        fullPriceNotice = `<div className={jamtrackPricesClasses}>$ {jamtrack.download_price}</div>`
        actionBtn = `<div>
          <div className="jamtrack-add-zone">
            {priceNotice}
              <a className="jamtrack-add-cart button-orange" href="#" data-jamtrack-id={jamtrack.id} data-variant="stream">ADD TO CART</a>
          </div>
          <div className="jamtrack-add-zone">
            {fullPriceNotice}
            <a className="jamtrack-add-cart button-orange" href="#" data-jamtrack-id={jamtrack.id} data-variant="full">ADD TO CART (FULL)</a>
          </div>
          <a className="jamtrack-variant-help" href='#'>HELP</a>
        </div>`

      availabilityNotice = null
      if jamtrack.sales_region==context.JK.AVAILABILITY_US
        availabilityNotice =
          `<div className="jamtrack-license">
            This JamTrack available only to US customers. &nbsp;&nbsp;&nbsp;&nbsp;
            <a className="license-us-why" href="#">why?</a>
          </div>`

      jamtracks.push `<tr className="jamtrack-record" key={jamtrack.id} data-jamtrack-id={jamtrack.id}>
        <td className="jamtrack-detail">
          <div className="jamtrack-name">"{jamtrack.name}"</div>
          <div className="jamtrack-original-artist"><a onClick={this.onArtistClick.bind(this, jamtrack.original_artist)}>by {jamtrack.original_artist}</a></div>
          <br className="clearall"/>
          <div className="clearall detail-label extra hidden song-writer">Songwriters:</div>
          <div className="detail-value extra hidden">{jamtrack.songwriter}</div>
          <div className="clearall detail-label extra hidden">Publishers:</div>
          <div className="detail-value extra hidden">{jamtrack.publisher}</div>
          <div className="clearall detail-label extra hidden">Genres:</div>
          <div className="detail-value extra hidden">{jamtrack.genres.join(', ')}</div>
          <div className="clearall detail-label extra hidden">Version:</div>
          <div className="detail-value extra hidden">{jamtrack.recording_type}</div>
        </td>
        <td className="jamtrack-tracks">
          <div className="detail-arrow">
            <div className="jamtrack-detail-btn">
              show all tracks <a className="details-arrow arrow-down"/>
            </div>
          </div>
          {tracks}
        </td>
        <td className="jamtrack-action">
          <div className="jamtrack-action-container">
            <div className="jamtrack-actions">
              {actionBtn}
              {availabilityNotice}
            </div>
          </div>

        </td>
      </tr>`

    #jamtracks.push `<div className="no-results">No matching JamTracks</div>` if jamtracks.length == 0

    searchClasses = classNames({
      "button-orange" : true,
      "search-btn" : true,
      "disabled" : @state.searching
    })

    artistSection = null
    jamTracksSection = null

    if @state.type == 'user-input'
      if @state.searching
        jamtracksHeader = "searching..."
      else
        jamtracksHeader = "search results: #{@state.count} jamtracks"



    else if @state.type == 'artist-select'
      jamtracksHeader = "search results: jamtracks for artist \"#{@state.artist}\""
    else if @state.type == 'song-select'
      jamtracksHeader = "search results: jamtrack \"#{@state.song}\""
    else
      throw "unknown search type #{@state.type}"

    if !@state.first_search


      # only show the artists links if the user typed the results
      if @state.type == 'user-input'
        artistSection =
          `<div>
            <h2>search results: artists</h2>
            <div className="artist-results">
              {artists}
            </div>
          </div>`

      jamTracksSection =
        `<div>
          <h2 className="jamtrack-results-header">{jamtracksHeader} <a className="back-to-jamtracks-home" href="/client#/jamtrack">back to jamtracks home</a></h2>

          <table className="generaltable jamtrack-table">
            <thead>
            <tr>
              <th className="jamtrack-detail">JAMTRACK</th>
              <th className="jamtrack-tracks">TRACKS INCLUDED / PREVIEW</th>
              <th className="jamtrack-shop">SHOP</th>
            </tr>
            </thead>
            <tbody className="jamtrack-content">
            {jamtracks}
            </tbody>
          </table>
          <div className="end-of-jamtrack-list end-of-list">No more JamTracks</div>
        </div>`

    options = {}


    searchValue = if @state.search == 'SEPARATOR' then '' else window.JamTrackSearchInput

    `<div className="JamTrackSearchScreen">
      <div className="controls">
        <JamTrackAutoComplete onSearch={this.search} />
        <button className={searchClasses} name="search" onClick={this.userSearch}>{searchText}</button>
        <div className="download-all">Download JamTracks catalog<br/><JamTrackCSVLink/> or <JamTrackPdfLink/></div>
      </div>
      <div className="content-body-scroller">
        {artistSection}
        {jamTracksSection}
      </div>
    </div>`



  clearResults:() ->
    @setState({currentPage: 0, next: null, show_all_artists: false, artists:[], jamtracks:[], type: 'user-input', searching:false, artist: null, song:null, is_free: @user.show_free_jamtrack, first_search: true})


  getInitialState: () ->
    {search: '', type: 'user-input', artists:[], jamtracks:[], show_all_artists: false, currentPage: 0, next: null, searching: false, first_search: true, count: 0, is_free: context.JK.currentUserFreeJamTrack}

  onArtistClick: (artist, e) ->
    e.preventDefault()

    @search('artist-select', artist)

  onSelectChange: (val) ->

    return false unless val?

    search_type
    if val.indexOf('ARTIST=') == 0
      search_type = 'artist-select'
      artist = val['ARTIST='.length..-1]
      @search(search_type, artist)
    else if val.indexOf('SONG=') == 0
      search_type = 'song-select'
      song = val['SONG='.length..-1]
      @search(search_type, song)
    else
      @logger.debug("user selected separator")
      # this is to signal to the component that the separator was selected, and it has code in render to negate the selection
      setTimeout((() =>
        @setState({search:val})
      ), 1)

      return false


  onSelectBlur: (e) ->

    #@logger.debug("blur time")

    #@search()

  showAllArtists: () ->
    @setState({show_all_artists: true})

  hideExtraArtists: () ->
    @setState({show_all_artists: false})


  defaultQuery:(extra) ->
    query =
      per_page: @LIMIT
      page: @state.currentPage + 1
      sort_by: 'jamtrack'
    if @state.next
      query.since = @state.next
    $.extend(query, extra)



  userSearch: (e) ->
    e.preventDefault()
    @search('user-input', window.JamTrackSearchInput)

  search: (search_type, input) ->
    return if @state.searching
    return unless input?

    window.JamTrackSearchInput = input

    $root = $(@getDOMNode())
    # disable scroll watching now that we've started a new search
    #@logger.debug("disabling infinite scroll")
    $root.find('.content-body-scroller').off('scroll')
    $root.find('.end-of-jamtrack-list').hide()

    artistSearch = {limit:100}
    if search_type == 'artist-select'
      # the user wants to see just artists matching thes exact name
      artistSearch.artist = input
    else
      # the user wants to see anything sort of matching input
      artistSearch.artist_search = input

    if input?
      @rest.getJamTrackArtists(artistSearch)
      .done((response) =>
        @setState({artists:response.artists})

        # we have to make sure the query starts from page 1, and no 'next' from previous causes a 'since' to show up
        query = @defaultQuery({page: 1})
        delete query.since

        @logger.debug("Search type", search_type)
        if search_type == 'artist-select'
          query.artist = input # works like exact match
        else if search_type == 'song-select'
          query.song = input # works as exact match

        else
          query.search = input # works with tsv
        @rest.getJamTracks(query)
        .done((response) =>
          @setState({jamtracks: response.jamtracks, next: response.next, searching: false, first_search: false, currentPage: 1, count: response.count})
        )
        .fail((jqXHR) =>
          @app.notifyServerError jqXHR, 'Search Unavailable'
          @setState({searching: false, first_search: false})
        )
      )
      .fail((jqXHR) =>
        @app.notifyServerError jqXHR, 'Search Unavailable'
        @setState({searching: false, first_search: false})
      )

      @setState({currentPage: 0, next: null, artists: [], jamtracks:[], searching: true, artist: input, song: input, type: search_type, search:input, count:0})

  getOptions: (input, callback) =>

    #@logger.debug("getOptions input #{input}", this)

    # sigh. ugly global
    window.JamTrackSearchInput = input

    if !input? || input.length == 0
      callback(null, {options: [], complete: false})
      return

    @rest.autocompleteJamTracks({match:input, limit:5})
    .done((autocomplete) =>

      options = []
      for artist in autocomplete.artists
        options.push { value: "ARTIST=#{artist.original_artist}", label: "Artist: #{artist.original_artist}" }

      if options.length > 0 && autocomplete.songs.length > 0
        options.push { value: 'SEPARATOR', label: "---------------"}

      for jamtrack in autocomplete.songs
        options.push { value: "SONG=#{jamtrack.name}", label: "Song: #{jamtrack.name}" }

      callback(null, {options: options, complete: false})
    )

  artistNavSelected: (e) ->
    e.preventDefault()

    @search('artist-select', $(e.target).attr('data-artist'))

  componentDidMount: () ->
    #@logger.debug("componentDidMount")

  componentDidUpdate: ( ) ->
    $root = $(this.getDOMNode())
    $scroller = $root.find('.content-body-scroller')

    for jamTrack in @state.jamtracks
      jamtrackElement = $root.find("tbody .jamtrack-record[data-jamtrack-id=\"#{jamTrack.id}\"]")
      alreadyRegistered = jamtrackElement.data('registered')

      unless alreadyRegistered
        jamtrackElement.data('jamTrack', jamTrack)
        jamtrackElement.data('registered', true)
        jamtrackElement.data('expanded', true)

        @handleExpanded(jamtrackElement)
        @registerEvents(jamtrackElement)


    if @state.next == null
      $scroller = $root.find('.content-body-scroller')
      # if we less results than asked for, end searching
      #$scroller.infinitescroll 'pause'
      #@logger.debug("disabling infinite scroll")
      $scroller.off('scroll')
      if @state.currentPage == 1 and @state.jamtracks.length == 0
        $root.find('.end-of-jamtrack-list').text('No JamTracks found matching your search').show()
        @logger.debug("JamTrackSearch: empty search")
      else if @state.currentPage > 0
        @logger.debug("end of search")
        $noMoreJamtracks = $root.find('.end-of-jamtrack-list').text('No more JamTracks').show()
        # there are bugs with infinitescroll not removing the 'loading'.
        # it's most noticeable at the end of the list, so whack all such entries
    else
      @registerInfiniteScroll($scroller)



  registerInfiniteScroll:($scroller) ->
    @logger.debug("registering infinite scroll")
    $scroller.off('scroll')
    $scroller.on('scroll', () =>

      # be sure to not fire off many refreshes when user hits the bottom
      return if @refreshing

      if $scroller.scrollTop() + $scroller.innerHeight() + 100 >= $scroller[0].scrollHeight
        $scroller.append('<div class="infinite-scroll-loader-2">... Loading more JamTracks ...</div>')
        @refreshing = true
        @setState({searching: true})
        @logger.debug("refreshing more jamtracks for infinite scroll")
        @rest.getJamTracks(@defaultQuery({search:@state.search}))
        .done((json) =>
          @setState({jamtracks: @state.jamtracks.concat(json.jamtracks), next: json.next, first_search: false, currentPage: @state.currentPage + 1, count: json.count})
        )
        .always(() =>
          $scroller.find('.infinite-scroll-loader-2').remove()
          @refreshing = false
          @setState({searching: false})
        )
    )

  playJamtrack:(e) ->
    e.preventDefault()

  addToCartJamtrack:(e) ->
    e.preventDefault()
    $target = $(e.target)
    params = id: $target.attr('data-jamtrack-id')
    params.variant = $target.attr('data-variant')
    isFree = $(e.target).is('.is_free')

    @rest.addJamtrackToShoppingCart(params).done((response) =>
      console.log("added item to shopping cart.  fast_redeem? " + response.fast_redeem)
      if response.fast_reedem
        if context.JK.currentUserId?
          context.location = '/client#/redeemComplete'
        else
          context.location = '/client#/redeemSignup'
      else
        context.location = '/client#/shoppingCart'


    ).fail(((jqxhr) =>

      handled = false
      if jqxhr.status == 422
        body = JSON.parse(jqxhr.responseText)
        if body.errors && body.errors.base
          handled = true
          context.JK.Banner.showAlert("You can not have a mix of free and non-free items in your shopping cart.<br/><br/>If you want to add this new item to your shopping cart, then clear out all current items by clicking on the shopping cart icon and clicking 'delete' next to each item.")
      if !handled
        @app.ajaxError(arguments[0], arguments[1], arguments[2])

    ))

  licenseUSWhy:(e) ->
    e.preventDefault()
    @app.layout.showDialog 'jamtrack-availability-dialog'

  registerEvents:($parent) ->
    $parent.find('.play-button').on 'click', @playJamtrack
    $parent.find('.jamtrack-add-cart').on 'click', @addToCartJamtrack
    $parent.find('.license-us-why').on 'click', @licenseUSWhy
    $parent.find('.jamtrack-detail-btn').on 'click', @toggleExpanded
    $parent.find('.jamtrack-variant-help').on 'click', @showVariantHelp
    $parent.find('.jamtrack-upgrade-help').on 'click', @showUpgradeHelp

  showVariantHelp: (e) ->
    $screen = $('#jamtrackSearch')
    e.preventDefault()
    context.JK.HelpBubbleHelper.jamtrackVariants($(e.target), $screen)

  showUpgradeHelp: (e) ->
    $screen = $('#jamtrackSearch')
    e.preventDefault()
    context.JK.HelpBubbleHelper.jamtrackUpgrade($(e.target), $screen)

  toggleExpanded:(e) ->
    e.preventDefault()
    jamtrackRecord = $(e.target).parents('.jamtrack-record')
    @handleExpanded(jamtrackRecord)

  handleExpanded:(trackElement) ->
    jamTrack = trackElement.data('jamTrack')
    expanded = trackElement.data('expanded')
    expand = !expanded
    trackElement.data('expanded', expand)

    detailArrow = trackElement.find('.jamtrack-detail-btn')

    if expand
      trackElement.find('.extra').removeClass('hidden')
      detailArrow.html('hide tracks <a class="details-arrow arrow-up"></a>')
      for track in jamTrack.tracks
        trackElement.find("[data-jamtrack-track-id='#{track.id}']").removeClass('hidden')
    else
      trackElement.find('.extra').addClass('hidden')
      detailArrow.html('show all tracks <a class="details-arrow arrow-down"></a>')
      count = 0
      for track in jamTrack.tracks
        if count < 6
          trackElement.find("[data-jamtrack-track-id='#{track.id}']").removeClass('hidden')
        else
          trackElement.find("[data-jamtrack-track-id='#{track.id}']").addClass('hidden')
        count++


  afterShow: (data) ->

    @setFilterFromURL()

  setFilterFromURL:()  ->

    performSearch = false
    if $.QueryString['artist']?
      performSearch = true
      @search('artist-select', $.QueryString['artist'])
    else if $.QueryString['song']?
      performSearch = true
      @search('song-select', $.QueryString['song'])
    else if $.QueryString['search']?
      performSearch = true
      @search('user-input', $.QueryString['search'])
    else
      # check if someone has requested a search for us as we transition to this screen
      search = context.JamTrackStore.checkRequestedSearch()
      if search?
        performSearch = true
        @search(search.searchType, search.searchData)
      else
        if !@state.first_search
          @search(@state.type, window.JamTrackSearchInput)

    if performSearch
      if window.history.replaceState #ie9 proofing
        window.history.replaceState({}, "", "/client#/jamtrack/search")


  beforeShow: () ->

  onAppInit: (@app) ->

    window.JamTrackSearchInput = '' # need to be not null; otherwise react-select chokes
    @EVENTS = context.JK.EVENTS
    @rest = context.JK.Rest()
    @logger = context.JK.logger

    screenBindings =
      'beforeShow': @beforeShow
      'afterShow': @afterShow

    @app.bindScreen('jamtrack/search', screenBindings)

  onUserChanged: (userState) ->
    @user = userState?.user
    @setState({is_free: @user?.show_free_jamtrack})

})