Given(/^I have a digital product I wish to approve$/) do
  @product_id = 2_200_917
  @upc = "192562102152"
end

Given(/^my product has error corrections$/) do
  step "I delete all rejection and release data associated with my product"
  session_token = Support::Services::GrassAuth.instance.workstation_session_token("label_7123")
  release_correction_id = Support::Services::OwsProductDigital.create_correction(
    @product_id, session_token
  )["release_correction_id"]
  Support::Services::OwsProductDigital.create_correction_details(
    @product_id, release_correction_id, session_token
  )
  Support::Services::OwsProductDigital.submit_product(@product_id, session_token)
end

Then(/^I can access the release approval checkout page$/) do
  on(OA::RelationshipsPage).release_approval_link
  on(OA::CheckOutReleasePage) do |page|
    page.expect_to_be_on_page
    expect(page.release_approval_heading?).to be true
  end
end

When(/^I check out the (product|release)$/) do |_|
  on(OA::CheckOutReleasePage) do |page|
    page.results_element[@upc].label_element.click
    page.click_with_javascript(page.check_out_releases_element)
  end
end

Then(/^I am on the release approval page$/) do
  on(OA::ReleaseApprovalPage) do |page|
    expect(page.approval_heading).to eql "Release Approval"
  end
end

Then(/^I approve the (product|release)$/) do |_|
  # TODO: figure out what this is actually dependent on. can't find a feature flag
  use_approval_comments = false
  on(OA::ReleaseApprovalPage) do |page|
    page.approve_checkbox_element.scroll.to
    js_click = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.click_with_javascript(page.approve_checkbox_element)
    end
    Retriable.retriable(on: Selenium::WebDriver::Error::UnknownError, tries: 2, on_retry: js_click) do
      page.check_approve_checkbox
    end
    if use_approval_comments
      page.approve_and_confirm("Watir Default Reason")
    else
      page.ensure_approve_enabled
      page.approve
    end
  end
end

When(/^I confirm that the release is not for distribution$/) do
  on(OA::ReleaseApprovalPage) do |page|
    retry_approve = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.approve
    end
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 2, on_retry: retry_approve) do
      page.confirm_not_for_distribution_element.when_present(5).click unless page.physical_product?
    end
  end
end

# 2018-05-17 This shouldn't be needed anymore after this commit:
# https://github.com/theorchard/cucumber_tests/pull/1091/files#diff-5476d2779259ed92dedfb955126c36ee
# Get rid of this if passing consistently
When(/^I wait for the approval to submit$/) do
  # Retries checkout when a race condition doesn't register the release as checked out
  # retry_checkout = proc do |exception, try|
  #   puts "#{exception.class}: '#{exception.message}' - Retries: #{try}"
  #   step "I look for the release in Release Approval"
  #   step "I check out the release"
  #   step "I approve the release"
  #   step "I confirm that the release is not for distribution"
  # end
  on(OA::ReleaseApprovalPage).approve_element.element.wait_while(timeout: 45, &:present?)
end

Then(/^the release should be in content$/) do
  visit(OA::ViewReleasePage, using_params: { queries: { "upc" => @upc } }) do |page|
    page_refresh = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.refresh
      sleep 3
    end
    Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 5, on_retry: page_refresh) do
      expect(page.release_status?).to be true
    end
    expect(page.release_status).to eql "in_content"
  end
end

Given(/^the release (\d+) is not checked out$/) do |upc|
  upc = upc.to_s
  query = "SELECT release_id FROM releases WHERE display_upc = '#{upc}'"
  release_id = Support::DbClient.query_art_relations(query).first["release_id"]
  query = "SELECT * FROM release_approval_queue WHERE release_id = '#{release_id}'"
  releases_in_queue = Support::DbClient.query_art_relations(query)
  if releases_in_queue.any? { |row| row["status"] == "checked_out" }
    user_id = releases_in_queue.find { |row| row["status"] == "checked_out" }["checked_out_by"]
    visit(OA::CheckedOutReleasesPage, using_params: { user_id: user_id }) do |page|
      puts "Checking in product with UPC #{upc} under user with user_id #{user_id}"
      page.loader_element.when_not_present(15)
      page.click_with_javascript(page.select_all_element)
      expect(page.select_all_checked?).to be false
      release_to_check_in = page.table_element(class: "table").find do |row|
        row.text.include? upc
      end
      page.click_with_javascript(release_to_check_in.checkbox_element)
      page.check_in_releases if page.check_in_releases?
      page.loader_element.wait_while(&:present?)
      page.wait_until { !release_to_check_in.present? }
    end
  end
end

When(/^I check out release (\d+)$/) do |upc|
  visit(OA::CheckOutReleasePage) do |page|
    page.find_release_by_upc(upc)
    page.select_all_element.element.click
    page.check_out_releases
  end
end

When(/^I reject all fields with comments$/) do
  puts "Release status right before rejecting: #{Support::DbClient.current_release_status(@product_id)}"
  on(OA::ReleaseApprovalPage) do |page|
    page.artwork_element.click
    page.release_name_element.click
    page.release_date_element.click
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 3) do
      page.track_name_element.click
      page.wait_until(1) do
        page.track_name_element.attribute_value("class").include? "error-rejection-field"
      end
    end
    page.artwork_rejection_comments = "bad artwork"
    page.general_rejection_comments = "bad general comment"
    page.release_name_rejection_comments = "bad release name"
    page.release_date_rejection_comments = "bad release date"
    page.track_name_rejection_comments = "bad track name"
    page.reject
  end
end

When(/^I reject all fields with comments via DB$/) do
  query = "SELECT release_status FROM releases WHERE release_id = #{@product_id};"
  if Support::DbClient.query_art_relations(query).first["release_status"] == "transfer_to_content"
    release_approval_id = Support::Helpers::Queries.release_approval_id @product_id
    Support::Helpers::Queries.release_label_processing @product_id
    Support::Helpers::Queries.reject_release release_approval_id
    track_id = Support::Helpers::Queries.track_id @product_id
    Support::Helpers::Queries.create_rejection_note(release_approval_id, "releases",
                                                    "artwork", "bad artwork", 0)
    Support::Helpers::Queries.create_rejection_note(release_approval_id, "releases", "release_name",
                                                    "bad release name", 0)
    Support::Helpers::Queries.create_rejection_note(release_approval_id, "releases", "release_date",
                                                    "bad release date", 0)
    Support::Helpers::Queries.create_rejection_note(release_approval_id, "track", "track_name",
                                                    "bad track name", track_id)
    Support::Helpers::Queries.create_rejection_note(release_approval_id, "releases",
                                                    "general_comments",
                                                    "bad general comment", 0)
  end
end

Then %r{I see an error message saying it failed Orchard/Sony validation} do
  on(OA::ReleaseApprovalPage) do |page|
    sony_validation_message = "THIS RELEASE FAILED THE ORCHARD/SONY DATABASE VALIDATION"
    expect(page.sony_validation_message).to include sony_validation_message
  end
end

Then(/^I should see warning banner of "(.*)"$/) do |expected_warning|
  on(OA::ReleaseApprovalPage) do |page|
    page.hidden_artist_warning_element.wait_until(&:present?)
    expect(page.hidden_artist_warning.downcase).to include(expected_warning.downcase)
  end
end

Then(/^I should be on the check out releases page$/) do
  eventually do
    expect(on(OA::CheckOutReleasePage).upc_element.present?).to be true
  end
end

Then(/^the product name matches my new product name$/) do
  expect(on(OA::ReleaseApprovalPage).product_name.strip).to eq @product_name
end

When(/^I add (.*?) as a priority territory on OA$/) do |territory_name|
  on(OA::ReleaseApprovalPage) do |page|
    page.edit_marketing_when_available
    page.add_priority_territory territory_name
  end
end

When(/^I enter and save projections and priority for the territory on OA$/) do
  on(OA::ReleaseApprovalPage) do |page|
    # convert to_i to remove possible leading zeros
    @value = Time.stamp.slice(11..16).to_i.to_s
    @percent_value = rand(1...99)
    page.spotify_global = @value
    page.apple_global = @value
    page.other_global = @value
    page.downloads_global = @value
    page.spotify_value_elements[1].send_keys @percent_value
    page.apple_value_elements[1].send_keys @percent_value
    page.downloads_value_elements[1].send_keys @percent_value
    page.other_value_elements[1].send_keys @percent_value
    page.marketing_priority = "A"
    page.save_marketing
  end
end

Then(/^I should see my highlight data in OA$/) do
  on(OA::ReleaseApprovalPage) do |page|
    page.edit_marketing_when_available
    expect(page.spotify_global).to eql @value
    expect(page.apple_global).to eql @value
    expect(page.other_global).to eql @value
    expect(page.downloads_global).to eql @value

    expect(page.spotify_value_elements[1].value).to eql @percent_value.to_s
    expect(page.apple_value_elements[1].value).to eql @percent_value.to_s
    expect(page.downloads_value_elements[1].value).to eql @percent_value.to_s
    expect(page.other_value_elements[1].value).to eql @percent_value.to_s

    expect(page.marketing_priority_element.text).to eql "A"
  end
end

When(/^I delete my highlight projections in OA$/) do
  on(OA::ReleaseApprovalPage) do |page|
    page.edit_marketing_when_available
    page.wait_for_projection_data
    page.delete_region_highlights_elements[0].when_present.click
    page.confirm_delete
    begin
      page.wait_until(1) { page.delete_region_highlights_elements.none? }
    rescue Watir::Exception::LocatorException
      puts "Delete buttons disappeared before detection."
    end
  end
end

Then(/^I should not see any highlight projections in OA$/) do
  on(OA::ReleaseApprovalPage) do |page|
    page.edit_marketing_when_available
    page.wait_for_projection_data
    expect(page.delete_region_highlights_elements.none?).to be true
  end
end
