class HomeworkCommonsController < ApplicationController
  include HomeworkCommonsHelper
  include ApplicationHelper
  include ExportHelper

  before_action :require_login, :check_auth, except: [:index, :choose_category]

  before_action :find_course, only: [:index, :create, :new, :shixuns, :subjects, :create_shixun_homework, :publish_homework,
                                     :end_homework, :set_public, :move_to_category, :choose_category,
                                     :create_subject_homework, :multi_destroy, :add_to_homework_bank]
  before_action :find_homework, only: [:edit, :show, :update, :group_list, :homework_code_repeat, :code_review_results,
                                       :code_review_detail, :show_comment, :settings, :works_list, :update_settings,
                                       :reference_answer, :publish_groups, :end_groups, :alter_name, :update_explanation,
                                       :update_score, :update_student_score, :batch_comment]
  before_action :user_course_identity
  before_action :homework_publish, only: [:show, :works_list, :code_review_results, :show_comment, :settings, :reference_answer,
                                          :update_student_score]
  before_action :teacher_allowed, only: [:new, :edit, :create, :update, :shixuns, :subjects, :create_shixun_homework,
                                         :publish_homework, :end_homework, :set_public, :choose_category, :move_to_category,
                                         :choose_category, :create_subject_homework, :multi_destroy, :group_list, :homework_code_repeat,
                                         :code_review_results, :code_review_detail, :update_explanation, :update_settings,
                                         :add_to_homework_bank, :publish_groups, :end_groups, :batch_comment]
  before_action :require_id_params, only: [:set_public, :multi_destroy, :publish_homework, :end_homework, :move_to_category,
                                           :add_to_homework_bank]
  before_action :course_manager, only: [:alter_name]

  def index
    tip_exception("type参数有误") if params[:type] && ![1, 3, 4].include?(params[:type].to_i)
    @user = current_user
    search = "#{params[:search].to_s.strip.downcase}" if params[:search]
    order = params[:order]
    page = params[:page] ? params[:page].to_i : 1
    @homework_type = params[:type] ? params[:type].to_i : 4
    module_type = @homework_type == 4 ? "shixun_homework" : @homework_type == 1 ? "common_homework" : "group_homework"
    @homework_commons = @course.homework_commons.where(homework_type: @homework_type)
    @main_category = @course.course_modules.find_by(module_type: module_type)
    if !params[:category].blank?
      @category = @main_category.course_second_categories.find_by(id: params[:category])
      tip_exception("子目录id有误") if !@category.present?
      @homework_commons = @homework_commons.where(course_second_category_id: params[:category])
    end
    @all_count = @homework_commons.size

    @member = @course.course_members.find_by(user_id: current_user.id, is_active: 1)
    # 老师显示所有的作业、未分班学生显示统一设置的且已发布、否则对学生所在分班已发布的作业
    if @user_course_identity < Course::STUDENT
      @homework_commons = @homework_commons
    elsif @user_course_identity == Course::STUDENT
      if @member.try(:course_group_id).to_i == 0
        @homework_commons = @homework_commons.homework_published.unified_setting
      else
        not_homework_ids = @course.homework_group_settings.none_published.where("course_group_id = #{@member.try(:course_group_id)}").pluck(:homework_common_id)

        @homework_commons = @homework_commons.where.not(id: not_homework_ids).homework_published
      end
    else
      @homework_commons = @homework_commons.homework_published.unified_setting
    end

    @published_count = @user_course_identity < Course::STUDENT ? @homework_commons.homework_published.size :
                         @homework_commons.size

    unless search.blank?
      @homework_commons = @homework_commons.where("homework_commons.name like ?", "%#{search}%")
    end

    unless order.blank?
      if @course.is_end
        @homework_commons = @homework_commons.none
      else
        case order
        when '1'
          if @user_course_identity == Course::STUDENT
            unified_homework_ids = @homework_commons.published_no_end.unified_setting.pluck(:id)
            group_homework_ids = @course.homework_group_settings.where("course_group_id = #{@member.course_group_id&.to_i}").published_no_end.pluck(:homework_common_id)
            homework_ids = unified_homework_ids + group_homework_ids
            homework_ids = homework_ids.blank? ? "(-1)" : "(" + homework_ids.join(",") + ")"
            sql_str = %Q(homework_commons.id in #{homework_ids})
          else
            sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_commons.end_time > '#{Time.now}')
          end
        when '2'
          if @user_course_identity == Course::STUDENT
            unified_homework_ids = @homework_commons.homework_ended.unified_setting.pluck(:id)
            group_homework_ids = @course.homework_group_settings.where("course_group_id = #{@member.course_group_id&.to_i}").has_end.pluck(:homework_common_id)
            homework_ids = unified_homework_ids + group_homework_ids
            homework_ids = homework_ids.blank? ? "(-1)" : "(" + homework_ids.join(",") + ")"
            sql_str = %Q(homework_commons.id in #{homework_ids} and allow_late = 1 and (late_time is null or late_time > '#{Time.now}'))
          else
            sql_str = %Q(allow_late = 1 and homework_commons.end_time < '#{Time.now}' and (late_time is null or late_time > '#{Time.now}'))
          end
        when '3'
          sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.evaluation_end > '#{Time.now}')
        when '4'
          sql_str = %Q((homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.appeal_time > '#{Time.now}'))
        when '5'
          sql_str = %Q((anonymous_comment = 0 or (anonymous_comment = 1 and homework_detail_manuals.comment_status = #{order})) and ((allow_late= 0 and homework_commons.end_time <= '#{Time.now}') or (allow_late= 1 and late_time <= '#{Time.now}')))
        else
          sql_str = %Q(homework_detail_manuals.comment_status = #{order})
        end
        @homework_commons = @homework_commons.joins(:homework_detail_manual).where(sql_str)
      end
    end
    @task_count = @homework_commons.size

    order_str = @homework_type == 4 ? "homework_commons.position DESC" : "IF(ISNULL(homework_commons.publish_time),0,1), homework_commons.publish_time DESC,
                                                  homework_commons.created_at DESC"
    @homework_commons = @homework_commons.order(order_str).page(page).per(15)

    if @homework_type == 4
      @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :homework_group_settings, :shixuns, :course_second_category, user: :user_extension)
    elsif @homework_type == 3
      @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :homework_group_settings, :homework_detail_group, :course_second_category, user: :user_extension)
    else
      @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :homework_group_settings, :course_second_category, user: :user_extension)
    end
  end

  def works_list
    @current_user = current_user
    @member = @course.course_member(@current_user.id)

    @shixun = @homework.shixuns.take if @homework.homework_type == "practice"

    student_works = @homework.all_works
    @all_member_count = student_works.size

    if @homework.publish_time.blank? || (@homework.publish_time > Time.now)
      @student_works = []
      if (params[:format] == "xlsx") || (params[:format] == "zip")
        normal_status(-1, "作业未发布")
      end
    else
      if @user_course_identity == Course::STUDENT
        @work = @homework.user_work(current_user.id)
        # 学生访问列表时计算个人成绩
        if @homework.homework_type == "practice" && !@homework.end_or_late
          myshixun = Myshixun.find_by(shixun_id: @shixun.id, user_id: current_user.id)
          if @work && myshixun
            challenge_settings = @homework.homework_challenge_settings
            games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id))
            HomeworksService.new.update_myshixun_work_score @work, myshixun, games, @homework, challenge_settings
          end
        end

        # 学生已提交作品且补交(提交)已截止、作品公开、非匿评阶段
        if @work&.work_status.to_i > 0 && (@homework.work_public || @homework.score_open) &&
          ((!@homework.anonymous_comment && @homework.end_or_late) || (@homework_detail_manual.comment_status > 4 && @homework.end_or_late))
          @student_works = student_works.where("student_works.user_id != #{@work.user_id}")

          # 匿评、申诉阶段只能看到分配给自己的匿评作品
        elsif @work&.work_status.to_i > 0 && @homework.anonymous_comment && @homework_detail_manual.comment_status > 2 && @homework_detail_manual.comment_status <= 4
          @is_evaluation = true
          @student_works = student_works.joins(:student_works_evaluation_distributions).where(
            "student_works_evaluation_distributions.user_id = #{@current_user.id}")
        else
          @student_works = []
        end
        @score_open = @homework.score_open && @work&.work_status.to_i > 0
      elsif @user_course_identity < Course::STUDENT
        @student_works = @homework.teacher_works(@member)
        @all_member_count = @student_works.size
        @score_open = true
      elsif @user_course_identity > Course::STUDENT
        @student_works = student_works
        @score_open = false
      else
        @student_works = []
      end

      if @student_works.size > 0
        # 教师评阅搜索 0: 未评, 1 已评
        unless params[:teacher_comment].blank?
          student_work_ids = StudentWorksScore.where(student_work_id: @student_works.map(&:id)).pluck(:student_work_id)
          if params[:teacher_comment].to_i == 0
            @student_works = @student_works.where.not(id: student_work_ids)
          elsif params[:teacher_comment].to_i == 1
            @student_works = @student_works.where(id: student_work_ids)
          end
        end

        # 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
        if params[:work_status].present?
          params_work_status = params[:work_status]
          work_status = params_work_status.map {|status| status.to_i}
          if @homework.homework_type == "practice"
            @student_works = @student_works.where(compelete_status: work_status)
          else
            @student_works = @student_works.where(work_status: work_status)
          end
        end

        # 分班情况
        unless params[:course_group].blank?
          group_ids = params[:course_group]
          group_user_ids = @course.students.where(course_group_id: group_ids).pluck(:user_id)
          # 有分组只可能是老师身份查看列表
          @student_works = @student_works.where(user_id: group_user_ids)
        end

        if @homework.homework_type == "group" && !params[:member_work].blank?
          if params[:member_work].to_i == 1
            @student_works = @student_works.where("student_works.user_id = commit_user_id")
          elsif params[:member_work].to_i == 0
            @student_works = @student_works.where("student_works.user_id != commit_user_id")
          end
        end

        # 输入姓名和学号搜索
        # TODO user_extension 如果修改 请调整
        unless params[:search].blank?
          @student_works = @student_works.joins(user: :user_extension).where("concat(lastname, firstname) like ?
                         or student_id like ?", "%#{params[:search].strip}%", "%#{params[:search].strip}%")
        end

        @work_count = @student_works.size

        # 排序
        rorder = params[:order].blank? ? "update_time" : params[:order]
        b_order = params[:b_order].blank? ? "desc" : params[:b_order]
        if rorder == "update_time" || rorder == "work_score"
          @student_works = @student_works.order("student_works.#{rorder} #{b_order}")
        elsif rorder == "student_id"
          @student_works = @student_works.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
        end
        @work_excel = @student_works

        # 分页参数
        page = params[:page] || 1
        limit = params[:limit] || 20
        @student_works = @student_works.page(page).per(limit)
        if @homework.homework_type == "practice"
          @student_works = @student_works.includes(:student_works_scores, :shixun_work_comments, user: :user_extension, myshixun: :games)
        else
          @student_works = @student_works.includes(:student_works_scores, :project, user: :user_extension)
        end
        @students = @course.students.preload(:course_group)
      end

      if params[:format] == "xlsx"
        if @user_course_identity >= Course::STUDENT
          tip_exception(403, "无权限操作")
        elsif @work_excel.blank? || @work_excel.size == 0
          normal_status(-1, "暂无用户提交!")
        elsif params[:export].present? && params[:export]
          normal_status(0, "正在下载中")
        else
          respond_to do |format|
            format.xlsx {
              set_export_cookies
              student_work_to_xlsx(@work_excel, @homework)
              exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
              render xlsx: "#{exercise_export_name.strip}", template: "homework_commons/works_list.xlsx.axlsx", locals:
                {table_columns: @work_head_cells, task_users: @work_cells_column}
            }
          end
        end
      elsif params[:format] == "zip"
        if @user_course_identity >= Course::STUDENT
          tip_exception(403, "无权限操作")
        else
          if @work_excel.present?
            zip_works = @work_excel&.where("work_status > 0")
            status = checkfileSize(zip_works)
          else
            status = -1
          end

          if status == 0
            if params[:export].present? && params[:export]
              normal_status(0, "正在下载中")
            else
              respond_to do |format|
                format.zip {
                  set_export_cookies
                  zipfile = zip_homework_common @homework, zip_works
                  file = decode64(zipfile[0][:base64file])
                  send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip'
                }
              end
            end
          else
            normal_status(status, status == -2 ? "500M" : "无附件可下载")
          end
        end
      end
    end
  end

  def update_score
    tip_exception("作业还未发布,暂不能计算成绩") if @homework.publish_time.nil? || @homework.publish_time > Time.now
    @homework.update_homework_work_score
    normal_status("更新成功")
  end

  def update_student_score
    work = @homework.student_works.find_by(user_id: current_user.id)
    myshixun = Myshixun.find_by(shixun_id: params[:shixun_id], user_id: current_user.id)
    ActiveRecord::Base.transaction do
      if work && myshixun
        challenge_settings = @homework.homework_challenge_settings
        games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id))
        HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings
        normal_status("更新成功")
      else
        normal_status("还未开启挑战,暂不能更新成绩")
      end
    end
  end

  def alter_name
    tip_exception("作业名称不能为空") if params[:name].blank?
    @homework.update_attributes!(name: params[:name].strip)
    normal_status("更新成功")
  end

  def show
    @user = current_user
    @attachments = @homework.attachments.where(attachtype: 1)
    @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT
  end

  # 评论列表接口、 包含一级和二级评论的获取
  def show_comment
    @page = params[:page] || 1
    @limit = params[:limit] || 10
    @parent = params[:parent_id]
    @current_user = current_user

    @messages = @homework.journals_for_messages
    @messages_count = @messages.size
    @parent_messages_count = @messages.parent_comment.size

    if @parent
      @messages = @messages.where(m_parent_id: @parent)
    else
      @messages = @messages.parent_comment
    end

    @messages = @messages.includes(:praise_treads).page(@page).per(@limit).order("created_on desc")
  end

  def reference_answer
    # 只有课堂老师 或 作业设置了“公开答案”,则在作业截止时间后(若开启了补交,则补交截止后),提交了作品的学生 才能访问
    if @homework.view_answer(@user_course_identity, current_user.id)
      @attachments = @homework.attachments.where(attachtype: 2)
    else
      normal_status(403, "无权限访问")
    end
    @current_user = current_user
    @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT
  end

  def update_explanation
    @homework.update_attributes!(explanation: params[:explanation])
    normal_status(0, "更新成功")
  end

  def new
    tip_exception("type参数有误") if params[:type].blank? || ![1, 3].include?(params[:type].to_i)
    @homework_type = params[:type].to_i
    module_type = params[:type].to_i == 1 ? "common_homework" : "group_homework"
    @main_category = @course.course_modules.find_by(module_type: module_type)
    @category = @main_category.course_second_categories.find_by(id: params[:category]) if params[:category].present?
  end

  def create
    tip_exception("type参数有误") if params[:type].blank? || ![1, 3].include?(params[:type].to_i)
    @homework_type = params[:type].to_i
    if @homework_type == 3
      validate_min_max_num
      tip_exception("base_on_project参数不能为空") if params[:base_on_project].nil?
    end

    ActiveRecord::Base.transaction do
      @homework = HomeworkCommon.new(homework_params)
      @homework.reference_answer = params[:reference_answer].to_s.strip
      @homework.homework_type = @homework_type
      @homework.user_id = current_user.id
      @homework.course_id = @course.id

      if params[:category].present?
        category = @course.course_second_categories.find_by(id: params[:category])
        @homework.course_second_category_id = category&.id.to_i
      end

      homework_detail_manual = HomeworkDetailManual.new
      @homework.homework_detail_manual = homework_detail_manual
      homework_detail_manual.te_proportion = 0.7
      homework_detail_manual.ta_proportion = 0.3

      if @homework_type == 3
        homework_detail_group = HomeworkDetailGroup.new(min_num: params[:min_num].to_i, max_num: params[:max_num].to_i,
                                                        base_on_project: params[:base_on_project])
        @homework.homework_detail_group = homework_detail_group
      end

      if @homework.save!
        homework_detail_manual.save! if homework_detail_manual
        homework_detail_group.save! if homework_detail_group

        # 作业描述的附件
        Attachment.associate_container(params[:attachment_ids], @homework.id, @homework.class) if params[:attachment_ids]
        # 作业参考答案的附件
        Attachment.associate_container(params[:reference_attachment_ids], @homework.id, @homework.class, 2) if params[:reference_attachment_ids]

        HomeworksService.new.create_works_list(@homework, @course)
      else
        tip_exception("创建失败")
      end
    end
  end

  def edit
    if @homework.course_second_category_id == 0
      module_type = @homework.homework_type == "normal" ? "common_homework" : "group_homework"
      @main_category = @course.course_modules.find_by(module_type: module_type)
    else
      @category = @homework.course_second_category
    end
  end

  def update
    if @homework.homework_type == "group"
      validate_min_max_num
      tip_exception("base_on_project参数不能为空") if !@homework.has_relate_project && params[:base_on_project].nil?
    end

    ActiveRecord::Base.transaction do
      @homework.update_attributes!(homework_params)
      @homework.reference_answer = params[:reference_answer].to_s.strip

      if @homework.homework_type == "group"
        homework_detail_group = @homework.homework_detail_group
        param_min = params[:min_num].to_i
        param_max = params[:max_num].to_i
        homework_detail_group.min_num = @homework.has_commit_work ? [param_min, homework_detail_group.min_num].min : param_min
        homework_detail_group.max_num = @homework.has_commit_work ? [param_max, homework_detail_group.max_num].max : param_max
        homework_detail_group.base_on_project = params[:base_on_project] unless @homework.has_relate_project
        homework_detail_group.save!
      end
      # 作业描述的附件
      Attachment.associate_container(params[:attachment_ids], @homework.id, @homework.class) if params[:attachment_ids]
      # 作业参考答案的附件
      Attachment.associate_container(params[:reference_attachment_ids], @homework.id, @homework.class, 2) if params[:reference_attachment_ids]

      normal_status(0, "更新成功")

    end
  end

  def settings
    @user = current_user
    @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT
    @course_groups = @course.course_groups.where(id: @course.charge_group_ids(@user))
    @shixun = @homework.shixuns.take if @homework.homework_type == "practice"
  end

  def update_settings
    # 课堂结束后不能再更新
    unless @course.is_end

      # 发布设置
      UpdateHomeworkPublishSettingService.call(@homework, publish_params)

      # 补交设置
      tip_exception("缺少allow_late参数") if params[:allow_late].nil?
      tip_exception("缺少late_penalty参数") if params[:allow_late] && params[:late_penalty].blank?
      tip_exception("缺少late_time参数") if params[:allow_late] && params[:late_time].blank?

      current_late_penalty = @homework.late_penalty
      if params[:allow_late]
        tip_exception("补交结束时间必须晚于截止时间") if params[:late_time] <= strf_time(@homework.end_time)
        tip_exception("补交结束时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:late_time] >
          strf_time(@course.end_date.end_of_day)
        tip_exception("迟交扣分不能小于0") if params[:late_penalty] && params[:late_penalty].to_i < 0

        @homework.allow_late = true
        @homework.late_time = params[:late_time]
        @homework.late_penalty = params[:late_penalty].to_i
      else
        @homework.allow_late = false
        @homework.late_penalty = 0
        @homework.late_time = nil
      end

      # 迟交扣分有变动则更新迟交学生的成绩
      late_penalty_change = @homework.late_penalty != current_late_penalty

      if @homework.homework_type == "practice"

        # 实训作业的评分设置
        tip_exception("总分值不能为空") if params[:total_score].blank?
        tip_exception("总分值不能小于0") if params[:total_score].to_i < 0
        tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil?
        tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil?
        tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank?
        tip_exception("效率分不能小于等于0") if params[:work_efficiency] && params[:eff_score] && params[:eff_score].to_f <= 0
        tip_exception("效率分不能大于总分值") if params[:work_efficiency] && params[:eff_score] && params[:eff_score].to_f.round(2) > params[:total_score].to_f.round(2)
        tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank?
        tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank?
        # tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank?
        # tip_exception("缺少challenge_score参数") if params[:challenge_settings][:challenge_score].blank?
        # tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if
        #     params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length

        sum_challenge_score = params[:challenge_settings].pluck(:challenge_score).reject(&:blank?)&.map {|score| score.to_f}.sum
        total_score = params[:work_efficiency] ? (params[:eff_score].to_f + sum_challenge_score) : sum_challenge_score
        tip_exception("分值之和必须等于总分值:#{params[:total_score]}分") if params[:total_score].to_f.round(2) != total_score.to_f.round(2)

        current_eff_score = @homework.eff_score.to_f.round(2)
        @homework.total_score = params[:total_score]
        @homework.work_efficiency = params[:work_efficiency]
        @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_f.round(2) : 0

        update_eff_score = current_eff_score.round(2) != @homework.eff_score.round(2)

        if @homework_detail_manual.answer_open_evaluation != params[:answer_open_evaluation]
          @homework_detail_manual.answer_open_evaluation = params[:answer_open_evaluation]
          score_change = true
        end

        @homework_detail_manual.shixun_evaluation = params[:shixun_evaluation].to_i

        if params[:challenge_settings]
          params[:challenge_settings].each do |challenge|
            setting = @homework.homework_challenge_settings.find_by(challenge_id: challenge[:challenge_id])
            score = challenge[:challenge_score]
            if setting && setting.score != score
              score_change = true
              setting.update_attributes!(score: score)
            elsif setting.blank?
              score_change = true
              HomeworkChallengeSetting.create!(homework_common_id: @homework.id, challenge_id: challenge[:challenge_id],
                                               shixun_id: @homework.homework_commons_shixun.try(:shixun_id), score: score)
            end
          end

          if @homework.homework_challenge_settings.where.not(challenge_id: params[:challenge_settings].pluck(:challenge_id)).count > 0
            score_change = true
            @homework.homework_challenge_settings.where.not(challenge_id: params[:challenge_settings].pluck(:challenge_id)).destroy_all
          end
        end

        # 公开设置
        tip_exception("缺少score_open参数") if params[:score_open].nil?
        @homework.score_open = params[:score_open]

        @homework.save!
        if score_change && @homework.end_or_late_none_group
          UpdateShixunWorkScoreJob.perform_later(@homework.id)
        elsif update_eff_score && (@homework.end_or_late_none_group || @homework.max_efficiency > 0)
          # 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止 或者作业已计算过效率分)
          HomeworksService.new.update_student_eff_score HomeworkCommon.find_by(id: @homework.id)
        end

        # 更新迟交扣分
        if !(score_change || update_eff_score) && late_penalty_change
          @homework.student_works.where(work_status: 2).each do |work|
            work.late_penalty = @homework.late_penalty
            work.save!
          end
        end

        unless @homework.allow_late
          @homework.student_works.where(work_status: 2).update_all(work_status: 1)
        end

        @homework_detail_manual.save!
        @homework.save!
      else

        # 普通和分组作业的匿评设置
        current_absence_penalty = @homework_detail_manual.absence_penalty
        current_appeal_penalty = @homework_detail_manual.appeal_penalty

        # 匿评未开启前可以更新:是否开启匿评、匿评开始时间、匿评数
        if @homework_detail_manual.comment_status < 3
          tip_exception("缺少anonymous_comment参数") if params[:anonymous_comment].nil?
          # anonymous_comment :true 是启用,false 是不启用
          if params[:anonymous_comment]
            tip_exception("匿评开启时间不能为空") if params[:evaluation_start].blank?
            tip_exception("匿评开启时间不能早于截止时间") if params[:evaluation_start] < strf_time(@homework.end_time)
            tip_exception("匿评结束时间不能为空") if params[:evaluation_end].blank?
            tip_exception("匿评截止时间必须晚于匿评开启时间") if params[:evaluation_end] <= params[:evaluation_start]
            tip_exception("匿评截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:evaluation_end] >
              strf_time(@course.end_date.end_of_day)
            tip_exception("匿评数必须为正整数") if params[:evaluation_num].blank? || params[:evaluation_num].to_i < 1
            tip_exception("缺评扣分不能为空") if params[:absence_penalty].blank?
            tip_exception("缺评扣分不能小于0") if params[:absence_penalty].to_i < 0
            tip_exception("缺评扣分不能大于100") if params[:absence_penalty].to_i > 100
          end

          @homework.anonymous_comment = params[:anonymous_comment]
          @homework_detail_manual.evaluation_start = !@homework.anonymous_comment ? nil : params[:evaluation_start]
          @homework_detail_manual.evaluation_num = !@homework.anonymous_comment ? 0 : params[:evaluation_num]

          # 不启用匿评时还原申诉设置和教师、助教的评分比例
          unless @homework.anonymous_comment
            @homework.anonymous_appeal = false
            @homework_detail_manual.appeal_time = nil
            @homework_detail_manual.appeal_penalty = 0
            @homework_detail_manual.te_proportion = 1
            @homework_detail_manual.ta_proportion = 0
          end

        end

        # 匿评未截止时可以更新匿评结束时间
        if @homework_detail_manual.comment_status < 4
          tip_exception("匿评结束时间不能为空") if @homework.anonymous_comment && params[:evaluation_end].blank?
          tip_exception("匿评截止时间必须晚于匿评开启时间") if @homework.anonymous_comment &&
            params[:evaluation_end] <= strf_time(@homework_detail_manual.evaluation_start)
          tip_exception("匿评截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @homework.anonymous_comment &&
            @course.end_date.present? && params[:evaluation_end] > strf_time(@course.end_date.end_of_day)

          @homework_detail_manual.evaluation_end = !@homework.anonymous_comment ? nil : params[:evaluation_end]
        end

        # 作业未结束可以更新缺评扣分
        tip_exception("缺评扣分不能为空") if @homework.anonymous_comment && params[:absence_penalty].blank?
        tip_exception("缺评扣分不能小于0") if @homework.anonymous_comment && params[:absence_penalty].to_i < 0
        tip_exception("缺评扣分不能大于100") if @homework.anonymous_comment && params[:absence_penalty].to_i > 100
        @homework_detail_manual.absence_penalty = !@homework.anonymous_comment ? 0 : params[:absence_penalty].to_i


        # 匿评申诉设置
        # 匿评申诉未开启前可以更新:是否启用匿评申诉
        if @homework_detail_manual.comment_status < 4 && @homework.anonymous_comment
          tip_exception("缺少anonymous_appeal参数") if params[:anonymous_appeal].nil?
          @homework.anonymous_appeal = params[:anonymous_appeal]
        end


        # 匿评申诉未结束前可以更新:匿评申诉结束时间
        if @homework_detail_manual.comment_status < 5
          tip_exception("匿评申诉结束时间不能为空") if @homework.anonymous_appeal && params[:appeal_time].blank?
          tip_exception("匿评开启时间不能早于匿评截止时间") if @homework.anonymous_appeal &&
            params[:appeal_time] <= strf_time(@homework_detail_manual.evaluation_end)
          tip_exception("匿评申诉结束不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @homework.anonymous_appeal &&
            @course.end_date.present? && params[:appeal_time] > strf_time(@course.end_date.end_of_day)

          @homework_detail_manual.appeal_time = @homework.anonymous_appeal ? params[:appeal_time] : nil
        end

        # 作业未结束可以更新违规匿评扣分
        tip_exception("违规匿评扣分不能为空") if @homework.anonymous_appeal && params[:appeal_penalty].blank?
        tip_exception("违规匿评扣分不能小于0") if @homework.anonymous_appeal && params[:appeal_penalty].to_i < 0
        tip_exception("违规匿评扣分不能大于100") if @homework.anonymous_appeal && params[:appeal_penalty].to_i > 100
        @homework_detail_manual.appeal_penalty = @homework.anonymous_appeal ? params[:appeal_penalty].to_i : 0

        # 如果缺评扣分的设置有变更且匿评已截止
        absence_penalty_change = current_absence_penalty != @homework_detail_manual.absence_penalty &&
          @homework_detail_manual.comment_status >= 4
        # 如果违规匿评扣分的设置有变更且匿评已截止
        appeal_penalty_change = current_appeal_penalty != @homework_detail_manual.appeal_penalty &&
          @homework_detail_manual.comment_status >= 4

        # 评分设置
        tip_exception("助教评分模式不能为空") if params[:ta_mode].blank?

        # 助教评分模式的变更
        ta_mode_change = @homework_detail_manual.ta_mode != params[:ta_mode].to_i
        @homework_detail_manual.ta_mode = params[:ta_mode].to_i

        # 最终成绩组成
        tip_exception("最终成绩组成模式不能为空") if params[:final_mode].nil?

        final_mode_change = @homework_detail_manual.final_mode != params[:final_mode]
        @homework_detail_manual.final_mode = params[:final_mode]
        if !@homework_detail_manual.final_mode
          tip_exception("教师评分比例不能为空") if params[:te_proportion].blank?
          te_proportion = params[:te_proportion].to_f.round(2)
          tip_exception("教师评分比例不能小于0") if te_proportion < 0
          tip_exception("助教评分比例不能为空") if params[:ta_proportion].blank?
          ta_proportion = params[:ta_proportion].to_f.round(2)
          tip_exception("助教评分比例不能小于0") if ta_proportion < 0
          if !@homework.anonymous_comment
            tip_exception("评分比例之和不能大于100") if (te_proportion + ta_proportion) > 1.0
          else
            tip_exception("学生评分比例不能为空") if params[:st_proportion].blank?
            st_proportion = params[:st_proportion].to_f.round(2)
            tip_exception("学生评分比例不能小于0") if st_proportion < 0
            tip_exception("评分比例之和不能大于100") if (te_proportion + ta_proportion + st_proportion) > 1.0
          end

          proportion_change = @homework_detail_manual.te_proportion.round(2) != te_proportion ||
            @homework_detail_manual.ta_proportion.round(2) != ta_proportion
          @homework_detail_manual.te_proportion = te_proportion
          @homework_detail_manual.ta_proportion = ta_proportion
        else
          @homework_detail_manual.te_proportion = 1
          @homework_detail_manual.ta_proportion = 0
        end

        # 公开属性设置
        tip_exception("缺少work_public参数") if params[:work_public].nil?
        tip_exception("缺少score_open参数") if params[:score_open].nil?
        tip_exception("缺少answer_public参数") if params[:answer_public].nil?
        @homework.work_public = params[:work_public]
        @homework.score_open = params[:score_open]
        @homework.answer_public = params[:answer_public]

        @homework_detail_manual.save!
        @homework.save!

        # 迟交扣分、缺评扣分、违规匿评扣分、助教评分模式变更、最终成绩组成、评分比例变更都需要更新学生成绩
        if late_penalty_change || absence_penalty_change || appeal_penalty_change || ta_mode_change ||
          final_mode_change || proportion_change

          student_works = @homework.student_works.has_committed
          work_ids = student_works.pluck(:id)

          student_works.each do |student_work|
            # 迟交扣分
            student_work.late_penalty = student_work.work_status == 1 ? 0 : @homework.late_penalty

            # 缺评扣分的更新 如果之前的作业缺评扣分为0,则需重新计算缺评次数
            if absence_penalty_change
              absence_penalty_count = current_absence_penalty == 0 ? student_work.absence_count :
                                        (student_work.absence_penalty / current_absence_penalty).to_i
              student_work.absence_penalty = absence_penalty_count * @homework_detail_manual.absence_penalty
            end

            # 违规匿评扣分 如果之前的作业违规扣分为0,则需重新计算违规匿评次数
            if appeal_penalty_change
              appeal_penalty_count = current_appeal_penalty == 0 ? student_work.appeal_count :
                                       (student_work.appeal_penalty / current_appeal_penalty).to_i
              student_work.appeal_penalty = appeal_penalty_count * @homework_detail_manual.appeal_penalty
            end

            # 助教模式变更且有助教评分记录时才更新
            if ta_mode_change && student_work.student_works_scores.where("reviewer_role = 2 AND score IS NOT NULL").count > 0
              student_work.teaching_asistant_score = student_work.ta_score @homework_detail_manual.ta_mode
            end

            student_work.save!
          end
        end

      end
      normal_status(0, "更新成功")
    else
      tip_exception("课堂已结束不能再更新")
    end
    # rescue ActiveRecord::RecordInvalid
    #   render_error("保存失败")
    # rescue ApplicationService::Error => ex
    #   uid_logger(ex.message)
    #   render_error(ex.message)
    #   raise ActiveRecord::Rollback
  end

  # 选用实训
  def shixuns
    @main_catrgory = @course.course_modules.where(module_type: "shixun_homework")
    @homework_category = @main_catrgory.take.course_second_categories

    search = params[:search]
    type = params[:type]
    # 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
    if current_user.admin_or_business?
      @shixuns = Shixun.unhidden
    else
      none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)

      @shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
    end

    # 实训的所有标签
    @tags = TagRepertoire.select([:id, :name]).joins(:shixuns).where(shixuns: {id: @shixuns}).distinct

    if params[:search] && params[:search].strip != ""
      @shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?",
                                             "%#{search}%", "%#{search}%").distinct
    end

    unless type.blank? || type == "all"
      @shixuns = @shixuns.joins(:shixun_tag_repertoires).where(shixun_tag_repertoires: {tag_repertoire_id: type}).distinct
    end

    @shixuns = @shixuns.select([:id, :name, :status, :myshixuns_count, :identifier, :user_id, :trainee])
    @total_count = @shixuns.size

    ## 分页参数
    page = params[:page] || 1
    @shixuns = @shixuns.reorder("shixuns.created_at desc").includes(:challenges, user: [user_extension: :school]).page(page).per(10)
  end

  def create_shixun_homework
    tip_exception("请至少选择一个实训") if params[:shixun_ids].blank?
    order_ids = params[:shixun_ids].size > 0 ? params[:shixun_ids].reverse.join(',') : -1
    shixuns = Shixun.where(id: params[:shixun_ids]).order("field(id, #{order_ids})")
    @homework_ids = []
    unless params[:category_id].blank?
      @category = @course.course_second_categories.find_by(id: params[:category_id], category_type: "shixun_homework")
    end
    shixuns.each do |shixun|
      homework = HomeworksService.new.create_homework shixun, @course, @category, current_user
      @homework_ids << homework.id
      CreateStudentWorkJob.perform_later(homework.id)
    end
  end

  # 选用实训课程
  def subjects
    @tags = Repertoire.where(nil).order("updated_at desc")
    # select = params[:select]  # 路径导航类型
    select = params[:type] # 路径导航类型
    reorder = params[:order] || "myshixun_count"
    sort = params[:sort] || "desc"
    search = params[:search]

    ## 分页参数
    page = params[:page] || 1
    limit = params[:limit] || 15
    offset = (page.to_i - 1) * limit

    # 最热排序
    if reorder == "myshixun_count"
      if select && select != "all"
        @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status,
                            subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
                            on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where
                            subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%'
                            AND subjects.repertoire_id = #{select} GROUP BY subjects.id ORDER BY myshixun_member_count #{sort}")
      else
        @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status,
                            subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
                            on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where
                            subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%'
                            GROUP BY subjects.id ORDER BY myshixun_member_count #{sort}")
      end
    else
      # 我的路径
      if reorder == "mine"
        mine_subject_id = StageShixun.find_by_sql("select DISTINCT(subject_id) from stage_shixuns where shixun_id in
                                                (select distinct(shixun_id) from myshixuns where user_id=#{current_user.id})").map(&:subject_id)
        manage_subject_id = SubjectMember.where(user_id: current_user.id).pluck(:subject_id)
        total_subject_id = (mine_subject_id + manage_subject_id).uniq
        @subjects = Subject.where(id: total_subject_id)
      end

      # 类型
      if select && select != "all"
        @subjects = @subjects.where(repertoire_id: select)
      end

      if search.present?
        @subjects = @subjects.where("name like ?", "%#{search}%")
      end

      # 排序
      order_str = "updated_at #{sort}"
      @subjects = @subjects.reorder(order_str)
    end

    @total_count = @subjects.size

    if reorder != "myshixun_count"
      # @subjects = @subjects.page(page).per(limit).includes(:shixuns, user: [user_extension: :school])
      @subjects = @subjects.page(page).per(limit).includes(:shixuns)
    else
      @subjects = @subjects[offset, limit]
      unless @subjects.blank?
        subject_ids = @subjects.pluck(:id)
        order_ids = subject_ids.size > 0 ? subject_ids.join(',') : -1
        # @subjects = Subject.where(id: subject_ids).order("field(id,#{order_ids})").includes(:shixuns, user: [user_extension: :school])
        @subjects = Subject.where(id: subject_ids).order("field(id,#{order_ids})").includes(:shixuns)
      end
    end
  end

  def create_subject_homework
    tip_exception("请至少选择一个实训课程") if params[:subject_ids].blank?
    subjects = Subject.where(id: params[:subject_ids], status: 2).includes(stages: :shixuns).reorder("id desc")
    @homework_ids = []

    # none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)

    course_module = @course.course_modules.find_by(module_type: "shixun_homework")
    subjects.each do |subject|
      shixun_ids = subject.shixuns.where(use_scope: 0).pluck(:id) +
        subject.shixuns.joins(:shixun_schools).where("school_id = #{current_user.try(:school_id).to_i} and use_scope = 1").pluck(:id)

      subject.stages.each do |stage|

        # 为实训作业创建与stage同名的子目录
        category = CourseSecondCategory.find_by(name: stage.name, course_id: @course.id, category_type: "shixun_homework") ||
          CourseSecondCategory.create!(name: stage.name, course_id: @course.id, category_type: "shixun_homework",
                                       course_module_id: course_module.id, position: course_module.course_second_categories.count + 1)

        # 去掉不对当前用户的单位公开的实训,已发布的实训
        stage.shixuns.no_jupyter.where(id: shixun_ids).unhidden.each do |shixun|
          homework = HomeworksService.new.create_homework shixun, @course, category, current_user
          @homework_ids << homework.id
          CreateStudentWorkJob.perform_later(homework.id)
        end
      end
    end
  end

  def publish_groups
    @current_user = current_user
    charge_ids = @course.charge_group_ids(@current_user)
    if @homework.publish_immediately charge_ids
      # 可立即发布的分班:当前用户管理的分班去除已发布的分班
      group_ids = @course.charge_group_ids(@current_user) - @homework.homework_group_settings.group_published.pluck(:course_group_id)
      @course_groups = @course.course_groups.where(id: group_ids)
      @group_settings = @homework.homework_group_settings.where(course_group_id: group_ids)
    else
      tip_exception("没有可发布的分班")
    end
  end

  def publish_homework
    tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0
    group_ids = params[:group_ids]&.reject(&:blank?)&.map(&:to_i)
    if params[:detail].blank?
      tip_exception("缺少截止时间参数") if params[:end_time].blank?
      tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
      tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
    else
      tip_exception("缺少分班截止时间参数") if params[:group_end_times].blank?
      group_end_times = params[:group_end_times].reject(&:blank?)&.map {|time| time.to_time}
      tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length
      group_end_times.each do |time|
        tip_exception("分班截止时间不能早于当前时间") if time <= Time.now
        tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && time > @course.end_date.end_of_day
      end
    end

    homeworks = @course.homework_commons.where(id: params[:homework_ids])
    homeworks = homeworks.includes(:homework_group_settings, :homework_detail_manual)

    charge_group_ids = @course.charge_group_ids(current_user)
    publish_groups = charge_group_ids & group_ids if group_ids

    # ActiveRecord::Base.transaction do
    homeworks.each do |homework|
      # 作业未发布时
      if homework.homework_detail_manual.try(:comment_status) == 0
        if !params[:group_ids].blank?

          # 全选即统一设置,unified_setting为true
          if @course.course_groups.where(id: publish_groups).size == @course.course_groups.size &&
            ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?)
            homework.homework_group_settings.destroy_all
            homework.unified_setting = true
            homework.end_time = params[:detail] ? group_end_times.max : params[:end_time]
          else
            homework.unified_setting = false
            # 创建作业分班设置:homework_group_setting
            homework.create_homework_group_settings

            # 选中的分班设置的发布时间改为当前时间,截止时间改为传的截止时间参数
            if params[:detail]
              group_ids.each_with_index do |group_id, index|
                homework.homework_group_settings.find_by(course_group_id: group_id)&.update_attributes!(publish_time: Time.now,
                                                                                                        end_time: group_end_times[index])
              end
            else
              homework.homework_group_settings.where(course_group_id: publish_groups).update_all(publish_time: Time.now,
                                                                                                 end_time: params[:end_time])
            end
            # 发消息
            tiding_group_ids = publish_groups
          end
        else
          homework.homework_group_settings.destroy_all
          # students = @course.students
        end

        homework.publish_time = Time.now

        # 截止时间的处理
        if homework.end_time.nil?
          homework.end_time = params[:detail] ? group_end_times.max : params[:end_time]
        elsif homework.max_group_end_time
          homework.end_time = homework.max_group_end_time
        end
        homework.homework_detail_manual.update_attributes!(comment_status: 1)

        if homework.course_act.blank?
          CourseActivity.create!(user_id: homework.user_id, course_id: homework.course_id, course_act: homework)
        end
        # 发消息
        HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids)
      else
        homework.create_homework_group_settings

        none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published
        if params[:detail]
          group_ids.each_with_index do |group_id, index|
            none_publish_settings.find_by(course_group_id: group_id)&.update_attributes!(publish_time: Time.now,
                                                                                         end_time: group_end_times[index])
          end
        else
          none_publish_settings.update_all(publish_time: Time.now, end_time: params[:end_time])
        end

        if homework.max_group_end_time
          homework.end_time = homework.max_group_end_time
        end
        HomeworkCommonPushNotifyJob.perform_later(homework.id, none_publish_settings.pluck(:course_group_id))
      end


      if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1
        homework.homework_detail_manual.update_attributes!(comment_status: 1)
      end

      # 补交结束时间
      homework.late_time = Time.at(homework.end_time.to_i + 30 * 24 * 3600) if homework.allow_late && homework.late_time.nil?

      homework.save!

      # 更新学生状态及成绩(手动点击计算)
      # HomeworkPublishUpdateWorkStatusJob.perform_later(tiding_group_ids, homework.id)
    end
    normal_status(0, "发布成功")

    # end
  end

  def end_groups
    @current_user = current_user
    charge_ids = @course.charge_group_ids(@current_user)
    if @homework.end_immediately charge_ids
      # 可立即截止的分班:统一设置则是用户管理的所有分班,否则是当前用户管理的分班中已发布且未截止的
      charge_group_ids = @course.charge_group_ids(@current_user) # 当前用户管理的分班
      group_ids = @homework.unified_setting ? charge_group_ids :
                    @homework.homework_group_settings.where(course_group_id: charge_group_ids).published_no_end.pluck(:course_group_id)
      @course_groups = @course.course_groups.where(id: group_ids)
    else
      tip_exception("没有可截止的分班")
    end
  end

  def end_homework
    tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0

    time = Time.now

    # 已发布且未截止的作业才能立即截止

    homeworks = @course.homework_commons.where(id: params[:homework_ids])
    homeworks = homeworks.published_no_end.includes(:homework_group_settings, :homework_detail_manual, :homework_challenge_settings)
    course_students = @course.students
    charge_group_ids = @course.charge_group_ids(current_user)
    group_ids = params[:group_ids]&.reject(&:blank?)&.map(&:to_i)
    end_groups = charge_group_ids & group_ids if group_ids

    homeworks.each do |homework|
      ActiveRecord::Base.transaction do
        homework_detail_manual = homework.homework_detail_manual

        # 分组设置
        if !params[:group_ids].blank?
          # 确保之前是统一设置或者有新创建的分班的数据一致性
          homework.create_homework_group_settings

          homework.unified_setting = false if homework.unified_setting && end_groups.length != @course.course_groups_count

          # 已发布且未截止的分班
          none_end_settings = homework.homework_group_settings.where(course_group_id: end_groups).published_no_end

          none_end_settings.update_all(end_time: time)
          student_works = homework.student_works.where(user_id: course_students.where(course_group_id: none_end_settings.
            pluck(:course_group_id)).pluck(:user_id)).has_committed if homework.homework_type == "practice"

          homework.end_time = homework.max_group_end_time
          if homework.end_time > time && homework_detail_manual.try(:comment_status) > 1
            homework_detail_manual.update_attributes!(comment_status: 1)
          end

          # 统一设置
        elsif homework.unified_setting
          student_works = homework.student_works.has_committed if homework.homework_type == "practice"
          homework.end_time = time
        end

        # homework_detail_manual.update_attributes!(comment_status: 2) if homework.end_time <= time

        # 实训作业的作品需要计算是否迟交
        if homework.homework_type == "practice"
          # shixun = homework.shixuns.first
          # homework_challenge_settings = homework.homework_challenge_settings
          unless student_works.blank?
            student_works.joins(:myshixun).where("myshixuns.status != 1").update_all(late_penalty: homework.late_penalty) if homework.allow_late
          end
        end
        homework.save!
      end
      HomeworkEndUpdateScoreJob.perform_later(homework.id) if !homework.allow_late && homework.end_time <= time
    end
    normal_status(0, "更新成功")
  end

  def set_public
    tip_exception("仅公开课堂才能公开作业") if @course.is_public == 0
    homeworks = @course.homework_commons.where(id: params[:homework_ids])
    homeworks.update_all(is_public: 1)
    normal_status(0, "更新成功")
  end

  def choose_category
    @main_catrgory = @course.course_modules.where(module_type: "shixun_homework")
    @homework_category = @main_catrgory.take.course_second_categories.includes(:homework_commons)
  end

  # 实训作业移动到目录
  def move_to_category
    tip_exception("请选择要移动的目录") if params[:new_category_id].blank?

    category = @course.course_second_categories.find_by(id: params[:new_category_id])
    if params[:new_category_id].to_i == 0 || category.present?
      homeworks = @course.homework_commons.where(id: params[:homework_ids])

      homeworks.update_all(course_second_category_id: params[:new_category_id])
      normal_status(0, "更新成功")
    else
      normal_status(-1, "目录不存在")
    end
  end

  # 删除多个作业
  def multi_destroy
    ActiveRecord::Base.transaction do
      homeworks = @course.homework_commons.where(id: params[:homework_ids])
      homeworks.destroy_all

      # 这些写是因为model中的关联删除无法删除is_delete=0的作品
      StudentWork.where(homework_common_id: homeworks.pluck(:id)).destroy_all
      normal_status(0, "删除成功")

    end
  end

  #加入到题库
  def add_to_homework_bank
    homeworks = @course.homework_commons.where(id: params[:homework_ids])

    homeworks.each do |homework|
      ActiveRecord::Base.transaction do
        homework_bank = current_user.homework_banks.find_by(homework_common_id: homework.id)
        if homework_bank.present?
          # 如果作业加入过题库则更新参数
          if homework_bank.homework_type == 1
            homework_bank.update_attributes!(name: homework.name, description: homework.description,
                                             reference_answer: homework.reference_answer, course_list_id: @course.course_list_id)
          elsif homework_bank.homework_type == 3
            homework_detail_group = homework.homework_detail_group
            homework_bank.update_attributes!(name: homework.name, description: homework.description,
                                             reference_answer: homework.reference_answer, course_list_id: @course.course_list_id,
                                             min_num: homework_detail_group.min_num, max_num: homework_detail_group.max_num,
                                             base_on_project: homework_detail_group.base_on_project)
          end

          # 附件的更新
          homework_bank.attachments.destroy_all
          homework.attachments.each do |attachment|
            att = attachment.copy
            att.author_id = homework_bank.user_id
            att.copy_from = attachment.id
            homework_bank.attachments << att
          end
        else
          new_homework_bank = add_to_homework_bank_f homework
          new_homework_bank.save!

          homework.update_attributes!(homework_bank_id: new_homework_bank.id)
        end

      end
    end
    normal_status(0, "加入成功")
  end

  # 代码查重分班列表
  def group_list
    @page = params[:page] || 1
    @limit = params[:limit] || 10
    @course_member_count = @course.course_groups.count
    @course_groups = @course.course_groups.page(@page).per(@limit)
    @ungroup_user_ids = @course.course_members.ungroup_students.pluck(:user_id)
  end

  # 班级作品查重
  def homework_code_repeat
    tip_exception(-1, "分班id不能为空!") if params[:group_ids].nil?
    shixun = @homework.shixuns.take
    # 通过代码文件来判断语言
    language = shixun.challenges.practice_type.pluck(:path).first
    language = language.split(";")[0].split(".").last.downcase if language.present?
    user_lists = []
    if language.present? && (language == "java" || language == "py")
      user_ids = @course.course_members.where(course_group_id: params[:group_ids]).distinct(:user_id).pluck(:user_id)
      challenge_ids = @homework.homework_challenge_settings.pluck(:challenge_id)
      challenge_ids = challenge_ids.size == 0 ? "(-1)" : "(#{challenge_ids.join(",")})"
      user_ids.each do |user_id|
        code_infos = []
        games = Game.find_by_sql("select games.* from games right join myshixuns ms on games.myshixun_id = ms.id where
                                    games.user_id = #{user_id} and games.status = 2 and ms.shixun_id = #{shixun.id} and
                                    games.challenge_id in #{challenge_ids}")
        games.each do |game|
          game.game_codes.each do |game_code|
            code_infos << {
              path: game_code.path,
              content: Base64.urlsafe_encode64(game_code.new_code.to_s, padding: false),
              passed_time: game.end_time.try(:strftime, '%Y-%m-%d %H:%M:%S')
            }
          end
        end
        if code_infos.size != 0
          user_lists << {
            user_id: user_id,
            code_info: code_infos
          }
        end
      end
      result = ReviewService.check(user_lists, language == "py" ? "python" : "java")
      if result.status == 0
        params[:group_ids].each do |group_id|
          @homework.homework_group_reviews << HomeworkGroupReview.new(:course_group_id => group_id,
                                                                      :user_id => current_user.id,
                                                                      :query_id => result.query_id)
        end
        normal_status("代码查重成功")
      else
        if result.status == 1
          tip_exception(-4, "代码查重异常,请稍后重试")
        else
          tip_exception(-3, "正在查重,请在几分钟后刷新页面查看结果")
        end
      end
    else
      tip_exception(-2, "平台目前支持java、python语言的查重<br/>其他语言正在规划中,敬请期待")
    end
  end


  # 代码查重届结果
  def code_review_results
    # 如果有未获取结果的查重操作 则先读取结果
    get_new_code_reviews_result @homework
    @current_user = current_user

    # 列表数据
    rorder = params[:order] || "code_rate"
    sort = params[:sort] || "desc"
    page = params[:page] || 1
    limit = params[:limit] || 15
    student_works = @homework.student_works.where("work_status > 0")
    # 按分班id搜索
    user_ids =
      if params[:group_ids]
        # 筛选了分班
        group_student_ids = @course.course_members.where(course_group_id: params[:group_ids]).pluck(:user_id)
        student_works.where(:user_id => group_student_ids).pluck(:user_id)
      else
        # 如果当前用户有分班 显示分班内的学生,没有则显示全部
        user_ids = @course.user_group_students(current_user.id).pluck(:user_id)
        if user_ids.present?
          student_works.where(:user_id => user_ids).pluck(:user_id)
        else
          student_works.pluck(:user_id)
        end
      end
    # 查询作品数总数
    @all_reviews_count = user_ids.count
    @users_reviews = @homework.homework_review_results.where("code_rate >= 50.0")
                       .where(:user_id => user_ids).joins(user: :user_extension)
    # 按学号和姓名搜索
    if params[:search]
      @users_reviews = @users_reviews.where("concat(lastname, firstname) like :keyword or student_id like :keyword", keyword: "%#{params[:search]}%")
    end
    # 抄袭作品数
    @copy_reviews_count = @users_reviews.count
    # 排序搜索
    @users_reviews = @users_reviews.order("#{rorder} #{sort}").page(page).per(limit)
    # 获取所有查重过的分班
    @course_groups = @course.course_groups.where(id: @homework.homework_group_reviews.pluck(:course_group_id).uniq)

    # 如果未分班被查重过,则显示未分班列
    @non_course_group =
      if @homework.homework_group_reviews.where(course_group_id: 0).count > 0
        @course.course_members.where(role: 4, course_group_id: 0).count
      end

    # 最新一次的查重时间
    @last_review_time = format_time @homework.homework_group_reviews.last.try(:created_at)
    @charge_ids = @course.charge_group_ids(@current_user)
  end

  # 代码查重代码的详情
  def code_review_detail
    @student_work = @homework.student_works.find_by(user_id: params[:user_id])
    @user = @student_work.user
    tip_exception("当前用户无作品可以显示") if @student_work.nil?
    # 查询最新一次的查重标识query_id
    group_id = @course.students.where(user_id: params[:user_id]).pluck(:course_group_id).first
    homework_group_review = @homework.homework_group_reviews.where(:course_group_id => group_id).last || @homework.homework_group_reviews.last
    query_id = homework_group_review.try(:query_id)
    Rails.logger.info("##################------query_id: #{query_id}")
    tip_exception(-1, "query_id有误") unless query_id.present?

    results = ReviewService.query_result({user_id: params[:user_id], query_id: query_id})
    @shixun = @homework.shixuns.take
    if results.status == 0
      code_info = results.code_info
      homework_challenge_settings = @homework.homework_challenge_settings
      @challenges = @shixun.challenges.where(id: homework_challenge_settings.pluck(:challenge_id), st: 0)
      @challenges =
        @challenges.map do |challenge|
          code_rate = 0
          game_codes = results.code_info.select {|info| challenge.path.split(";").include?(info.origin_path)}
          # 先判断用户该关卡是否查重了  取多个待补充文件的平均值
          if game_codes.count > 0
            code_rate += game_codes.map(&:rate).sum / challenge.path.split(";").length
          end
          logger.info("#####game_codes: #{game_codes}")
          #target = game_codes.count > 0 ? game_codes[0].target_user_id : nil
          # 作品完成时间
          game = challenge.games.find_by(user_id: @user.id)
          end_time = game.end_time
          # 用户关卡的得分
          all_score = homework_challenge_settings.find_by(challenge_id: challenge.id).try(:score).to_f
          final_score = @student_work.work_challenge_score game, all_score, challenge.id
          # 抄袭用户
          copy_user = User.find_by_id(game_codes[0].try(:target_user_id))
          copy_end_time = copy_user.games.find_by(challenge_id: challenge.id).try(:end_time) if copy_user.present?
          # 代码部分
          code_list = []
          challenge.path.split(";").each do |path|
            if code_info.select {|info| path == info.origin_path}.size > 0
              info = code_info.select {|info| path == info.origin_path}[0]
              code_list << {path: path, origin_content: info.origin_content, target_content: info.target_content}
            end
          end
          # TODO: 这里本来应该前端做的,但是现在页面已经刷不开了。
          {code_rate: code_rate, copy_user_id: copy_user.try(:id), end_time: end_time, final_score: final_score,
           all_score: all_score, copy_end_time: copy_end_time, copy_username: copy_user.try(:full_name),
           username: game.user.full_name, code_list: code_list, subject: challenge.subject, position: challenge.position,
           id: challenge.id}
        end

    else
      if results.status == 1
        tip_exception(-1, "代码查重异常,请稍后重试")
      else
        tip_exception(-2, "代码查重正在执行中,请稍后")

      end
    end

  end

  def batch_comment
    tip_exception(-1, "作业还未发布,不能评阅") if @homework_detail_manual.comment_status == 0
    tip_exception("请至少输入一个评阅") if params[:comment].blank? && params[:hidden_comment].blank?
    ActiveRecord::Base.transaction do
      work_ids = @homework.student_works.where(work_status: [1, 2], user_id: @course.teacher_group_user_ids(current_user.id)).pluck(:id)
      has_comment_ids = ShixunWorkComment.where(challenge_id: 0, student_work_id: work_ids, batch_comment: 0).pluck(:student_work_id)
      batch_comment_works = ShixunWorkComment.where(challenge_id: 0, student_work_id: work_ids, batch_comment: 1)
      batch_comment_works.update_all(comment: params[:comment], hidden_comment: params[:hidden_comment])
      work_ids = work_ids - has_comment_ids - batch_comment_works.pluck(:student_work_id)
      # @homework.student_works.where(work_status: 0, id: work_ids).update_all(work_status: 1, commit_time: @homework.end_time, update_time: Time.now, work_score: 0, final_score: 0)
      HomeworkBatchCommentJob.perform_later(params[:comment], params[:hidden_comment], work_ids, @homework.id, current_user.id)
      normal_status("评阅成功")
    end
  end

  private

  def find_homework
    begin
      @homework = HomeworkCommon.find(params[:id])
      @course = @homework.course
      @homework_detail_manual = @homework.homework_detail_manual
    rescue Exception => e
      uid_logger(e.message)
      tip_exception("id不存在")
    end
  end

  def homework_params
    tip_exception("标题不能为空") if params[:name].blank?
    tip_exception("内容不能为空") if params[:description].blank?
    params.require(:homework_common).permit(:name, :description, :reference_answer)
  end

  def require_id_params
    tip_exception("请至少选择一个作业") if params[:homework_ids].blank?
    tip_exception("批量设置不能超过15个") if params[:homework_ids].length > 15 && params[:type].blank?
  end

  def validate_min_max_num
    tip_exception("min_num参数不能为空") if params[:min_num].blank?
    tip_exception("max_num参数不能为空") if params[:max_num].blank?
    tip_exception("最小人数不能小于1") if params[:min_num].to_i < 1
    tip_exception("最大人数不能小于最小人数") if params[:max_num].to_i < params[:min_num].to_i
  end

  def validate_absence_penalty

  end

  def get_new_code_reviews_result homework
    if homework.code_reviews_new_results?
      # 获取最新的查询id
      query_id = homework.homework_group_reviews.where(status: 0).last.try(:query_id)
      results = ReviewService.query_result({query_id: query_id})
      if results.status == 0
        shixun = homework.shixuns.take
        challenges = shixun.challenges.where(id: homework.homework_challenge_settings.pluck(:challenge_id), st: 0)
        challenge_count = challenges.count
        Rails.logger.info("#####results_user_list: #{results.user_lists.to_json}")
        results.user_lists.map(&:user_id).uniq.each do |user|
          user_rate = 0
          # 计算每个关卡的相似度
          challenges.each do |challenge|
            game_codes = results.user_lists.select {|user_list| user_list.user_id == user &&
              challenge.path.split(";").include?(user_list.origin_path)}
            # 先判断用户该关卡是否查重了  取多个待补充文件的平均值
            if game_codes.count > 0
              user_rate += game_codes.map(&:rate).sum / challenge.path.split(";").length
            end
          end
          user_rate = challenge_count == 0 ? 0 : user_rate / challenge_count

          # 如果用户已有查重记录则更新相似度  否则新建一条记录
          user_review = homework.homework_review_results.find_by(:user_id => user)
          if user_review.present?
            user_review.update_attributes!(:code_rate => user_rate)
          else
            homework.homework_review_results.create!(:user_id => user, :code_rate => user_rate)
          end
        end
        nuser_ids = results.user_lists.map(&:user_id).uniq
        homework.homework_review_results.where.not(user_id: nuser_ids).destroy_all
        homework.homework_group_reviews.where(status: 0).update_all(status: 1)
      elsif results.status == 2
        tip_exception(-2, "代码查重正在执行中,请稍后")
      else
        tip_exception(-1, "代码查重异常,请稍后重试")
      end
    end
  end

  def add_to_homework_bank_f homework
    homework_bank = HomeworkBank.new(name: homework.name, description: homework.description, user_id: current_user.id,
                                     homework_type: homework.homework_type == "normal" ? 1 : 3, quotes: 1, is_public: 0,
                                     homework_common_id: homework.id, reference_answer: homework.reference_answer,
                                     course_list_id: @course.course_list_id)
    if homework.homework_type == "group" && homework.homework_detail_group
      homework_bank.min_num = homework.homework_detail_group.min_num
      homework_bank.max_num = homework.homework_detail_group.max_num
      homework_bank.base_on_project = homework.homework_detail_group.base_on_project
    end
    homework.attachments.each do |attachment|
      att = attachment.copy
      att.author_id = homework_bank.user_id
      att.copy_from = attachment.id
      att.attachtype = attachment.attachtype || 1
      homework_bank.attachments << att
    end
    homework_bank
  end

  def publish_params
    params.permit(:unified_setting, :publish_time, :end_time, group_settings: [:publish_time, :end_time, group_id: []])
  end

end