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, :choose_category, :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]
  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]
  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 @homework_type == 4 && !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?
      case order
      when '1'
        sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_commons.end_time > '#{Time.now}')
      when '2'
        sql_str = %Q(allow_late = 1 and homework_commons.end_time < '#{Time.now}' and (late_time is null or late_time > '#{Time.now}'))
      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((homework_detail_manuals.comment_status = #{order} or (anonymous_comment = 0 and homework_commons.end_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
    @task_count = @homework_commons.size

    @homework_commons = @homework_commons.order("IF(ISNULL(homework_commons.publish_time),0,1), homework_commons.publish_time DESC,
                                                  homework_commons.created_at DESC").page(page).per(15)

    if @homework_type == 4
      @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :shixuns)
    elsif @homework_type == 3
        @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :homework_detail_group)
    else
      @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings)
    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"
          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("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 && @homework.work_public
        @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 延迟提交
        unless params[:work_status].blank?
          @student_works = @student_works.where(work_status: params[:work_status])
        end

        # 分班情况
        unless params[:course_group].blank?
          group_user_ids = @course.students.where(course_group_id: params[:course_group]).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("user_id = commit_user_id")
          elsif params[:member_work].to_i == 0
            @student_works = @student_works.where("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]}%", "%#{params[:search]}%")
        end

        @work_count = @student_works.size
        @work_excel = @student_works.where("work_status > 0")

        # 排序
        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

        # 分页参数
        page = params[:page] || 1
        limit = params[:limit] || 20
        @student_works = @student_works.page(page).per(limit)
        @students = @course.students.where(user_id: @student_works.pluck(:user_id)).preload(:course_group)
        if @homework.homework_type == "practice"
          @student_works = @student_works.includes(:student_works_scores, user: :user_extension, myshixun: :games)
        else
          @student_works = @student_works.includes(:student_works_scores, :project, user: :user_extension)
        end
      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
    begin
      @homework.update_homework_work_score
      normal_status("更新成功")
    rescue Exception => e
      uid_logger(e.message)
      tip_exception(e.message)
      raise ActiveRecord::Rollback
    end
  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
      begin
        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
      rescue Exception => e
        uid_logger(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      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
  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
      begin
        @homework = HomeworkCommon.new(homework_params)
        @homework.homework_type = @homework_type
        @homework.user_id = current_user.id
        @homework.course_id = @course.id

        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
      rescue Exception => e
        uid_logger(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  def edit

  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
      begin
        @homework.update_attributes(homework_params)

        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, "更新成功")
      rescue Exception => e
        uid_logger(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  def settings
    @user = current_user
    @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT
  end

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

        # 作业未发布时，unified_setting参数不能为空
        if @homework.publish_time.nil? || @homework.publish_time > Time.now
          tip_exception("缺少统一设置的参数") if params[:unified_setting].nil?
          if params[:unified_setting] || @course.course_groups_count == 0
            tip_exception("发布时间不能为空") if params[:publish_time].blank?
            tip_exception("截止时间不能为空") if params[:end_time].blank?
            tip_exception("发布时间不能早于当前时间") if params[:publish_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
            tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
            tip_exception("截止时间不能早于发布时间") if params[:publish_time] > params[:end_time]
            tip_exception("截止时间不能晚于课堂结束时间（#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}）") if
              @course.end_date.present? && params[:end_time] > @course.end_date.end_of_day

            @homework.unified_setting = 1
            @homework.homework_group_settings.destroy_all
            @homework.publish_time = params[:publish_time]
            # 截止时间为空时取发布时间后一个月
            @homework.end_time = params[:end_time]

          else
            tip_exception("分班发布设置不能为空") if params[:group_settings].blank?
            # 创建作业的分班设置
            create_homework_group_settings @homework

            setting_group_ids = []

            params[:group_settings].each do |setting|
              tip_exception("分班id不能为空") if setting[:group_id].length == 0
              tip_exception("发布时间不能为空") if setting[:publish_time].blank?
              tip_exception("截止时间不能为空") if setting[:end_time].blank?
              tip_exception("发布时间不能早于当前时间") if setting[:publish_time] <= strf_time(Time.now)
              tip_exception("截止时间不能早于当前时间") if setting[:end_time] <= strf_time(Time.now)
              tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time]
              tip_exception("截止时间不能晚于课堂结束时间（#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}）") if
                @course.end_date.present? && setting[:end_time] > @course.end_date.end_of_day


              publish_time = setting[:publish_time] == "" ? Time.now : setting[:publish_time]
              # 截止时间为空时取发布时间后一个月
              end_time = setting[:end_time] == "" ? Time.at(publish_time.to_time.to_i+30*24*3600) : setting[:end_time]
              HomeworkGroupSetting.where(homework_common_id: @homework.id, course_group_id: setting[:group_id]).
                  update_all(publish_time: publish_time, end_time: end_time)
              setting_group_ids << setting[:group_id]
            end

            # 未设置的分班：发布时间和截止时间都为nil
            HomeworkGroupSetting.where.not(course_group_id: setting_group_ids).where(homework_common_id: @homework.id).
                update_all(publish_time: nil, end_time: nil)

            # 记录已发布需要发消息的分班
            publish_group_ids = HomeworkGroupSetting.where(homework_common_id: @homework.id).group_published.pluck(:course_group_id)

            @homework.unified_setting = 0
            @homework.publish_time = @homework.min_group_publish_time
            @homework.end_time = @homework.max_group_end_time
          end

          # 如果作业立即发布则更新状态、发消息
          if @homework.publish_time <= Time.now and @homework_detail_manual.comment_status == 0
            @homework_detail_manual.comment_status = 1
            send_tiding = true
          end

          # 作业在"提交中"状态时
        else
          if @homework.end_time > Time.now && @homework.unified_setting
            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)

            @homework.end_time = params[:end_time]

          elsif !@homework.unified_setting
            create_homework_group_settings @homework
            tip_exception("分班发布设置不能为空") if params[:group_settings].blank?
            params[:group_settings].each do |setting|
              group_settings = HomeworkGroupSetting.where(homework_common_id: @homework.id, course_group_id: setting[:group_id])

              tip_exception("分班id不能为空") if setting[:group_id].length == 0
              tip_exception("发布时间不能为空") if setting[:publish_time].blank?
              tip_exception("截止时间不能为空") if setting[:end_time].blank?
              # 如果该发布规则 没有已发布的分班则需判断发布时间
              tip_exception("发布时间不能早于等于当前时间") if setting[:publish_time] <= strf_time(Time.now) && group_settings.group_published.count == 0

              tip_exception("截止时间不能早于等于当前时间") if setting[:end_time] <= strf_time(Time.now)
              tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time]
              tip_exception("截止时间不能晚于课堂结束时间（#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}）") if
                @course.end_date.present? && setting[:end_time] > strf_time(@course.end_date.end_of_day)

              group_settings.none_published.update_all(publish_time: setting[:publish_time])
              group_settings.none_end.update_all(end_time: setting[:end_time])
            end

            @homework.end_time = @homework.max_group_end_time
          end
        end

        # 补交设置
        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("缺少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[:eff_score] && params[:eff_score].to_i <= 0
          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

          current_eff_score = @homework.eff_score
          @homework.work_efficiency = params[:work_efficiency]
          @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_i : 0

          update_eff_score = current_eff_score != @homework.eff_score

          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.student_works.has_committed.each do |student_work|
          #     HomeworksService.new.set_shixun_final_score student_work
          #   end
          # end

          # 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止)
          if update_eff_score && @homework.end_or_late_none_group
            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

        HomeworkCommonPushNotifyJob.perform_later(@homework.id, publish_group_ids) if send_tiding
        normal_status(0, "更新成功")
      else
        tip_exception("课堂已结束不能再更新")
      end
    rescue Exception => e
      uid_logger(e.backtrace)
      tip_exception(e.message)
      raise ActiveRecord::Rollback
    end
  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?
      @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)

      # 新版用下面的代码
      # ## 我的实训
      # @shixuns =
      #     if params[:order_by] == 'mine'
      #       current_user.my_shixuns.unhidden
      #     else
      #       if current_user.admin?
      #         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
      #     end
      #
      # ## 方向
      # if params[:tag_level].present? && params[:tag_id].present?
      #   @shixuns = @shixuns.filter_tag(params[:tag_level].to_i, params[:tag_id].to_i)
      #   case params[:tag_level].to_i
      #   when 1 #大类
      #     @search_tags = Repertoire.find(params[:tag_id].to_i).name
      #   when 2 #子类
      #     @search_tags =  SubRepertoire.find(params[:tag_id].to_i).name
      #   when 3 #tag
      #     tag = TagRepertoire.find(params[:tag_id].to_i)
      #     @search_tags = "#{tag.sub_repertoire.name} / #{tag.name}"
      #   end
      # end
      #
      # ## 搜索关键字创建者、实训名称、院校名称
      # if params[:keyword].present?
      #   keyword = params[:keyword].strip
      #   @shixuns = @shixuns.joins(user: [user_extenison: :school]).
      #       where("schools.name like '%#{keyword}%'
      #               or concat(lastname, firstname) like '%#{keyword}%'
      #               or shixuns.name like '%#{keyword.split(" ").join("%")}%'").distinct
      # end
      #
      # ## 筛选 难度
      # if params[:diff].present? && params[:diff].to_i != 0
      #   @shixuns = @shixuns.where(trainee: params[:diff])
      # end
      #
      # ## 排序参数
      # bsort = params[:sort] || 'desc'
      # case params[:order_by] || 'hot'
      # when 'hot'
      #   @shixuns = @shixuns.order("myshixuns_count #{bsort}")
      # when 'mine'
      #   @shixuns = @shixuns.order("shixuns.created_at #{bsort}")
      # else
      #   @shixuns = @shixuns.order("myshixuns_count #{bsort}")
      # end
      #
      # @total_count = @shixuns.count
      #
      # ## 分页参数
      # page  = params[:page]  || 1
      # limit = params[:limit] || 15
      #
      # @shixuns = @shixuns.includes(:challenges, user: [user_extension: :school]).page(page).per(limit)
    #
  end

  def create_shixun_homework
    tip_exception("请至少选择一个实训") if params[:shixun_ids].blank?
    shixuns = Shixun.where(id: params[:shixun_ids]).reorder("id desc")
    @homework_ids = []
    unless params[:category_id].blank?
      @category = @course.course_second_categories.find_by(id: params[:category_id], category_type: "shixun_homework")
    end
    ActiveRecord::Base.transaction do
      begin
        shixuns.each do |shixun|
          homework = HomeworksService.new.create_homework shixun, @course, @category, current_user
          @homework_ids << homework.id
        end
      rescue Exception => e
        uid_logger(e.message)
        tip_exception("创建失败")
        raise ActiveRecord::Rollback
      end
    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")
    ActiveRecord::Base.transaction do
      begin
        subjects.each do |subject|

          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.where.not(shixuns: {id: none_shixun_ids}).unhidden.each do |shixun|
              homework = HomeworksService.new.create_homework shixun, @course, category, current_user
              @homework_ids << homework.id
            end
          end
        end
      rescue Exception => e
        uid_logger(e.message)
        tip_exception("创建失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  def publish_groups
    @current_user = current_user
    if @homework.publish_immediately @current_user
      # 可立即发布的分班：当前用户管理的分班去除已发布的分班
      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)
    else
      tip_exception("没有可发布的分班")
    end
  end

  def publish_homework
    tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0
    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)

    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 & params[:group_ids] if params[:group_ids]

    ActiveRecord::Base.transaction do
      begin
        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
                homework.homework_group_settings.destroy_all
                homework.unified_setting = true
                homework.end_time = params[:end_time]
              else
                homework.unified_setting = false
                # 创建作业分班设置：homework_group_setting
                create_homework_group_settings(homework)

                # 选中的分班设置的发布时间改为当前时间，截止时间改为传的截止时间参数
                homework.homework_group_settings.where(course_group_id: publish_groups).update_all(publish_time: Time.now,
                                                                                                   end_time: params[:end_time])
                # 发消息
                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[:end_time]
            elsif homework.max_group_end_time
              homework.end_time = homework.max_group_end_time
            end
            homework.homework_detail_manual.update_attribute('comment_status', 1)

            if homework.course_acts.size == 0
              homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id)
            end
            # 发消息
            HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids)
          else
            create_homework_group_settings(homework)

            none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published
            none_publish_settings.update_all(publish_time: Time.now, end_time: params[:end_time])
            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_attribute("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, "发布成功")
      rescue Exception => e
        uid_logger(e.message)
        tip_exception("发布失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  def end_groups
    @current_user = current_user
    if @homework.end_immediately @current_user
      # 可立即截止的分班：统一设置则是用户管理的所有分班，否则是当前用户管理的分班中已发布且未截止的
      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).none_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.strftime("%Y-%m-%d %H:%M:%S")

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

    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)
    end_groups = charge_group_ids & params[:group_ids] if params[:group_ids]

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

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

            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_attribute("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_attribute("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

=begin
              student_works.where("work_status != 0").includes(:myshixun).each do |student_work|
                unless student_work.myshixun.is_complete?
                  student_work.update_attributes(work_status: 2, late_penalty: homework.late_penalty)
                  student_work.late_penalty = homework.late_penalty
                end
                HomeworksService.new.set_shixun_final_score student_work, student_work.myshixun, homework_detail_manual.answer_open_evaluation,
                                  homework_challenge_settings
              end

              student_works.where("work_status = 0").each do |student_work|
                myshixun = Myshixun.where(shixun_id: shixun.id, user_id: student_work.user_id).first
                if myshixun.present?
                  student_work.update_attributes(work_status: (myshixun.is_complete? ? 1 : 2),
                                                 late_penalty: myshixun.is_complete? ? 0 : homework.late_penalty,
                                                 commit_time: myshixun.created_at, myshixun_id: myshixun.id)
                  student_work.late_penalty = myshixun.is_complete? ? 0 : homework.late_penalty
                  HomeworksService.new.set_shixun_final_score student_work, myshixun, homework_detail_manual.answer_open_evaluation,
                                  homework_challenge_settings
                end
              end
=end

              # 更新所有学生的效率分(重新取homework确保是更新后的)
              HomeworkEndUpdateScoreJob.perform_later(homework.id) if !homework.allow_late && homework.end_time <= time
            end
          end
          homework.save!
        end
        normal_status(0, "更新成功")
      rescue Exception => e
        uid_logger(e.message)
        tip_exception("操作失败")
        raise ActiveRecord::Rollback
      end
    end
  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
  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
      begin
        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, "删除成功")

      rescue Exception => e
        uid_logger(e.message)
        tip_exception("删除失败")
        raise ActiveRecord::Rollback
      end
    end
  end

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

    homeworks.each do |homework|
      ActiveRecord::Base.transaction do
        begin
          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!
          end

        rescue Exception => e
          uid_logger(e.message)
          tip_exception("删除失败")
          raise ActiveRecord::Rollback
        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)

  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.course_members.where(user_id: params[:user_id]).pluck(:course_group_id).first
    query_id = @homework.homework_group_reviews.where(:course_group_id => group_id).last.try(:query_id)
    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
            # 抄袭用户
            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

  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("name参数不能为空") if params[:name].blank?
    tip_exception("description参数不能为空") 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
  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 create_homework_group_settings homework
    if homework.homework_group_settings.size != @course.course_groups.size
      @course.course_groups.where.not(id: homework.homework_group_settings.pluck(:course_group_id)).each do |group|
        homework.homework_group_settings << HomeworkGroupSetting.new(course_group_id: group.id, course_id: @course.id,
                                                                     publish_time: homework.publish_time, end_time: homework.end_time)
      end
    end
  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

end
