# frozen_string_literal: true

# Provides helper methods to compute footprints
class FootprintService
  # Compute the footprint
  # @param klass Invoice|InvoiceItem|HistoryValue
  # @param item an instance of the provided class
  # @param sort the items in database by the provided criterion, to find the previous one
  def self.compute_footprint(klass, item, sort_on = 'id')
    Checksum.text(FootprintService.footprint_data(klass, item, sort_on))
  end

  # Return the original data string used to compute the footprint
  # @param klass Invoice|InvoiceItem|HistoryValue
  # @param item an instance of the provided class
  # @param sort the items in database by the provided criterion, to find the previous one
  def self.footprint_data(klass, item, sort_on = 'id')
    raise TypeError unless item.is_a? klass

    previous = klass.where("#{sort_on} < ?", item[sort_on])
                 .order("#{sort_on} DESC")
                 .limit(1)

    columns  = FootprintService.footprint_columns(klass)

    "#{columns.map { |c| item[c] }.join}#{previous.first ? previous.first.footprint : ''}"
  end

  # Return an ordered array of the columns used in the footprint computation
  # @param klass Invoice|InvoiceItem|HistoryValue
  def self.footprint_columns(klass)
    klass.columns.map(&:name).delete_if { |c| %w[footprint updated_at].include? c }
  end

  # Logs a debugging message to help finding why a footprint is invalid
  # @param klass Invoice|InvoiceItem|HistoryValue
  # @param item an instance of the provided class
  def self.debug_footprint(klass, item)
    columns = FootprintService.footprint_columns(klass)
    current = FootprintService.footprint_data(klass, item)
    saved = FootprintDebug.find_by(footprint: item.footprint, klass: klass)
    puts "Debug footprint for #{klass} [ id: #{item.id} ]"
    puts '-----------------------------------------'
    puts "columns: [ #{columns.join(', ')} ]"
    puts "current footprint: #{current}"
    puts "  saved footprint: #{saved&.data}"
    puts '-----------------------------------------'
  end
end