Then(/^I see that the engagement page works$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until { page.filters_element.present? }
    expect(page.filters_element.present?).to be true
    expect(page.listened_element.present?).to be true
    expect(page.graph_element.present?).to be true
    expect(page.placements_element.present?).to be true
  end
end
Then(/^the engagement table should be populated$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    eventually(timeout: 20) do
      if @users.source_of_streams_user.feature_variance_enabled? "engagement_skips_saves"
        expect(page.total_streams_ff.present?).to be true
        expect(page.listeners_collection_ff.present?).to be true
        expect(page.active_discovery_ff.present?).to be true
        expect(page.passive_discovery_ff.present?).to be true
      else
        expect(page.total_streams).not_to eq("NAN")
        expect(page.listeners_collection).not_to eq("NAN")
        expect(page.active_discovery).not_to eq("NAN")
        expect(page.passive_discovery).not_to eq("NAN")
        expect(page.total_streams).not_to eq("-")
        expect(page.listeners_collection).not_to eq("-")
        expect(page.active_discovery).not_to eq("-")
        expect(page.passive_discovery).not_to eq("-")
      end
      expect(page.playlist_row_elements.empty?).to be false
    end
  end
end

Then(/^the engagement graph and table should not load$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    # Source of streams is now enabled for everyone, users with no data should not see any.
    expect(page.current_url).to eql(DOMAINS[:workstation] + "/analytics/engagement")
    if @users.workstation_user.feature_variance_enabled? "engagement_skips_saves"
      page.wait_until(15) { page.no_streams_element.present? }
    else
      eventually(timeout: 15) { expect(page.total_streams).to eql("0") }
    end
    expect(page.placements_no_data).to include("No top placements for this period")
  end
end

When(/^I toggle search for (track|artist) in Engagement page$/) do |search_type|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until { page.filters }
    return if page.artist_track_search_toggle_element.text.split("\n").first.downcase == search_type
    page.artist_track_search_toggle_element.click
    if search_type == "track"
      page.tracks_search_toggle_element.click
    elsif search_type == "artist"
      page.artist_search_toggle_element.click
    end
  end
end

Then(/^I search the engagement page for the (.*?) (track|artist)$/) do |search_val, search_type|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    step("I toggle search for #{search_type} in Engagement page")

    if @users.workstation_user
      # legacy test
      @original_streams = if @users.workstation_user.feature_variance_enabled? "engagement_skips_saves"
                            page.total_streams_ff
                          else
                            page.total_streams
                          end
    elsif @users.source_of_streams_user.feature_variance_enabled? "engagement_skips_saves"
      # standalone test
      @original_streams = page.total_streams_ff
    else
      @original_streams = page.total_streams
    end

    page.throttled_input(page.search_input_element, search_val)
    retype = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.search_input_element.send_keys :backspace
      page.send_keys(search_val[-1])
    end
    Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 2, on_retry: retype) do
      eventually(timeout: 15) { expect(page.first_search_result).to include(search_val) }
    end
    page.search_results_element.element.click
  end
end

And(/^I remove a track search from the Engagement page/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.search_input_element.send_keys(:backspace)
  end
end

Then(/^I should see fewer streams in Engagement page$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    if @users.workstation_user
      # legacy test
      current_streams = if @users.workstation_user.feature_variance_enabled? "engagement_skips_saves"
                          page.total_streams_ff
                        else
                          page.total_streams
                        end
    else
      # standalone test
      current_streams = if @users.source_of_streams_user.feature_variance_enabled? "engagement_skips_saves"
                          page.total_streams_ff
                        else
                          page.total_streams
                        end
    end
    expect(@original_streams > current_streams)
  end
end

Then(/^I should see (.*?) in the search field in Engagement page$/) do |query|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    expect(page.search_container).to include query.strip
  end
end

Then(/^in Engagement page I should not see either (.*?) or (.*?) in the search field$/) do |track, track2|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    expect(page.search_container).not_to include track
    expect(page.search_container).not_to include track2
  end
end

And(/I select the (.*?) graph filter in Engagement page$/) do |filter|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    @start = Time.now.to_i
    page.send("#{filter}_toggle_element").parent.click
    page.wait_until(20) { !page.loading_indicator_dot_element.present? }
  end
end

Then(/^the search bar text should be "(.*?)" in Engagement page$/) do |expected_text|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    expect(page.search_placeholder_text_element.text).to include(expected_text)
  end
end

And(/^I select the artist of a filtered placements tile in Engagement page$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until(30) { !page.loading_indicator_dot_element.present? }
    page.wait_until(30) do
      page.placements_tile_element.p_element(class: "PlacementsTile-track-title-and-artist").present?
    end
    page.wait_until(30) { !page.placement_tile_track_elements.empty? }
    page.wait_until(30) { page.placement_tile_track_div_elements.first.present? }
    puts page.placement_tile_track_div_elements.first.text
    page.placement_tile_artist_name_elements.first.scroll.to
    page.placement_tile_artist_name_element.click
  end
end

And(/^I select a random playlist placements marker in Engagement page$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    # select a random playlist placement marker
    page.wait_until(30) { !page.playlist_placement_marker_elements.empty? }
    expect(page.playlist_placement_marker_elements.length).to be > 0
    # placement markers render before the count is added to them in the dom
    # due to not knowing the data we're waiting in before grabbing them to give
    # them a chance to load.
    page.wait_until { page.playlist_placement_marker_elements.any? { |spotify| !spotify.text.empty? } }
    page.playlist_placement_marker_elements.first.wait_until(&:present?)
    marker = page.playlist_placement_marker_elements.sample
    @playlist_count = marker.text.to_i
    page.click_with_javascript(marker)
  end
end

Then(/^in Engagement page the placements table should contain the correct amount of placements$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    # Placements table has a header row which is annoyingly counted
    puts @playlist_count
    if @playlist_count > 0
      expect(page.playlist_placements_table_element.rows - 1).to eql(@playlist_count)
    else
      expect(page.playlist_placements_table_element.rows).to eql(2)
    end
    puts(page.playlist_placements_table_element.rows)
  end
end

Then(/in Engagement page the filtered placements table contains data$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    # length of the table headers is 1
    page.wait_until(10) { page.playlist_placements_elements.length > 1 }
  end
end

And(/^I get the number of placements after adding the (first|second) track in Engagement page$/) do |round|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until(30) { page.playlist_placements_container_wrapper_element.h2.text.include?("of") }
    puts page.playlist_placements_container_wrapper_element.h2.text
    if round == "first"
      @first_placements = page.playlist_placements_container_wrapper_element.h2.text
      @first_placements.slice!("Top")
      of_index = @first_placements.index("of")
      @first_placements.slice!(of_index..@first_placements.length)
    else
      second_placements = page.playlist_placements_container_wrapper_element.h2.text
      second_placements.slice!("Top")
      of_index = second_placements.index("of")
      second_placements.slice!(of_index..second_placements.length)
      second_placement_value = (@first_placements.to_i - second_placements.to_i).abs
      expect(@first_placements.to_i + second_placement_value).to eq(second_placements.to_i)
    end
  end
end

Then(/^The playlist placements totals should have subtracted correctly in Engagement page$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until(30) { page.playlist_placements_container_wrapper_element.h2.text.include?("of") }
    puts page.playlist_placements_container_wrapper_element.span.text
    final_placements = page.playlist_placements_container_wrapper_element.h2.text
    final_placements.slice!("Top")
    of_index = final_placements.index("of")
    final_placements.slice!(of_index..final_placements.length)
    puts final_placements
    puts @first_placements
    expect(final_placements).to eq(@first_placements)
  end
end

Then(/^in Engagement page the placement tiles should contain the track (.*)$/) do |expected_track_title|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    step("in Engagement page the placement tiles have loaded")
    track_titles = []
    page.placement_tile_track_title_elements.each do |track_title|
      track_titles.push(track_title.text.delete("\""))
    end
    expect(track_titles.include?(expected_track_title)).to be true
  end
end

Then(/^in Engagement page the placement tiles should contain the artist (.*)$/) do |expected_artist_name|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    step("in Engagement page the placement tiles have loaded")
    artist_names = []
    page.placement_tile_artist_name_elements.each do |artist_name|
      artist_names.push(artist_name.text.delete("\""))
    end
    expect(artist_names.include?(expected_artist_name)).to be true
  end
end

Then(/^in Engagement page the placement tiles should contain background images$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.placement_tile_background_image_elements.each do |tile_image|
      page.wait_until(60, "Background images did not load") { !tile_image.style.empty? }
      style = tile_image.style
      expect(style.include?("background-image")).to be true
    end
  end
end

Then(/^in Engagement page the placement tiles should contain followers$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.placement_tile_followers_elements.each do |followers|
      # TODO: create more distinct classes for the info section in fe sos
      expect(followers.parent.b_element.text).to be_truthy
    end
  end
end

And(/^in Engagement page the placement tiles have loaded$/) do
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.loading_indicator_dot_element.when_not_present
    page.wait_until { page.placement_tile_track_elements.any? }
  end
end

When(/^in Engagement page I set the date filter to (.*)$/) do |date_range|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.click_date_filter
    case date_range
    when "last year"
      page.last_year_filter_element.click
    when "last month"
      page.last_month_filter_element.click
    when "last week"
      page.last_week_filter_element.click
    end
  end
end
# rubocop:disable Metrics/LineLength
When(/^I set the dates from (\d{4}-\d{2}-\d{2}) to (\d{4}-\d{2}-\d{2}) in Engagement page$/) do |from_date, to_date|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until { page.placement_tile_track_div_elements.any? }
    page.click_date_filter
    page.custom_range_filter_element.when_present.click
    page.set_the_date("start", from_date)
    page.set_the_date("end", to_date)
    page.custom_done_element.click
  end
end

When(/^in Engagement page I get the (streams|saves|listeners collection|active discovery|passive discovery) count$/) do |entity|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    page.wait_until { page.total_streams_ff.present? }
    case entity
    when "streams"
      start_value = page.total_streams_ff
    when "saves"
      start_value = page.total_saves
    when "listeners collection"
      start_value = page.listeners_collection_ff
    when "active discovery"
      start_value = page.active_discovery_ff
    when "passive discovery"
      start_value = page.passive_discovery_ff
    end

    multiplier = Support::Helpers::Multiplier.parse(start_value)
    start_value = start_value[0..-1] if start_value.include?(".")
    start_value = start_value.to_f * multiplier.to_f

    @start_values = {} unless @start_values
    @start_values[entity] = start_value
    puts "#{entity} start value equals to : #{start_value}"
  end
end
# rubocop:enable Metrics/LineLength

Then(
  /^in Engagement page (streams|saves|listeners collection|active discovery|passive discovery) decreases$/
) do |entity|
  on(ReactWorkstation::ReactEngagementPage) do |page|
    case entity
    when "streams"
      end_value = page.total_streams_ff
    when "saves"
      end_value = page.total_saves
    when "listeners collection"
      end_value = page.listeners_collection_ff
    when "active discovery"
      end_value = page.active_discovery_ff
    when "passive discovery"
      end_value = page.passive_discovery_ff
    end

    multiplier = Support::Helpers::Multiplier.parse(end_value)
    end_value = end_value[0..-1] if end_value.include?(".")
    end_value = end_value.to_f * multiplier.to_f
    puts "#{entity} end value equals to : #{end_value}"

    start_value = @start_values[entity]
    expect(start_value).to be > end_value
  end
end
