When(/^I view the Analytics Overview page$/) do
  on(Workstation::AnalyticsTopChartsPage).go_to_overview_button
end

Then(/^I should be on the Analytics Overview page$/) do
  # look for any DOM element on this page
  on(Workstation::AnalyticsOverviewPage) do |page|
    expect(page.start_date?).to be_truthy, "Couldn't find an expected element on #{page.class}"
  end
end

Then(/^I should see the overview for this label$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    label_name = @users.workstation_user_data[:vendor_name]
    applied_vendor = page.applied_vendor

    puts "Logged-in label: #{label_name}"
    puts "Applied vendor card: #{applied_vendor}"
    # Compare the label name in the welcome panel (top-right)
    # to the applied vendor card:
    expect(label_name).to eq(applied_vendor)
  end
end

Then(/^I should see "(.*?)" as the active view\-by$/) do |applied_view_by|
  eventually do
    actual_view_by = on(Workstation::AnalyticsOverviewPage).active_view_by_button_element.text.downcase
    expect(actual_view_by).to eql applied_view_by.downcase
  end
end

Then(/^I should see "(.*?)" as the active period$/) do |active_period|
  on(Workstation::AnalyticsOverviewPage) do |page|
    expect(page.active_period_element.text.downcase).to eql(active_period.downcase)
  end
end

Then(/^I should see a (.*?) total of (\d+)$/) do |data_channel, expected|
  actual = on(Workstation::AnalyticsOverviewPage).get_channel_total(data_channel)
  expect(actual).to eq expected.to_i
end

And(/^I select the countries: (.*)$/) do |filters|
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.countries_button
    selected_filters = filters.split(",").map(&:strip)
    page.select_filters("countries", *selected_filters)
  end
end

And(/^I select the sources: (.*)$/) do |filters|
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.sources_button
    selected_filters = filters.split(",").map(&:strip)
    page.select_filters("sources", *selected_filters)
  end
end

When(/^I get the data for (.*) from point (\d+) on the (.*?) chart$/) do |date, chart_point, which_chart|
  on Workstation::AnalyticsOverviewPage do |page|
    reapply = proc do |exception, try|
      Kernel.puts "#{exception.class}: '#{exception.message}' - Attempt: #{try}"
      page.apply
    end
    Retriable.retriable(on: [RSpec::Expectations::ExpectationNotMetError,
                             Watir::Exception::UnknownObjectException,
                             Watir::Wait::TimeoutError], tries: 2, on_retry: reapply) do
      page.wait_until { page.h4_element(text: which_chart).present? }
      expect(page.channel_graph_elements.any? { |x| x.text.include? which_chart }).to be true
      @chart_data = page.point_in_analytics_graph(which_chart, chart_point.to_i)
      puts "date: #{@chart_data[:date]}, sales: #{@chart_data[:sales]}"
      expect(@chart_data[:date]).to include date
    end
  end
end

Then(/^the number of sales for the data point is (.*)$/) do |sales|
  expect(@chart_data[:sales].to_i).to eql sales.to_i
end

Given(/^I view the (.*?) filter$/) do |filter|
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.filter_by(filter)
    page.wait_until { page.send("#{filter}_list_elements").any? }
  end
end

Then(/^I should see at least (\S+?) unique (sources|regions) in the list$/) do |min, filter|
  min = min.to_i
  on(Workstation::AnalyticsOverviewPage) do |page|
    actual = page.send("#{filter}_list_elements").map(&:text)
    unique_elements = actual.uniq

    puts "Actual #{filter} available: #{actual.count}"
    puts "Unique #{filter} available: #{unique_elements.count}"
    expect(unique_elements.count).to be >= min

    begin
      expect(actual).to match_array(unique_elements)
    rescue RSpec::Expectations::ExpectationNotMetError => e
      Kernel.warn "Some non-unique items detected in Analytics #{filter} filter!"
      Kernel.warn e
    end
  end
end

Then(/^the to and from dates in the UI should be correct$/) do
  to_date = Date.today - 2
  @to ||= to_date.strftime("%Y-%m-%d")
  @from ||= (to_date.prev_month + 1).strftime("%Y-%m-%d")
  on(Workstation::AnalyticsOverviewPage) do |page|
    expect(page.start_date_element.value).to eq(@from)
    expect(page.end_date_element.value).to eq(@to)
  end
end

Then(/^the to and from dates in the URL should be correct$/) do
  to_date = Date.today - 2
  @to ||= to_date.strftime("%Y-%m-%d")
  @from ||= (to_date.prev_month + 1).strftime("%Y-%m-%d")
  url = on(Workstation::AnalyticsOverviewPage).current_url
  uri = URI.parse(url) # will parse the Url
  uri_params = CGI.parse(uri.query) # will only parse the Query part of the Url
  url_from_date = uri_params["from_date"].first # will get me the from Date only
  url_to_date = uri_params["to_date"].first # will get me the to Date only

  expect(url_to_date).to eq(@to)
  expect(url_from_date).to eq(@from)
end

When(/^I set the Overview start date to (.*?) and end date to (.*?)$/) do |from, to|
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.unhide_all_channels
    page.start_date = from
    page.end_date = to
  end
  @from = from
  @to = to
end

When(/^I have the top (\d+) performing (products?|artists?|tracks?)$/) do |num, type|
  on(ReactWorkstation::ReactHomePage) do |page|
    @top_items = []
    page.goto unless page.current_url == page.page_url_value
    type.chop! if type[-1] == "s"
    page.select_top_ten(type)
    page.top_ten_loader_element.element.wait_while(&:present?)
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 3) do
      page.wait_until(1) do
        page.top_ten_loader_line_element.element.wait_while(&:present?)
      end
    end
    page.top_ten_item_elements[0..(num.to_i - 1)].each do |title|
      @top_items.push title.text
    end
  end
end

When(/^I filter for the top (products?|artists?|tracks?) in analytics overview$/) do |type|
  visit(Workstation::AnalyticsOverviewPage)
  filter_string = @top_items.map { |x| "\"#{x}\"" }.join(", ")
  step "I filter for #{type}: #{filter_string}"
end

When(/^I filter for (.*?): (.*?)$/) do |filter_type, search_param|
  if filter_type[-1] == "s"
    @filter_singular = filter_type.chop # Make singular
    filter_plural = filter_type
  else
    @filter_singular = filter_type
    filter_plural = filter_type + "s" # Pluralize
  end
  valid = %w[imprints artists tracks genres products projects]
  unless valid.include? filter_plural
    fail "Invalid option: #{filter_plural}. Can only use this step for one of: #{valid}"
  end

  # Split on commas between dub-quotes, then remove any leading/trailing spaces and dub-quotes
  @search_param = search_param.split(/",\s?"/).map { |s| s.strip.chomp('"').reverse.chomp('"').reverse }
  puts "array of desired filters: #{@search_param}"
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.filter_by(filter_plural)
    @search_param.each do |item|
      page.add_something
      page.card_search_box = item.to_s
      page.wait_for_results
      page.wait_until do
        page.result_elements.find { |match| match.element.present? }.text.downcase.include? item.downcase
      end
      # use label element because clicking li element doesnt work in WSR
      page.result_elements.find { |match| match.element.present? }.label_element.click
    end
  end
end

Then(/^I should see my chosen filter applied$/) do
  applied_filters = on(Workstation::AnalyticsOverviewPage)
                    .send("applied_#{@filter_singular}_elements")
                    .map(&:text)
  puts "array of applied filters: #{applied_filters}"
  expect(applied_filters.map(&:downcase)).to match_array(@search_param.map(&:downcase))
end

Given(/^I apply the selected filters$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.apply
    # if you want to wait for graphs to finish loading, then add
    # page.wait_for_any_graph_to_load to the following step
  end
end

Then(/^I should see the correct overview for that artist$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Download Tracks")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

Then(/^I should see the correct overview record displayed for that (.*?)$/) do |record_type|
  on(Workstation::AnalyticsOverviewPage) do |page|
    release_name = page.send("applied_#{record_type}_elements")[0].text.downcase
    case record_type
    when "artist"
      expected = @artist.downcase
    when "project"
      expected = @project.downcase
    when "track"
      expected = @track.downcase
    end
    expect(release_name).to eq expected
  end
end

# Delete for project_manager teardown
Then(/^I should see the correct overview for that release$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Download Albums")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

Then(/^I should see the correct overview for that project$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Download Albums")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

Then(/^I should see the correct overview for that track$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Download Tracks")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

Then(/^I should see the correct overview for that subscription stream/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Subscription Audio Streams")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

Then(/^I should see the correct overview for that ad subscription stream/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    download_total = page.get_channel_total("Ad-Supported Audio Streams")
    puts "Downloads: #{download_total}"
    expect(download_total).to eq @downloads
  end
end

When(/^I change the data channel order$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.div_element(id: "graph_1").wait_until(&:present?)
    page.unhide_all_channels
    @id_of_second_graph_on_load = page.channel_graph_elements[1].attribute("id")
    puts "Second initial graph id: #{@id_of_second_graph_on_load}"
    page.drag_second_graph_to_third_position
    # after moving, get the id of the second graph in the list
    @id_of_second_graph_after_move = page.channel_graph_elements[1].attribute("id")
    puts "After moving the graph id: #{@id_of_second_graph_after_move}"
    # fail the test unless the second graph in the list is different from
    # the second graph when the page loaded
    expect(page.channel_graph_elements[1].attribute("id")).not_to eq(@id_of_second_graph_on_load)
  end
end

Then(/^the channel order should remain same when I revisit$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    page.refresh
    page.wait_until { page.div_element(id: @id_of_second_graph_on_load).present? }
    expect(page.channel_graph_elements[1].attribute("id")).to eq(@id_of_second_graph_after_move)
  end
end

Then(/^the download tracks graph should display correctly on the overview page$/) do
  on(Workstation::AnalyticsOverviewPage) do |page|
    # because clicking back button doesn't wait for page load
    page.wait_until { page.current_url.include? "overview" }
    page.wait_for_any_graph_to_load
    # Next 2 expectations make sure that the graph elements are drawn
    download_tracks_container = page.find_graph_by_name("Download Tracks").div_element(class: "graph-holder")
    # no native tag support for <g class="all-sales">`
    expect(download_tracks_container.element.element(class: "all-sales").present?).to be true
    # no native tag support for <path class="area">
    expect(download_tracks_container.element.element(class: "area").present?).to be true
  end
end

Then(/^I should see the (YouTube Audio and Video Streams|Audio Streams) section$/) do |section_name|
  on(Workstation::AnalyticsOverviewPage) do |page|
    stream_section_name = section_name.downcase.tr(" ", "_")
    page.wait_until { page.send("#{stream_section_name}?") }
    expect(
      page.send("#{stream_section_name}_element").element.element(class: "panel-heading").h3.text
    ).to eq(section_name)
    puts "#{section_name} section is available"
  end
end

Then(/^I see the data channels for (YouTube Audio and Video Streams|Audio Streams) section$/) do |section|
  on(Workstation::AnalyticsOverviewPage) do |page|
    graph_section_name = section.downcase.tr(" ", "_")
    expected_channel_list = page.channel_list(graph_section_name)
    puts expected_channel_list
    page.wait_until { page.send("#{graph_section_name}_section_element").div_elements.any? }
    page.unhide_all_channels
    actual_channel_list = page.send("#{graph_section_name}_section_element")
                              .divs(class: "graph")
                              .map { |channel_block| channel_block.h4.text }
    puts actual_channel_list
    expect(actual_channel_list).to match_array(expected_channel_list)
  end
end
