class ActiveGenie::Ranking::RankingScoring

def self.call(...)

def self.call(...)
  new(...).call
end

def call

def call
  ActiveGenie::Logger.with_context(log_context) do
    @reviewers = generate_reviewers
    players_without_score.each do |player|
      # TODO: This can take a while, can be parallelized
      player.score = generate_score(player)
    end
  end
end

def generate_reviewers

def generate_reviewers
  return @reviewers if @reviewers.size > 0
  reviewer1, reviewer2, reviewer3 = ActiveGenie::Scoring::RecommendedReviewers.call(
    [@players.sample.content, @players.sample.content].join("\n\n"),
    @criteria,
    config: @config
  ).values_at('reviewer1', 'reviewer2', 'reviewer3')
  
  ActiveGenie::Logger.debug({ code: :new_reviewers, reviewers: [reviewer1, reviewer2, reviewer3] })
  [reviewer1, reviewer2, reviewer3]
end

def generate_score(player)

def generate_score(player)
  score, reasoning = ActiveGenie::Scoring.call(
    player.content,
    @criteria,
    @reviewers,
    config: @config
  ).values_at('final_score', 'final_reasoning')
  ActiveGenie::Logger.debug({ code: :new_score, player_id: player.id, score:, reasoning: })
  score
end

def initialize(players, criteria, reviewers: [], config: {})

def initialize(players, criteria, reviewers: [], config: {})
  @players = players
  @criteria = criteria
  @config = ActiveGenie::Configuration.to_h(config)
  @reviewers = Array(reviewers).compact.uniq
end

def log_context

def log_context
  { ranking_scoring_id: }
end

def players_without_score

def players_without_score
  @players_without_score ||= @players.select { |player| player.score.nil? }
end

def ranking_scoring_id

def ranking_scoring_id
  player_ids = players_without_score.map(&:id).join(',')
  ranking_unique_key = [player_ids, @criteria, @config.to_json].join('-')
  Digest::MD5.hexdigest(ranking_unique_key)
end