require 'ruby-progressbar'
require_relative './validate/account_id'
require_relative './validate/contract'
require_relative './validate/upc'
require_relative './validate/amount'
require_relative './validate/currency'
require_relative './validate/distribution_type'
require_relative './validate/comment'
require_relative './validate/adjustment_type'
require_relative './validate/activity_date'
require_relative './validate/apply_date'
require_relative './validate/accounting_period'

class Validate
  attr_reader :invalid_rows, :valid_rows, :all_rows, :upc_label_cache_hits

  def self.run(adjustments_for_period_id, adjustment_file_name, rows, royalty_repo, skip_validation)
    validation = Validate.new(adjustments_for_period_id, adjustment_file_name, rows, royalty_repo)

    return validation if skip_validation

    validation.execute
    validation
  end

  def initialize(adjustments_for_period_id, adjustments_file_name, rows, repo)
    @adjustments_for_period_id = adjustments_for_period_id
    @repo = repo
    @adjustments_file_name = adjustments_file_name
    @invalid_rows = []
    @valid_rows = []
    @all_rows = remove_header(rows)
    @period_status = false
    @upc_label_cache_hits = 0
  end

  def remove_header(rows)
    rows[1..-1]
  end

  def execute
    @period_status = AccountingPeriod.open?(@adjustments_for_period_id, @repo)

    progressbar = ProgressBar.create(:title => "Validating", :starting_at => 0, :total => @all_rows.count)

    @all_rows.each do | row |
      progressbar.increment
      validate(row)
    end

    @upc_label_cache_hits = @repo.upc_label_cache_hits
  end

  def validate(row)
    reasons = []
    reasons << AccountingPeriod.validate(@adjustments_for_period_id, @period_status)
    reasons << AccountID.validate(row, @repo)
    reasons << Contract.validate(row, @repo)
    reasons << UPC.validate(row, @repo)
    reasons << Amount.validate(row)
    reasons << Currency.validate(row)
    reasons << ActivityDate.validate(row, @repo)
    reasons << ApplyDate.validate(row, @repo)
    reasons << AdjustmentType.validate(row, @repo)
    reasons << Comment.validate(row)
    reasons << DistributionType.validate(row)

    row[:reasons] = reasons.flatten

    row[:reasons].any? ? @invalid_rows << row : @valid_rows << row
  end
end

