When(
  /^I populate the digital product landing page form with (required|all) data$/
) do |required_or_all|
  use_optional_fields = required_or_all == "all"
  @product_data = DataHelpers::DigitalProductMetadata.new(
    user_name: @users.distribution_user.name
  )
  @product_data.add_optional_landing_page_fields if use_optional_fields
  on(Project::CreateProductPage) do |page|
    page.populate_digital_fields(@product_data.data)
  end
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product data: ", @product_data.data)
end

When(
  /^I populate the digital product 2 landing page form with (required|all) data$/
) do |required_or_all|
  use_optional_fields = required_or_all == "all"
  @product_data = DataHelpers::DigitalProductBasics.new(
    user_name: @users.distribution_user.name
  )
  @product_data.add_optional_landing_page_fields if use_optional_fields
  on(Project::CreateProductPage) do |page|
    page.populate_digital_fields(@product_data.data)
  end
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product data: ", @product_data.data)
end

When(/^I use an orchard-generated UPC$/) do
  on(Project::CreateProductPage) do |page|
    # watir will sometimes click the scroll bar on local chrome
    page.scroll_to :bottom
    page.select_orchard_generated_upc
  end
end

When(/^I use my own UPC$/) do
  @product_upc = Support::Helpers::UPC.generate_unused_upc
  on(Project::CreateProductPage) do |page|
    page.select_use_own_upc
    page.upc = @product_upc
  end
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product upc: ", @product_upc)
end

Then(/^I see the correct data on the digital product basics page$/) do
  on(Project::DigitalProductBasicsPage) do |page|
    page.product_name_element.when_present
    release_basics = page.release_basics_values(
      only_for: @product_data.fields
    )
    expect(release_basics).to match @product_data.data
  end
end

Then(/^I see the UPC on the digital product basics page$/) do
  actual_upc = on(Project::DigitalProductBasicsPage).upc
  expect(actual_upc).to eql @product_upc
end

Given(/^I have an existing digital product on (QA|Production)$/) do |_|
  @project_id = 3_697_912
  @product_id = 2_020_312
  Support::Helpers::ScenarioVariables.add_scenario_variable("Project id: ", @project_id)
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product id: ", @product_id)
end

Given(/^I have an existing digital product on QA missing artwork/) do
  @project_id = 4_322_352
  @product_id = 2_801_962
  @product_data = DataHelpers::DigitalProductBasics.new(
    user_name: @users.distribution_user.name
  )
  Support::Helpers::ScenarioVariables.add_scenario_variable("Project id: ", @project_id)
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product id: ", @product_id)
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product data: ", @product_data.data)
end

Given(/^I have a digital product I wish to submit$/) do
  @product_id = 2_259_087
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product id: ", @product_id)
end

Given(/^I have a digital product I wish to unsubmit$/) do
  @product_id = 2_544_106
  Support::Helpers::ScenarioVariables.add_scenario_variable("Product id: ", @product_id)
  if Support::DbClient.current_release_status(@product_id) != "transfer_to_content"
    session_token = Support::Services::GrassAuth.instance.workstation_session_token("label_7123")
    Support::Services::OwsProductDigital.submit_product(@product_id, session_token)
  end
  puts "Release status after submit: #{Support::DbClient.current_release_status(@product_id)}"
end

Given(/^my product is in-progress$/) do
  Support::Helpers::Queries.update_release_status_label_processing(@product_id)
  Support::Helpers::Queries.delete_release_approval_queue(@product_id)
  Support::Helpers::Queries.delete_release_status(@product_id)
end

Given(/^I am on the Project::DigitalProductBasicsPage for a newly-created digital 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 digital audio as the product type"
  step "I populate the digital product landing page form with required data"
  step "I use an orchard-generated UPC"
  step "I submit the digital audio product landing page form"
  on(Project::DigitalProductOverviewPage).edit_basics
  on(Project::DigitalProductBasicsPage) do |page|
    page.product_name_element.when_present
    @product_upc = page.upc
    @product_id = page.product_id_from_url
  end
end

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

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

When(/^I populate (required|all) digital product basics fields$/) do |required_or_all|
  @product_data.add_required_basics_fields
  on(Project::DigitalProductBasicsPage) do |page|
    page.populate_required_fields(@product_data.data)
    if required_or_all == "all"
      @product_data.add_optional_basics_fields
      page.populate_optional_fields(@product_data.data)
    end
  end
end

When(
  /^I populate the digital product basics dropdowns with (existing|new) options$/
) do |existing_or_new|
  on(Project::DigitalProductBasicsPage) do |page|
    if existing_or_new == "new"
      @product_data.add_new_basics_dropdown_options
      page.create_new_dropdown_options(@product_data.data)
    else
      page.select_existing_dropdown_options(@product_data.data)
    end
  end
end

When(/^I populate the digital product basics classical fields$/) do
  @product_data.add_classical_basics_fields
  on(Project::DigitalProductBasicsPage) do |page|
    page.populate_genre(@product_data.data)
    page.populate_classical_fields(@product_data.data)
  end
end

When(/^I submit the(?: empty)? digital audio product basics page form$/) do
  on(Project::DigitalProductBasicsPage).submit
end

Then(/^I am redirected to the Workstation::ViewReleasePage for the product$/) do
  eventually do
    expect(@browser.url).to include "/releasebuilder/view?release_id=#{@product_id}"
  end
end

Then(/^I see the correct data on the view release page$/) do
  on(Workstation::ViewReleasePage) do |page|
    expect(page.orchard_artist).to eql @project_data[:artist]
    expect(page.assigned_upc).to eql @product_upc
    expect(page.label_catalog_number).to eql @project_data[:code]

    actual_values = page.release_basics_values(
      only_for: @product_data.view_release_page_fields
    )
    expect(actual_values).to match @product_data.view_release_page_data
  end
end

When(/^I go to the digital product (.*) section$/) do |section_name|
  case section_name
  when "artwork"
    on(Project::DigitalProductOverviewPage).edit_artwork_with_retry
    on(Project::ProductArtworkPage).artwork_dropzone_element.when_present
  when "basics"
    on(Project::DigitalProductOverviewPage).edit_basics
    on(Project::DigitalProductBasicsPage).upc_element.when_present
  when "territories"
    on(Project::DigitalProductOverviewPage).edit_territories
    on(Project::ProductTerritoryRestrictionsPage).territories_list_element.when_present
  when "scheduling and pricing"
    on(Project::DigitalProductOverviewPage).edit_pricing
    on(Project::DigitalProductPricingPage).release_date_element.when_present
  when "tracks"
    on(Project::DigitalProductOverviewPage).edit_tracks_with_retry
    on(Project::DigitalProductTracksPage) do |page|
      page.wait_until do
        page.file_replace? || page.upload_tracks? || page.upload_main? || page.tracks_complete?
      end
    end
  when "publishing obligation"
    on(Project::DigitalProductOverviewPage).edit_publishing
  else
    fail "Unknown section: '#{section_name}'!"
  end
end

Then(/^I am on the product publishing page$/) do
  on(Project::ProductPublishingPage) do |page|
    eventually(timeout: 10) do
      expect(page.publishing_body_element.present?).to be true
    end
  end
end

When(/^I go to the digital product (.*) step$/) do |step|
  case step
  when "overview"
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 3) do
      on(Project::DigitalProductBasePage) do |page|
        page.overview_step
        page.wait_until(5) { page.current_product_step_element == page.overview_step_element }
      end
    end
  when "scheduling and pricing"
    on(Project::DigitalProductBasePage).scheduling_and_pricing_step
  when "tracks"
    on(Project::DigitalProductBasePage).tracks_step
  when "territories"
    on(Project::DigitalProductBasePage).territory_restrictions_step
  else
    fail "Unknown step: '#{section_name}'!"
  end
end

When(/^I submit my product$/) do
  on(Project::DigitalProductBasePage) do |page|
    tries = 1
    wait_time = 20
    validate = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.validate_product if page.validate_product_element.present?
      tries += 1
    end
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 6, on_retry: validate) do
      wait_time = 120 unless tries < 3
      page.submit_element.wait_until(wait_time, &:present?)
    end
    page.submit
  end
end

When(/^I unsubmit my product$/) do
  on(Project::DigitalProductBasePage) do |page|
    page.product_more_actions_element.wait_until(&:present?).click
    click_more_actions = proc do
      page.product_more_actions_element.click
    end
    Retriable.retriable(on: Watir::Wait::TimeoutError, tries: 2, on_retry: click_more_actions) do
      page.wait_until(2) { page.unsubmit_product_element.present? }
    end
    page.unsubmit_product_element.click
  end
end

Then(/^I see the UPC on the digital product overview page$/) do
  actual_upc = on(Project::DigitalProductOverviewPage).upc
  expect(actual_upc).to eql @product_upc
end

Given(/^I am on the Project::DigitalProductOverviewPage for a newly-created 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 digital audio as the product type"
  step "I populate the digital product 2 landing page form with required data"
  step "I use an orchard-generated UPC"
  step "I submit the digital audio product landing page form"
end

Then(/^I should get (\d+) validation messages for the required fields$/) do |expected_field_count|
  on(Project::CreateProductPage) do |page|
    expect(page.validation_message_elements.find_all { |x| x.element.present? }.size)
      .to eq expected_field_count.to_i
  end
end

Then(/^I should be on the Digital Product Overview page$/) do
  eventually(timeout: 30) do
    expect(on(Project::DigitalProductOverviewPage).current_url).to include "overview"
  end
end

Then(/^I should see the submit success modal$/) do
  on(Project::SubmitSuccessModal) do |modal|
    validate = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      step "I submit my product"
    end
    Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 2, on_retry: validate) do
      eventually(timeout: 60) { expect(modal.submit_success_modal?).to be true }
      modal.submit_success_modal_close_element.click
    end
  end
end
