module Workstation
  class AccountingBreakdownPage < Workstation::BasePage
    include AccountingFilters

    page_url "/accounting/"

    # overriding page_header from BasePage because of inconsistent
    # DOM elements due to this using a different, SPA framework
    h1(:page_header) { div_element(id: "page").h1_element }

    div(:spinner, class: "lock")
    table(:statement_table, class: %w[table statementTbl])
    nav(:subnav, class: "main-subnav")
    # the following elements are for the upper most accounting statement which is comprised of dl and dd tags
    element(:opening_balance, :element, id: "openingBalance")
    element(:revenue, :element, id: "netReceipt")
    element(:net_revenue, :element, id: "netRevenue")
    element(:gross_revenue, :element, id: "grossRevenue")
    element(:performance_rights, :element, id: "performanceRoyalties")
    element(:compilations, :element, id: "compilations")
    element(:sync_licensing, :element, id: "syncLicensing")
    element(:publishing, :element, id: "totalPublishing")
    element(:adjustments, :element, id: "totalAdjustments")
    element(:payment, :element, id: "totalPayment")
    elements(:check, :element, class: "check-amount")
    element(:ringtones, :element, id: "ringtonePublishing")
    element(:full_tracks, :element, id: "fullTracksPublishing")
    element(:itunes_match, :element, id: "cloudPublishing")
    element(:outstanding_balance, :element, id: "outstandingBalance")
    element(:encoding_fees, :element, id: "encodingFees")
    element(:advance_paid, :element, id: "advancePaid")

    link(:performance_rights_details, class: "view_perf_royalties_details")
    link(:compilations_details, class: "view_compilations_details")
    link(:sync_licensing_details, class: "view_sync_licensing_details")
    div(:adjustments_pop_over, class: "popover-content")
    spans(:adjustment_comment) { adjustments_pop_over_element.span_elements(class: "adjustment-comment") }

    # New Filters
    link(:filter_list_item,
         class: ["//*[@class='accounting-filter", "filter-dropdown", "active']//ul/li[2]/a"])
    span(:filter_selected) { div_element(id: "filters_applied").span_element }
    div(:filter_select, class: ["accounting-filter", "filter-dropdown", "active"])
    text_field(:filter_search, id: "inputfetchReleases")
    button(:select_filter, text: "Select")
    link(:remove_filter, class: "remove_filter")

    # Links are selectable filter options
    # Used :data_type since :id's of links were not filter-specific, i.e.: /^dropdown_a_/
    links(:subaccount_filter_option, data_type: "subaccount_ids")
    links(:imprint_filter_option, data_type: "imprint_ids")
    links(:artist_filter_option, data_type: "artist_ids")
    links(:release_filter_option, data_type: "release_ids")
    links(:product_filter_option, data_type: "release_ids")
    links(:track_filter_option, data_type: "track_ids")
    links(:source_filter_option, data_type: "store_ids")
    links(:channel_filter_option, data_type: "transaction_type_ids")
    links(:country_filter_option, data_type: "country_ids")
    links(:period_filter_option, data_type: "activity_period_ids")

    # Views
    button(:subaccount_view, class: "subaccountId")
    button(:imprint_view, class: "imprint_id")
    button(:artist_view, class: "artist_id")
    button(:release_view, class: "release_id")
    button(:product_view, class: "release_id")
    button(:track_view, class: "track_id")
    button(:source_view, class: "store_id")
    button(:channel_view, class: "transaction_type_id")
    button(:country_view, class: "country_id")
    button(:activity_period_view, class: "activity_period_id")
    button(:active_view) { div_element(class: "revenuePanel").button_element(class: "active") }

    def column_exists?(name)
      column_name = name.upcase
      breakdown_table_element.first_row[column_name].exists?
    end

    # Breakdown
    div(:breakdown_div, id: "breakdown")
    div(:no_data) { breakdown_div_element.div_element(text: /^We\'re sorry/) } # TODO: better loc
    table(:breakdown_table, id: "breakdownTable")
    span(:breakdown_revenue, class: "sales-total")

    def wait_for_spinner_to_disappear
      # Increased on 3/22/2018 while systems does stuff for their 3/30 deadline
      spinner_element.element.wait_while(timeout: 300, &:present?)
    end

    def wait_for_statement_table
      # Ensure that the statement table has a value listed for outstanding balance
      outstanding_balance_element.element.wait_until(&:present?)
    end

    def adjustments_sum
      popover_values = adjustments_pop_over_element.element.dts.map(&:text)
      popover_values.pop # to remove the total
      bigdecimal_popover_values = popover_values.map { |x| currency_to_bigdecimal(x) }
      bigdecimal_popover_values.reduce(:+)
    end

    # Adjustment type, like Sync Licensing, Compiltations, etc.
    def click_adjustment_details_link(adjustment_type)
      details_link = adjustment_type.to_snake_case
      send "#{details_link}_details"
    end

    # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
    def expected_outstanding_balance
      c = ->(string) { string.gsub(/[^\d-]/, "").to_d / 100 }

      running_total = 0
      running_total += c.call opening_balance_element.when_present.text
      running_total += c.call advance_paid if advance_paid?
      running_total += c.call revenue if revenue?
      running_total += c.call encoding_fees if encoding_fees?
      running_total += c.call full_tracks if full_tracks?
      running_total += c.call ringtones if ringtones?
      running_total += c.call adjustments if adjustments?
      running_total += c.call payment if payment?

      outstanding_bal = c.call outstanding_balance
      expect(outstanding_bal).to be_within(1.00).of(running_total)
      running_total
    end
    # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity

    def search_for_product_breakdown
      upc = breakdown_table_element.div_element(class: "smalltext").text.scan(/\d+/).first
      throttled_input(filter_search_element, upc, 1)
    end
  end
end
