Given(
  /^I have existing Physical Product data for (label|subaccount) (\d+) for all fields$/
) do |account_type, account_id|
  @product_data = DataHelpers::PhysicalProductMetadata.new(
    account_type: account_type.to_sym,
    account_id: account_id.to_i
  )
  product_data = @product_data.data
  puts "product name: #{product_data[:product_name]}"
  puts "product code: #{product_data[:product_code]}"
  puts "product upc: #{product_data[:upc]}"
end

When(/^I delete any existing goals$/) do
  on(Project::PhysicalProductGoalsPage).delete_all_goals
end

When(/^I add release basics to the Physical Product(| using an orchard generated UPC)$/) do |orch_upc|
  on(Project::CreatePhysicalProductPage) do |page|
    @product_data.add_configuration_mapping_fields
    if orch_upc == ""
      page.populate_physical_product_fields(@product_data.data)
    else
      page.populate_physical_product_fields(@product_data.data, false)
    end
    sleep 2 # no idea why this is necessary
    page.save
  end
  if on(Project::CreatePhysicalProductPage).error?
    fail "Validation errors! Refer to screenshot."
  end
  on(Project::PhysicalProductGoalsPage) do |page|
    page.goals_header_element.when_present(90)
  end
end

When(/^I add release basics to the Physical Product without saving$/) do
  on(Project::CreatePhysicalProductPage) do |page|
    @product_data.add_configuration_mapping_fields
    page.populate_physical_product_fields(@product_data.data)
  end
end

When(/^I go to the sales goals section$/) do
  on(Project::PhysicalProductDetailsPage).navigate_to_goals_element.click
  on(Project::PhysicalProductGoalsPage).goals_header_element.when_present
end

When(/^I go to the details section$/) do
  on(Project::PhysicalProductDetailsPage).navigate_to_details_element.click
end

When(/^I change my orchard pricing to CD Tier 2$/) do
  @prior_pricing = on(Project::CreatePhysicalProductPage).us_pricing_code
  on(Project::CreatePhysicalProductPage).select_orchard_pricing "CD Tier #2"
end

When(/^I enter a goal of (.*) for store number (.*)$/) do |goal_number, store_number|
  on(Project::PhysicalProductGoalsPage) do |page|
    page.goal_input_elements[store_number.to_i - 1].clear
    page.goal_input_elements[store_number.to_i - 1].send_keys goal_number
  end
end

When(/^I edit my goals$/) do
  on(Project::PhysicalProductGoalsPage) do |page|
    page.edit_goal_elements[0].click
    existing_value = page.goal_input_elements[0].value.to_i
    page.goal_input_elements[0].clear
    @edit_goal_value = existing_value > 1 ? existing_value - 1 : existing_value + 1
    page.goal_input_elements[0].send_keys @edit_goal_value
    page.save_goal
    page.goals_header_element.when_present
  end
end

When(/^I select United States as a target market$/) do
  on(Project::PhysicalProductGoalsPage) do |page|
    page.select_target_markets("United States")
  end
end

When(/^I save my sales goal$/) do
  on(Project::PhysicalProductGoalsPage).save_goal
  on(Project::PhysicalProductGoalsPage).goals_header_element.when_present
end

When(/^I click edit on the first target market goal$/) do
  on(Project::PhysicalProductGoalsPage).edit_goal_elements[0].click
end

When(/^I add empty release basics to the Physical Product$/) do
  on(Project::CreatePhysicalProductPage) do |page|
    # page doesn't save unless artist data is present.
    page.wait_until { page.primary_artist != "" }
    page.save
  end
end

When(/^I click edit goals$/) do
  on(Project::PhysicalProductReviewPage).edit_goals
  on(Project::PhysicalProductGoalsPage).goals_header_element.when_present
end

Then(/^I should not see any delete goal elements$/) do
  expect(on(Project::PhysicalProductGoalsPage).delete_goal_elements.any?).to be false
end

Then(/^I should not see the target market dropdown$/) do
  expect(on(Project::PhysicalProductGoalsPage).target_market_dropdown?).to be false
end

Then(/^I should see that the first week estimate field is disabled$/) do
  expect(on(Project::PhysicalProductGoalsPage).first_week_estimate_element.disabled?).to be true
end

Then(/^I should see that my target goal input elements are disabled$/) do
  on(Project::PhysicalProductGoalsPage) do |page|
    page.goal_input_elements.each { |goal| expect(goal.disabled?).to be true }
    page.dist_elements.each { |goal| expect(goal.disabled?).to be true }
  end
end

Then(/^I should see no goal values on the page$/) do
  eventually(timeout: 10) do
    expect(on(Project::PhysicalProductGoalsPage).goal_value_elements.any?).to be false
  end
end

Then(/^I should see a validation error message on the physical product form$/) do
  on(Project::CreatePhysicalProductPage) do |page|
    page.wait_until { page.error_element.exists? }
    expect(page.error?).to be true
  end
end

Then(/^I should see a total of (.*) sales goals$/) do |expected_total|
  expect(on(Project::PhysicalProductGoalsPage).goal_input_elements[-1].value).to eql expected_total
end

Then(/^my totals should reflect my edits$/) do
  on(Project::PhysicalProductGoalsPage) do |page|
    page.edit_goal_elements[0].click
    expect(page.goal_input_elements[-1].value.to_i).to eql @edit_goal_value
  end
end

Then(/^I should see a total of (.*) sales goals in review$/) do |expected_total|
  expect(on(Project::PhysicalProductReviewPage).review_goals_total_element.text).to eql expected_total
end

Then(/^I should be on tracklist page$/) do
  on(Project::PhysicalProductTrackPage) do |page|
    page.wait_until { page.track_list_header? }
    expect(page.track_list_header).to eql "Tracklist"
  end
end

Then(/^I should see all distribution fields are disabled$/) do
  on(Project::PhysicalProductGoalsPage).dist_elements.each { |field| expect(field.disabled?).to be true }
end

Then(/^I should be able to add and delete track to the product$/) do
  on(Project::PhysicalProductTrackPage) do |page|
    page.wait_until { page.add_track? }
    sleep 1
    page.add_track
    @track_data = DataHelpers::Product.new(label_type: "label").fresh_track_metadata
    page.populate_required_track_fields(0, @track_data[0])
    page.add_track
    page.populate_required_track_fields(1, @track_data[1])
    page.track[0].remove
    page.yes_delete
    expect(page.track[0].track_name).to eql @track_data[1][:track_name]
    page.populate_required_track_fields(0, @track_data[0])
    page.save_and_continue
  end
end

When(/^I add a track to the product$/) do
  on(Project::PhysicalProductTrackPage) do |page|
    @browser.alert.ok if @browser.alert.exists?
    page.wait_until { page.add_track? }
    sleep 1
    page.add_track
    @track_data = DataHelpers::Product.new(label_type: "label").fresh_track_metadata
    page.populate_required_track_fields(0, @track_data[0])
    page.save_and_continue
  end
  on(Project::ProductTerritoryRestrictionsPage) do |page|
    # otherwise artwork element doesnt work for some reason
    page.territory_restrictions_header_element.when_present
  end
end

Then(/^I should be on carve out Territory Restrictions page$/) do
  on(Project::ProductTerritoryRestrictionsPage) do |page|
    page.wait_until { page.territory_restrictions_header? }
    expect(page.territory_restrictions_header).to eql "Territory Restrictions"
  end
end

When(/^I go to the review section$/) do
  on(Project::PhysicalProductDetailsPage) do |page|
    Retriable.retriable(on: [RSpec::Expectations::ExpectationNotMetError,
                             Selenium::WebDriver::Error::UnknownError], tries: 3) do
      page.navigate_to_review_element.click
      eventually(timeout: 15) do
        expect(page.navigate_to_review_element.attribute_value("class").include?(
                 "ProductBuildSteps-active-item"
        )).to be true
      end
    end
  end
end

When(/^I go to the physical product tracks section$/) do
  sleep 0.50
  on(Project::PhysicalProductDetailsPage).navigate_to_tracklist_element.click
end

Then(/^I see the correct physical release basics$/) do
  # Retries grabbing release_details_values since some fields take a bit longer to populate
  Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 3) do
    release_details_values = on(Project::PhysicalProductReviewPage).release_details_values(
      only_for: @product_data.fields
    )
    @product_data.data.delete(:product_version)
    @product_data.data.delete(:version_notes)
    eventually(timeout: 5) do
      expect(release_details_values).to match @product_data.data
    end
  end
end

Then(/^I see the correct physical release basics with an orchard generated UPC$/) do
  @product_data.data.delete(:product_version)
  @product_data.data.delete(:version_notes)
  eventually(timeout: 5) do
    release_details_values = on(Project::PhysicalProductReviewPage).release_details_values(
      only_for: @product_data.fields
    )
    expect(release_details_values[:upc].to_i.is_a?(Integer)).to be true
    release_details_values.delete(:upc)
    @product_data.data.delete(:upc)
    expect(release_details_values).to match @product_data.data
  end
end

When(/^I submit the product for approval$/) do
  on(Project::PhysicalProductReviewPage) do |page|
    page.wait_for_page_to_scroll_to_top
    page.artwork_element.when_present
    page.submit
    page.confirm_submit_element.when_present.click
    page.product_status_submitted_element.when_present
    expect(page.product_status_submitted).to eql "Your product has been submitted and is awaiting approval."
  end
  @upc = @product_data.data[:upc] # used by approval steps
end

Given(/^I am on the Project::ProjectDetailsPage for the project$/) do
  visit(
    Project::ProjectDetailsPage,
    using_params: {
      project_id: @project_id,
      queries: @url_queries
    }
  )
end

Given(/^I have an existing physical product on (QA|Production)$/) do |_|
  @project_id = 3_501_773
  @product_id = 1_916_480
end

Given(/^I have an existing physical product on (QA|Production) from which I can delete Sales Goals$/) do |_|
  @project_id = 3_501_773
  @product_id = 2_195_179
end

Given(/^I have an existing delivered physical product from which I can edit Sales Goals$/) do
  @project_id = 3_886_616
  @product_id = 2_251_200
end

Given(/^I have an existing completed physical product on (QA|Production)$/) do |_|
  @project_id = 3_482_981
  @product_id = 1_926_393
end

Given(/^I have an existing physical product from which I can edit Tracks$/) do
  @project_id = 3_966_651
  @product_id = 2_366_254
end

Then(/^the product should be in content$/) do
  query = "SELECT release_status FROM releases WHERE release_id = #{@product_id};"
  Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 10, base_interval: 5) do
    release_status = Support::DbClient.query_art_relations(query).first["release_status"]
    expect(release_status). to eq("in_content")
  end
end

Then(/^my US pricing code should change$/) do
  expect(@prior_pricing).not_to eq(on(Project::CreatePhysicalProductPage).us_pricing_code)
end

Then(/^I can see my expected track data on the summary page$/) do
  on(Project::PhysicalProductReviewPage) do |page|
    eventually(timeout: 5) do
      expect(page.track_number_element.text).to eq @track_data[0][:track_number]
      expect(page.track_name_element.text).to eq @track_data[0][:track_name]
      expect(page.track_artist_element.text).to eq @track_data[0][:track_artist]
      expect(page.track_length_element.text).to eq @track_data[0][:track_length]
      expect(page.track_side_element.text).to eq @track_data[0][:track_side]
      expect(page.track_disc_element.text).to eq @track_data[0][:track_disc]
      expect(page.track_isrc_element.text).to eq @track_data[0][:track_isrc]
    end
  end
end

When(/^I delete the product$/) do
  on(Project::PhysicalProductDetailsPage) do |page|
    page.product_more_actions_element.click
    page.delete_product_option_element.when_present.click
    page.confirm_delete_element.when_present.click
  end
end

When(/^I should not see the product in the sidebar$/) do
  on(Project::PhysicalProductDetailsPage) do |page|
    # this check fails with CUCUMBER_PROFILE=grid because the message disappears quicker
    # than the check is triggered
    # expect(page.product_status_deleted).to eql "You have successfully deleted the product."
    eventually(timeout: 15) do
      expect(page.sidebar_product_more_actions_elements.any?).to be false
    end
  end
end

Given(/^I am on the Project::PhysicalProductTrackPage for a newly\-created physical product$/) do
  step "I am on the Project::ProjectDetailsPage for a newly created project"
  step "I add a product to the project"
  step "I select physical audio as the product type"
  step "I submit the physical audio product landing page form"
  step "I add release basics to the Physical Product"
  step "I add a first week estimate projection of 1 for United States"
  on(Project::PhysicalProductTrackPage) do |page|
    page.add_track_element.when_present
    @product_id = page.product_id_from_url
  end
end

Given(
  /^I am on the Project::PhysicalProductReviewPage for a newly\-created submitted physical product$/
) do
  step "I am on the Project::PhysicalProductTrackPage for a newly-created physical product"
  step "I add a track to the product"
  step "I go to the physical product artwork section"
  step "I upload valid artwork"
  step "I go to the review section"
  step "I submit the product for approval"
end

Given(/^I have a new project and physical product for label (.*)$/) do |label_id|
  step "I have a new project"
  new_product_dict = Support::Helpers::ProductDataTransformer.prep_data_for_api_sumbit(
    @product_data.data, @project_id
  )
  session_token = Support::Services::GrassAuth.instance.workstation_session_token("label_" + label_id)
  product_response = Support::Services::OwsProductPhysical.create_product(
    session_token, new_product_dict
  )
  @upc = product_response["display_upc"]
  @product_id = product_response["product_id"]
  @product_data.add_configuration_mapping_fields
end

Given(/^I add a first week estimate projection of (\d+) for (.*?)$/) do |projections, target_market|
  on(Project::PhysicalProductGoalsPage) do |page|
    page.wait_until { page.target_market_dropdown? }
    page.select_target_market_dropdown target_market
    expect(page.target_country_name_element.when_present.text).to eql target_market
    page.first_week_estimate = projections
    page.save_sales_estimate
    expect(page.target_goal_item_element.when_present.text.include?(target_market)).to be true
    page.save_and_continue
  end
end

When(/^I submit the physical product$/) do
  on(Project::PhysicalProductReviewPage) do |page|
    page.wait_for_page_to_scroll_to_top
    page.artwork_element.when_present
    page.submit
    page.confirm_submit_element.when_present.click
    page.product_status_submitted_element.when_present
  end
end

Then(/^I see that the product is submitted$/) do
  on(Project::PhysicalProductReviewPage) do |page|
    expect(page.product_status_submitted).to eql "Your product has been submitted and is awaiting approval."
  end
end
