class StudentWork < ApplicationRecord
  #学生提交作品表 #work_status :0 未提交  1 已提交  2 迟交
  belongs_to :user
  belongs_to :commit_user, class_name: 'User', foreign_key: :commit_user_id, optional: true
  belongs_to :update_user, class_name: 'User', foreign_key: :update_user_id, optional: true
  belongs_to :homework_common
  belongs_to :myshixun, optional: true
  has_many :student_works_evaluation_distributions, dependent: :destroy
  has_many :student_works_scores, dependent: :destroy
  belongs_to :project, optional: true

  # attachtype: 1（正常提交的附件）， 7（补交的附件）
  has_many :attachments, as: :container, dependent: :destroy

  has_many :tidings, as: :container, dependent: :destroy

  has_many :challenge_work_scores, dependent: :destroy

  before_save :set_work_score

  validates :description, length: { maximum: 5000 }

  scope :has_committed, lambda { where("work_status != 0") }
  # 未提交
  scope :unfinished, -> {where(work_status: 0)}
  # 按时提交
  scope :finished, -> {where(work_status: 1)}
  # 延迟提交
  scope :delay_finished, -> {where(work_status: 2)}

  #按用户id查找
  scope :homework_by_user, lambda{|ids| where(user_id: ids)}

  #根据homework_common_id查找
  scope :find_by_homework, lambda{|ids| where(homework_common_id: ids)}

  def myshixun_consume
    self.myshixun && self.myshixun.passed_count > 0 ? self.myshixun.total_spend_time : "--"
  end

  # 助教评分次数
  def ta_comment_count
    self.student_works_scores.select{|score| score.reviewer_role == 2}.group_by(&:user_id).count
  end

  # 匿评次数
  def student_comment_num
    homework_common.homework_detail_manual.comment_status > 2 ? self.student_works_scores.select{|score| score.reviewer_role == 3}.group_by(&:user_id).count : 0
  end

  # 匿评申诉总条数
  def appeal_all_count
    homework_common.homework_detail_manual.comment_status >= 3 ? self.student_works_scores.
        select{|score| score.reviewer_role == 3 && score.appeal_status != 0}.group_by(&:user_id).count : 0
  end

  # 匿评申诉待处理条数
  def appeal_deal_count
    homework_common.homework_detail_manual.comment_status >= 3 ? self.student_works_scores.
        select{|score| score.reviewer_role == 3 && score.appeal_status == 1}.group_by(&:user_id).count : 0
  end

  # 当前用户该作品的匿评申诉总条数
  def my_appeal_all_count user_id
    student_works_scores.select{|score| score.reviewer_role == 3 && score.appeal_status != 0 && score.user_id == user_id}.size
  end

  # 当前用户该作品的匿评申诉总条数
  def my_appeal_deal_count user_id
    student_works_scores.select{|score| score.reviewer_role == 3 && score.appeal_status == 1 && score.user_id == user_id}.size
  end

  # 分组名
  def work_group_name
    self.group_id == 0 ?  "--" : "分组#{self.group_id}"
  end

  # 助教评分
  def ta_score ta_mode
    if ta_mode == 1
      ts_score = StudentWorksScore.find_by_sql("SELECT AVG(score) AS score FROM (SELECT * FROM
                                                (SELECT * FROM student_works_scores WHERE student_work_id = #{self.id}
                                                AND reviewer_role = 2 AND score IS NOT NULL ORDER BY created_at DESC)
                                                AS t GROUP BY user_id) AS a")
      score = ts_score.first.score.nil? ? nil : ts_score.first.score.to_f.try(:round, 2)
    else
      score = StudentWorksScore.where("student_work_id = #{self.id} AND reviewer_role = 2 AND score IS NOT NULL").last.try(:score)
    end
  end

  # 缺评次数
  def absence_count
    absence_penalty_count = self.user.student_works_evaluation_distributions.joins(:student_work).
        where("homework_common_id = #{self.homework_common_id}").count -
        self.user.student_works_scores.joins(:student_work).where("homework_common_id = #{self.homework_common_id}
                                                  and reviewer_role = 3").select("distinct student_work_id").count
    absence_penalty_count = absence_penalty_count < 0 ? 0 : absence_penalty_count
  end

  # 违规匿评次数
  def appeal_count
    appeal_count = self.user.student_works_scores.joins(:student_work).where("homework_common_id = #{self.homework_common_id}
                                                  and appeal_status = 3").select("distinct student_work_id").count
  end

  def delete_atta atta
    last_score = student_works_scores.where.not(score: nil).last
    atta.author_id == user_id && (!last_score.present? || last_score.try(:created_at) < atta.created_on)
  end

  # 作品总体评价
  def overall_appraisal
    case self.work_score.to_i
    when (90..100)
      '优秀'
    when (70...90)
      '良好'
    when (60...70)
      '及格'
    when (0...60)
      '不及格'
    end
  end

  # 更新作品成绩
  def set_work_score
    if work_status > 0 && homework_common && !self.ultimate_score
      case homework_common.homework_type
      when "normal", "group"
        if !homework_common&.homework_detail_manual&.final_mode
          tea_ass_proportion = homework_common.homework_detail_manual.ta_proportion
          tea_proportion = homework_common.homework_detail_manual.te_proportion
          if self.teacher_score
            if self.teaching_asistant_score.nil?
              if self.student_score.nil?
                self.final_score = self.teacher_score
              else
                te_proportion = tea_proportion + tea_ass_proportion / 2
                final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}")
                final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') -
                    BigDecimal.new("#{te_proportion}"))
                final_score = final_te_score + final_s_score
                self.final_score = format("%.2f", final_score.to_f)
              end
            else
              if self.student_score.nil?
                te_proportion = tea_proportion + (1.0 - tea_proportion - tea_ass_proportion) / 2
                final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}")
                final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * (BigDecimal.new('1.0') -
                    BigDecimal.new("#{te_proportion}"))
                final_score = final_te_score + final_ta_score
                self.final_score = format("%.2f",final_score.to_f)
              else
                final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{tea_proportion}")
                final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}")
                final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') -
                    BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}"))
                final_score = final_te_score + final_ta_score + final_s_score
                self.final_score = format("%.2f",final_score.to_f)
              end
            end
          else
            if self.teaching_asistant_score.nil?
              self.final_score = self.student_score
            elsif self.student_score.nil?
              self.final_score = self.teaching_asistant_score
            else
              ta_proportion = tea_ass_proportion + tea_proportion / 2
              final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}")
              final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') -
                  BigDecimal.new("#{ta_proportion}"))
              final_score = final_ta_score + final_s_score
              self.final_score = format("%.2f",final_score.to_f)
            end
          end

        else
          self.final_score = self.teacher_score ? self.teacher_score :
                                 (self.teaching_asistant_score ? self.teaching_asistant_score : self.student_score)
        end

        # 作品最终得分work_score 等于作品得分 - 缺评扣分 - 迟交扣分 - 申诉扣分
        score = self.final_score.to_f - self.absence_penalty - self.late_penalty - self.appeal_penalty if self.final_score
        self.work_score = score ? format("%.2f",(score < 0 ? 0 : score).to_f) : nil

      when "practice"
        # 作品最终得分work_score 等于作品关卡得分 + 效率分 - 迟交扣分
        work_score = self.final_score + self.eff_score - self.late_penalty if self.final_score
        self.work_score = work_score ? format("%.2f", work_score < 0 ? 0 : work_score) : nil
      end
    end
  end

  def scored?
    student_works_scores.where.not(reviewer_role: 3).exists?
  end

  def work_challenge_score game, score
    game_score = 0
    adjust_score = challenge_work_scores.where(challenge_id: game.challenge_id).last
    if adjust_score.present?
      game_score = adjust_score.score
    else
      setting = homework_common.homework_group_setting user_id
      if game.status == 2 && ((game.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && game.end_time && game.end_time < homework_common.late_time))
        answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation
        game_score = answer_open_evaluation ? score : (game.final_score > 0 ? game.real_score(score) : 0)
      end
    end
    game_score
  end
end
