When(/^I enter a check/) do
  check_payable = "QA Automation #{Time.stamp}"
  puts "check payable: #{check_payable}"
  @check = {
    check_payable: check_payable,
    upc: "888608383028",
    vendor_id: "7123",
    check_amount: "1.00",
    currency: "United States Dollar (USD)",
    paid_for_type: "Digital",
    cut_date: "2014-06-15",
    check_no: Time.now.strftime("%s"),
    entry_date: Time.now.strftime("%Y-%m-%d")
  }
  Support::Helpers::ScenarioVariables.add_scenario_variable("Check ", @check)
  on(OA::AddCheckPayablePage) do |page|
    page.populate_page_with(@check)
    page.submit
  end
end

When(/^I see errors when I attempt to submit a check without the required fields/) do
  on(OA::AddCheckPayablePage) do |page|
    page.submit
    errors = ["UPC is missing or not valid.",
              "VendorID is missing or not numeric.",
              "Amount is not valid.",
              "Cut Date must be a valid date in YYYY-MM-DD format."]

    message = page.error_alert_element.when_present.text
    errors.each do |e|
      expect(message).to include(e)
    end
  end
end

Then(/^I should see a message that the check was successfully added$/) do
  on(OA::AddCheckPayablePage) do |page|
    message = page.success_alert_element.when_present.text
    expect(message).to eq("Checkpaid successfully added.")
  end
end

Given(/^A nonexistent check$/) do
  @check = { upc: "111111111111" }
  Support::Helpers::ScenarioVariables.add_scenario_variable("Check ", @check)
end

When(/^I search for the check$/) do
  visit(OA::SearchCheckPayablePage) do |page|
    page.populate_page_with @check
    page.search
  end
end

Then(/^I should see the Check Payable Results page with no results$/) do
  on(OA::CheckPayableResultsPage) do |page|
    expect(page.no_results?).to be true
    # In case we are on a legacy OA page with no user info header
    visit OA::RelationshipsPage unless page.user_full_name?
  end
end

Then(/^I should see the check$/) do
  on(OA::CheckPayableResultsPage) do |page|
    expect(@check[:check_no]).not_to be nil
    expect(page.text).to include @check[:check_no]
  end
end

When(/^I enter a manual adjustment/) do
  # Skips the rest of the test if an accounting run is in progress
  pending if Support::Helpers::AccountingRun.in_progress?
  adjustment = DataHelpers::UploadManualAdjustment.create_manual_adjustment

  on(OA::AddManualAdjustmentPage) do |page|
    page.populate_page_with(adjustment)
    page.submit
  end
end

Then(/^I should see a message that the adjustment was successfully added$/) do
  on(OA::AddManualAdjustmentPage) do |page|
    message = page.success_alert_element.when_present.text
    expect(message).to eql "Manual Adjustment Added Successfully."
  end
end

Then(/^I confirm that the new adjustments? ha(ve|s) been added$/) do |*|
  DataHelpers::UploadManualAdjustment.records.each do |adjustment|
    puts "searching for comment: #{adjustment['comment']}"
    visit(OA::SearchManualAdjustmentPage) do |page|
      page.comment = adjustment["comment"]
      page.search
    end
    on(OA::ManualAdjustmentResultsPage) do |page|
      fail "no results found!" if page.results.include? "No Manual Adjustment found"
      expect(page.results).to include adjustment["comment"]
    end
  end
end

Given(/^I have an up-to-date (.*) template$/) do |class_name|
  case class_name
  when "UploadManualAdjustment"
    page_class = OA::UploadManualAdjustmentPage
    template_class = DataHelpers::UploadManualAdjustment
  when "UploadCheckDeletion"
    page_class = OA::UploadCheckDeletionPage
    template_class = DataHelpers::UploadCheckDeletion
  else
    fail "unknown template #{class_name}!"
  end

  template_url = visit(page_class).template_url
  template_class.get_template(template_url)
end

When(/^I upload a manual adjustment spreadsheet with (valid|invalid) data$/) do |valid|
  validity = (valid == "valid" ? true : false)
  file = DataHelpers::UploadManualAdjustment.create_spreadsheet(valid: validity)
  on(OA::UploadManualAdjustmentPage).upload_file file
end

When(/^I upload a check deletion spreadsheet with invalid data$/) do
  file = DataHelpers::UploadCheckDeletion.create_invalid_spreadsheet
  on(OA::UploadCheckDeletionPage).upload_file file
end

Then(/^I should see a message that the adjustments were successfully added$/) do
  expected_message = "Manual Adjustments successfully added and cache was "\
    "cleared for all vendors."
  on(OA::AccountingPage) do |page|
    expect(page.success_message).to eql expected_message
  end
end

Then(/^I should see an error message for the uploaded manual adjustment spreadsheet$/) do
  on(OA::UploadManualAdjustmentPage) do |page|
    expect(page.validation_errors).not_to eql ""
  end
end

Then(/^I should see an error message for the uploaded delete check spreadsheet$/) do
  on(OA::UploadCheckDeletionPage) do |page|
    expect(page.validation_errors).not_to eql ""
  end
end

Given(/^A label with an outstanding balance for the current quarter$/) do
  # can't use check details to delete any prior checks -- page w/ check number fails to finish loading
  label_id = "6"
  payee_name = "1201 Music"

  visit(OA::SalesHistoryPage, using_params: { queries: { "vendor_id" => label_id } }) do |page|
    quarter = page.current_quarter
    balance = page.current_quarter_outstanding_balance
    puts "current quarter: #{quarter}"
    puts "current balance: #{balance}"
    balance_float = balance.to_decimal_only
    expect(balance_float.to_f).to be > 0, "vendor #{label_id} doesn't have an outstanding balance. "\
      "ensure that a check has not already been cut for the most recent period"
    @check = { label_id: label_id, payee: payee_name, balance: balance }
    Support::Helpers::ScenarioVariables.add_scenario_variable("Check ", @check)
  end
end

When(/^I generate a check for that label$/) do
  visit(OA::GenerateChecksPayablePage) do |page|
    page.label_id = @check[:label_id]
    page.payment_interval = "Quater"
    page.generate
    page.status_element.when_present(90)
    eventually(timeout: 90) { expect(page.status_element.text).to eq "Completed!" }
  end
end

When(/^I process the check$/) do
  visit(
    OA::ApproveNewChecksPage,
    using_params: { queries: { "vendor_id_req" => @check[:label_id] } }
  ) do |page|
    page_refresh = proc do |exception, try|
      puts "#{exception.class}: '#{exception.message}' - Retry attempt: #{try}"
      page.refresh
      sleep 10
    end
    Retriable.retriable(on: RSpec::Expectations::ExpectationNotMetError, tries: 6, on_retry: page_refresh) do
      page.approve_single_check(@check)
    end
    page.submit

    page.expect_success
  end
end

When(/^I cut the check$/) do
  visit(OA::ProcessCheckPage, using_params: { queries: { "vendor_id" => @check[:label_id] } }) do |page|
    # check numbers
    check_number = Time.now.strftime("%s")
    puts "check number: #{check_number}"
    page.check_no = check_number
    @check[:date] = page.date
    @check[:check_no] = check_number
    Support::Helpers::ScenarioVariables.add_scenario_variable("Check ", @check)
    page.process
  end
  on(OA::ProcessCheckConfirmPage) do |page|
    page.confirm
  end
end

When(/^I delete the check$/) do
  # need hash to match spreadsheet headers
  spreadsheet_checks = [{
    "entity type" => "label",
    "id" => @check[:label_id],
    "payee" => @check[:payee],
    "check #" => @check[:check_no],
    "amount" => @check[:balance].to_decimal_only,
    "date cut" => @check[:date]
  }]
  Support::Helpers::ScenarioVariables.add_scenario_variable("spreadsheet_checks ", spreadsheet_checks)
  file = DataHelpers::UploadCheckDeletion.create_custom_spreadsheet spreadsheet_checks
  on(OA::UploadCheckDeletionPage) do |page|
    page.upload_file file
    fail "file did not validate: #{page.validation_errors}" if page.validation_errors?
  end
  on(OA::AccountingPage) do |page|
    expect(page.success_message).to eql "Checks successfully deleted."
  end
end
