# 将试卷库中的试卷发送到课堂
class ExaminationBanks::SendToCourseService < ApplicationService
  attr_reader :exam, :exercise

  # exam: examination_bank 试卷库中的试卷
  # exercise: exercise.new 新建的试卷
  def initialize(exam, exercise)
    @exam = exam
    @exercise = exercise
  end

  def call
    # 先判断题库数量是否足够，不足的不允许发送
    # 根据试题来源先筛选试题,1私有题库,0公共加私有题库
    if exam.source == 1
      item_banks = ItemBank.where(user_id: User.current.id)
    elsif exam.source == 0
      item_banks = ItemBank.where(user_id: User.current.id).or(ItemBank.where(public: 1))
    end
    # 按照随机规则的配置，将试题分好组
    grouped_item_banks = {}
    exam.examination_bank_random_settings.each do |examination_bank_random_setting|
      # 是否正确筛选了?
      grouped_item_banks[examination_bank_random_setting.id] = item_banks.select do |item_bank|
        item_bank.difficulty == examination_bank_random_setting.difficulty &&
        item_bank.sub_discipline_id == examination_bank_random_setting.sub_discipline_id &&
        item_bank.item_type == examination_bank_random_setting.item_type
      end
      raise Educoder::TipException.new("题库数量小于随机规则配置的数量!") if grouped_item_banks[examination_bank_random_setting.id].size < examination_bank_random_setting.quanlity
    end

    ActiveRecord::Base.transaction do
      exercise.exercise_name = exam.name
      exercise.examination_bank_id = exam.id
      if exam.is_random?
        exercise.time = exam.time.present? ? exam.time : -1
      else
        exercise.time = exam.duration.present? ? exam.duration : -1
      end
      exercise.is_md = false
      # 随机组卷会用到的属性
      exercise.is_random = exam.is_random #是否为随机组卷
      exercise.source = exam.source #题目来源
      exercise.difficulty = exam.difficulty #试卷难度
      exercise.save!

      if exercise.is_random?
        # 如果是随机组卷的话，仅仅需要将随机规则发送过去
        exam.examination_bank_random_settings.each do |examination_bank_random_setting|
          exercise.exercise_random_settings.create!(
              difficulty: examination_bank_random_setting.difficulty,
              sub_discipline_id: examination_bank_random_setting.sub_discipline_id,
              quanlity: examination_bank_random_setting.quanlity,
              item_type: examination_bank_random_setting.item_type
          )
        end
        # 赋分规则
        exam.examination_bank_score_settings.each do |examination_bank_score_setting|
          exercise.exercise_score_settings.create!(
              item_type: examination_bank_score_setting.item_type,
              score: examination_bank_score_setting.score
          )
        end
      else
        exam.examination_items.except(:order).order("item_type asc, position asc").includes(:examination_item_choices, :container, :examination_item_analysis).each_with_index do |item, index|
          question = exercise.exercise_questions.new
          question.question_type = question_type item.item_type
          question.question_title = item.name
          question.question_number = index + 1
          question.question_score = item.score
          question.is_ordered = item.is_ordered

          if item.item_type == "PROGRAM"
            new_hack = item.container.fork
            new_hack.update!(status: 1)
            question.hack_id = new_hack.id
            question.save!
          else
            question.save!
            if item.item_type.in?(%W(COMPLETION SUBJECTIVE))
              item.examination_standard_answers.each do |standard_answer|
                question.exercise_standard_answers << ExerciseStandardAnswer.new(
                    answer_text: standard_answer.answer_text, exercise_choice_id: standard_answer.position
                )
              end
            end
            ExerciseQuestionAnalysis.new(analysis: item.analysis, exercise_question_id: question.id)
            item.examination_item_choices.each_with_index do |choice, position|
              question.exercise_choices << ExerciseChoice.new(choice_text: choice.choice_text, choice_position: position+1)
              if choice.is_answer
                question.exercise_standard_answers << ExerciseStandardAnswer.new(exercise_choice_id: position+1)
              end
            end
          end
        end
      end

      exam.increment!(:quotes)
    end
    exercise
  end

  def question_type item_type
    question_type = case item_type
                    when 'SINGLE'
                      Exercise::SINGLE
                    when 'MULTIPLE'
                      Exercise::MULTIPLE
                    when 'JUDGMENT'
                      Exercise::JUDGMENT
                    when 'COMPLETION'
                      Exercise::COMPLETION
                    when 'SUBJECTIVE'
                      Exercise::SUBJECTIVE
                    when 'PRACTICAL'
                      Exercise::PRACTICAL
                    when 'PROGRAM'
                      Exercise::PROGRAM
                    end
    question_type
  end
end