class Admins::CreateCompetitionPrizeUsersService < ApplicationService
  attr_reader :competition

  def initialize(competition)
    @competition = competition
  end

  def call
    raise Error, '竞赛还未结束' unless competition.finished?
    raise Error, '请勿重复生成' if competition.competition_prize_users.exists?
    raise Error, '请先设置奖项' if prizes.blank?
    raise Error, '无获奖队伍' if prize_teams.blank?

    ActiveRecord::Base.transaction do
      columns = %i[competition_id competition_team_id competition_prize_id user_id
                   status rank leader created_at updated_at]

      CompetitionPrizeUser.bulk_insert(*columns) do |worker|
        prize_teams.each_with_index do |team, index|
          rank = index + 1
          prize = team_prize(rank) # 根据排名获取当前队伍奖项

          team.team_members.each do |member|
            attr = {
              competition_id: competition.id,
              competition_team_id: team.id,
              competition_prize_id: prize.id,
              user_id: member.user_id,
              leader: member.creator?,
              status: :pending,
              rank: rank
            }

            worker.add(attr)
          end
        end
      end
    end
  end

  private

  def prizes
    @_prizes ||= competition.competition_prizes.order(id: :asc).to_a
  end

  def team_prize(rank)
    current = 0
    prizes.each do |prize|
      return prize if rank > current && rank <= current + prize.num

      current += prize.num
    end
  end

  def prize_teams
    @_prize_teams ||= begin
      prize_num_total = prizes.sum(&:num)

      # 只有一个阶段,则成绩为该阶段成绩,否则为stage ID为0的总成绩
      stage_id = competition.competition_stages.count == 1 ? competition.competition_stages.first.id : 0

      competition.competition_teams.joins(:competition_scores)
        .where(competition_scores: { competition_stage_id: stage_id })
        .order("competition_scores.score desc, competition_scores.cost_time desc")
        .includes(:team_members)
        .limit(prize_num_total)
    end
  end
end