class Exercise < ApplicationRecord
  belongs_to :course, counter_cache: true
  belongs_to :exercise_bank, optional: true
  belongs_to :user

  has_many :exercise_users,:dependent => :destroy
  has_many :exercise_questions,:dependent => :destroy
  has_many :exercise_group_settings,:dependent => :destroy
  has_many :tidings, as: :container
  has_many :course_acts, class_name: 'CourseActivity', as: :course_act, dependent: :destroy

  scope :is_exercise_published, -> { where("exercise_status > ? ",1)}
  scope :unified_setting, -> { where("unified_setting = ?",true) }
  scope :exercise_by_ids, lambda { |ids| where(id: ids) unless ids.blank? }
  scope :exercise_by_status, lambda { |s| where(exercise_status: s) unless s.blank? }
  scope :exercise_search, lambda { |keywords|
    where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?}

  validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" }

  after_create :create_exercise_list

  def create_exercise_list
    str = ""
    # TODO: 一次性为所有学生创建数据是否存在问题?
    self.course.students.find_each do |student|
      str += "," if str != ""
      str += "(#{student.user_id}, #{self.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
    end

    if str != ""
      sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str
      ActiveRecord::Base.connection.execute sql
    end
  end

  #获取学生视角的试卷用户
  def get_stu_exercise_users
    if unified_setting  #试卷统一设置
      exercise_users
    else
      ex_group_setting_ids = exercise_group_settings.exercise_group_published.pluck(:course_group_id)
      course_user_ids = course.students.where(course_group_id:ex_group_setting_ids).pluck(:user_id)
      exercise_users.where(user_id:course_user_ids)
    end
  end

  def get_exercise_end_time(user_id)
    if unified_setting
      self&.end_time
    else
      user_course_group = course.course_members.find_by(user_id: user_id)&.course_group_id
      exercise_group_settings.find_by(course_group_id:user_course_group)&.end_time
    end
  end

  #统一设置,为当前老师有权限的分班学生,分班设置,也为当前老师有权限的分班的学生
  def all_exercise_users(user_id)
    ex_users = self.exercise_users
    group_ids = common_published_ids(user_id)
    if group_ids.present?
      ex_users = ex_users.where(user_id: course.students.where(course_group_id: group_ids).pluck(:user_id))
    end
    ex_users
  end

  #当前用户已发布的班级id和试卷分组已发布的班级id的交集
  def common_published_ids(user_id)
    current_user_groups = course.teacher_course_group_ids(user_id)
    if unified_setting
      if course.none_group_count > 0  #有未分班的,则发布到未发布分班
        un_group_ids = [0]
      else
        un_group_ids = []
      end
      published_group_ids = (current_user_groups + un_group_ids).uniq    #统一设置时,为当前用户的分班id及未分班
    else
      ex_group_setting = exercise_group_settings.pluck("course_group_id").uniq
      common_all_ids = ex_group_setting & current_user_groups  #当前用户有权限的已发布的分班id #非统一设置时,为当前用户有权限的且已发布分班的id
      published_group_ids = common_all_ids.uniq
    end
    published_group_ids
  end


  #判断用户是否属于试卷分班的学生中
  def check_user_in_course(user_id,user_identity)
    ex_group_settings = exercise_group_settings.pluck(:course_group_id)
    member = course.course_members.course_find_by_ids("user_id",user_id)
    member_group_id = member.pluck(:course_group_id).uniq
    if (member_group_id & ex_group_settings).size > 0 || user_identity < Course::STUDENT
      true
    else
      false
    end
  end

  #判断是否为分班,如果分班,试卷的截止时间为当前分班时间,否则为试卷的截止时间
  def get_exercise_status(user_id)
    user_group = course.course_members.find_by(user_id: user_id)
    if user_group.present?
      if user_group.role == "STUDENT"   #为学生
        is_teacher = false
      else
        is_teacher = true
      end
      ex_time = get_exercise_times(user_id,is_teacher)

      pb_time = ex_time[:publish_time]
      ed_time = ex_time[:end_time]

      if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now
        status = 2
      elsif ed_time.present? && ed_time <= Time.now
        status = 3
      else
        status  = 1
      end
    else
      status = exercise_status
    end
    status
  end

  #获取试卷的发布时间和截止时间。teacher 为boolean,当为true时,表示的是当前为老师
  def get_exercise_times(user_id,teacher)
    if unified_setting
      pb_time = publish_time
      en_time = end_time
    else
      ex_group_setting = exercise_group_settings
      if teacher  #当前为老师,为设置组的最大值和最小值
        user_group = course.teacher_course_groups.get_user_groups(user_id)
        user_group_ids = user_group.present? ? user_group.pluck(:course_group_id) : course.course_groups.pluck(:id)
        user_ex_group_settings = ex_group_setting.find_in_exercise_group("course_group_id",user_group_ids)
        pb_time_min = user_ex_group_settings.publish_time_no_null.map(&:publish_time)
        en_time_max = user_ex_group_settings.end_time_no_null.map(&:end_time)
        pb_time = pb_time_min.size > 0 ? pb_time_min.min : nil
        en_time = en_time_max.size > 0 ? en_time_max.max : nil
      else
        user_group = course.students.course_find_by_ids("user_id",user_id)
        if user_group.present?
          user_group_id = user_group.first.course_group_id
          user_ex_group_setting = ex_group_setting.find_in_exercise_group("course_group_id",user_group_id)
          pb_time = user_ex_group_setting.present? ? user_ex_group_setting.first.publish_time : nil
          en_time = user_ex_group_setting.present? ? user_ex_group_setting.first.end_time : nil
        else
          pb_time = nil
          en_time = nil
        end
      end
    end
    {
        "publish_time":pb_time,
        "end_time":en_time
    }
  end

  #判断当前用户的答题状态
  def check_user_answer_status(user)
    ex_answer_user = exercise_users.find_by(user_id: user.id)
    user_ex_status = get_exercise_status(user.id)
    user_status = 2
    if ex_answer_user.present? && (ex_answer_user.start_at.present? || ex_answer_user.end_at.present?)   #学生有过答题的,或者立即截止,但学生未做试卷的
      user_status = ex_answer_user.commit_status
    end
    if ex_answer_user.present? && ex_answer_user.start_at.blank? && user_ex_status == 3
      user_status = 4
    end

    user_status
  end

end