class Competitions::SaveTeamForm
  include ActiveModel::Model

  attr_accessor :competition, :team, :creator
  attr_accessor :name, :teacher_ids, :member_ids

  validates :name, presence: true

  validate :check_creator_enrollable
  def check_creator_enrollable
    return unless check_creator_identity_enrollable

    check_creator_multiple_enrollable
  end

  validate :check_teachers_enrollable
  def check_teachers_enrollable
    if competition.teacher_enroll_forbidden? # 禁止老师报名
      return if creator.is_teacher? # 因为创建者有单独校验，所以这里跳过
      return if teacher_ids.blank?

      if teacher_ids.present?
        errors.add(:teacher_ids, :enroll_forbidden)
        return
      end
    end

    self.teacher_ids = teacher_ids.map(&:to_i)
    all_teachers = creator.is_teacher? ? teacher_ids + [creator.id] : teacher_ids
    all_teachers.uniq!

    if all_teachers.size < competition.teacher_staff.minimum || all_teachers.size > competition.teacher_staff.maximum
      errors.add(:teacher_ids, :invalid_count, minimum: competition.teacher_staff.minimum, maximum: competition.teacher_staff.maximum)
      return
    end

    # 老师可多次报名，不检查
    return unless competition.teacher_multiple_limited?

    # 存在已报名老师
    enrolled_teacher_members = competition.team_members.where(user_id: all_teachers)
                                 .where.not(competition_team_id: team.id).pluck(:user_id)
    if enrolled_teacher_members.present?
      errors.add(:teacher_ids, :enrolled, names: User.where(id: enrolled_teacher_members).map(&:real_name).join('，'))
      return
    end
  end

  validate :check_members_enrollable
  def check_members_enrollable
    if competition.member_enroll_forbidden? # 禁止学生报名
      return unless creator.is_teacher? # 因为创建者有单独校验，所以这里跳过
      return if member_ids.blank?

      if member_ids.present?
        errors.add(:member_ids, :enroll_forbidden)
        return
      end
    end

    self.member_ids = member_ids.map(&:to_i)
    all_members = creator.is_teacher? ? member_ids : member_ids + [creator.id]
    all_members.uniq!

    if all_members.size < competition.member_staff.minimum || all_members.size > competition.member_staff.maximum
      errors.add(:member_ids, :invalid_count, minimum: competition.member_staff.minimum, maximum: competition.member_staff.maximum)
      return
    end

    # 成员可多次报名，不检查
    return unless competition.member_multiple_limited?

    # 存在已报名成员
    enrolled_members = competition.team_members.where(user_id: all_members)
                         .where.not(competition_team_id: team.id).pluck(:user_id)
    if enrolled_members.present?
      errors.add(:member_ids, :enrolled, names: User.where(id: enrolled_members).map(&:real_name).join('，'))
      return
    end
  end

  private

  # 竞赛是否限制了职业
  def check_creator_identity_enrollable
    if creator.is_teacher? && competition.teacher_enroll_forbidden?
      errors.add(:creator, :teacher_enroll_forbidden)
      return false
    elsif !creator.is_teacher? && competition.member_enroll_forbidden?
      errors.add(:creator, :member_enroll_forbidden)
      return false
    end

    true
  end

  # 创建者是否能多次报名
  def check_creator_multiple_enrollable
    return unless team.new_record? # 编辑战队时不需要校验
    return unless competition.enrolled?(creator)

    if (creator.is_teacher? && competition.teacher_multiple_limited?) || (!creator.is_teacher? && competition.member_multiple_limited?)
      errors.add(:creator, :enrolled)
      return false
    end

    true
  end
end