class Competition < ApplicationRecord
  belongs_to :laboratory, optional: true

  has_many :competition_modules, dependent: :destroy
  has_many :unhidden_competition_modules, -> { where(hidden: false) }, class_name: 'CompetitionModule'

  has_many :competition_stages, dependent: :destroy
  has_many :competition_stage_sections, dependent: :destroy
  has_one :current_stage_section, -> { where('end_time > NOW()') }, class_name: 'CompetitionStageSection'

  has_many :competition_teams, dependent: :destroy
  has_many :team_members, dependent: :destroy
  has_many :chart_rules, dependent: :destroy

  has_many :competition_scores, dependent: :destroy

  has_many :competition_staffs, dependent: :destroy
  has_one :teacher_staff, -> { where(category: :teacher) }, class_name: 'CompetitionStaff'
  has_one :member_staff, -> { where.not(category: :teacher) }, class_name: 'CompetitionStaff'
  has_one :competition_mode_setting, dependent: :destroy

  has_many :informs, as: :container, dependent: :destroy
  has_many :attachments, as: :container, dependent: :destroy

  has_many :competition_awards, dependent: :destroy
  has_many :competition_schools, dependent: :destroy
  has_many :sponsor_schools, -> { where(source: :sponsor) }, class_name: 'CompetitionSchool'  # 主办方
  has_many :region_schools, -> { where(source: :region) }, class_name: 'CompetitionSchool'   # 开放范围

  has_many :competition_managers, dependent: :destroy
  has_many :managers, through: :competition_managers, source: :user

  has_many :competition_prizes, dependent: :destroy
  has_many :competition_prize_users, dependent: :destroy

  validates :introduction, length: { maximum: 500, too_long: "不能超过500个字符" }

  before_save :set_laboratory
  after_create :create_competition_modules

  def mode_type
    case mode
    when 1
      "实训"
    when 2
      "课堂"
    when 3
      "教学"
    when 4
      "托管"
    else
      "--"
    end
  end

  # 报名数
  def team_member_count
    course = competition_mode_setting&.course if mode == 2
    course ? course.students.count : team_members.count
  end

  def sponsor_schools_name
    sponsor_schools.map{|sponsor| sponsor.school.name}
  end

  def region_schools_name
    region_schools.map{|region| region.school.name}
  end

  def competition_status
    if !status
      com_status = "nearly_published"
    elsif end_time.nil? || end_time > Time.now
      com_status = "progressing"
    else
      com_status = "ended"
    end
    com_status
  end

  def teacher_staff_num
    teacher_staff ? "#{teacher_staff.minimum}~#{teacher_staff.maximum}" : "--"
  end

  def member_staff_num
    member_staff ? "#{member_staff.minimum}~#{member_staff.maximum}" : "--"
  end

  # 是否上架
  def published?
    status?
  end

  # 即将发布
  def nearly_published?
    !published? && published_at.present?
  end

  # 是否为个人赛
  def personal?
    competition_staffs.sum(:maximum).to_i == 1 || (competition_staffs.nil? && max_num == 1)
  end

  # 报名是否结束
  def enroll_ended?
    enroll_end_time.blank? || enroll_end_time < Time.now
  end

  # 是否已经报名
  def enrolled?(user)
    team_members.exists?(user_id: user.id)
  end

  # 是否开放
  def open?(user)
    user_school_id = user.user_extension&.school_id.to_i
    region_schools.size == 0 || region_schools.exists?(school_id: user_school_id)
  end

  # 是否禁止教师报名
  def teacher_enroll_forbidden?
    teacher_staff.blank? || teacher_staff.maximum.zero?
  end

  # 是否禁止学生报名
  def member_enroll_forbidden?
    member_staff.blank? || member_staff.maximum.zero?
  end

  # 老师是否能多次报名
  def teacher_multiple_limited?
    teacher_staff&.mutiple_limited?
  end

  # 队员是否能多次报名
  def member_multiple_limited?
    member_staff&.mutiple_limited?
  end

  def max_min_stage_time
    CompetitionStageSection.find_by_sql("SELECT MAX(end_time) as max_end_time, MIN(start_time) as min_start_time,
                                         competition_stage_id FROM competition_stage_sections WHERE competition_id = #{id}
                                         GROUP BY competition_stage_id order by competition_stage_id")
  end

  def all_module_types
    %w[home enroll inform chart resource certificate]
  end

  def max_stage_end_time
    competition_stages.map(&:max_end_time).max
  end

  def charts_count
    competition_prizes&.pluck(:num).sum.to_i > 0 ? competition_prizes&.pluck(:num).sum.to_i : awards_count
  end

  def manager?(user)
    user && competition_managers.exists?(user_id: user.id)
  end

  def finished?
    end_time.blank? || end_time < Time.now
  end

  private

  def get_module_name type
    case type
    when 'home'     then '赛制介绍'
    when 'enroll'   then '报名'
    when 'inform'   then '通知公告'
    when 'chart'    then '排行榜'
    when 'resource' then '资料下载'
    when 'certificate' then '获奖证书'
    else ''
    end
  end

  def create_competition_modules
    CompetitionModule.bulk_insert(*%i[competition_id module_type name position created_at updated_at]) do |worker|
      all_module_types.each_with_index do |type, index|
        worker.add(competition_id: id, module_type: type, name: get_module_name(type), position: index + 1, )
      end
    end
  end

  def set_laboratory
    return unless new_record?

    self.laboratory = Laboratory.current if laboratory_id.blank?
  end
end