class CoursesController < ApplicationController
  include MessagesHelper
  include ExportHelper

  # model validation error
  rescue_from ActiveRecord::RecordInvalid do |ex|
    render_error(ex.record.errors.full_messages.join(','))
  end
  # form validation error
  rescue_from ActiveModel::ValidationError do |ex|
    render_error(ex.model.errors.full_messages.join(','))
  end

  before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
                                                      :left_banner, :top_banner, :informs, :online_learning]
  before_action :check_account, only: [:new, :create, :apply_to_join_course, :join_excellent_course]
  before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
                                                      :left_banner, :top_banner, :apply_to_join_course, :exit_course]
  before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt,
                                    :set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers,
                                     :top_banner, :left_banner, :add_teacher_popup, :add_teacher,
                                     :graduation_group_list, :create_graduation_group, :join_graduation_group,
                                     :course_group_list, :set_course_group, :change_course_admin, :change_course_teacher,
                                     :delete_course_teacher, :teacher_application_review, :students, :all_course_groups,
                                     :transfer_to_course_group, :delete_from_course, :search_users, :add_students_by_search,
                                     :base_info, :get_historical_courses, :create_group_by_importing_file,
                                     :attahcment_category_list,:export_member_scores_excel, :duplicate_course,
                                     :switch_to_teacher, :switch_to_assistant, :switch_to_student, :exit_course,
                                     :informs, :update_informs, :online_learning, :update_task_position, :tasks_list,
                                    :join_excellent_course, :export_couser_info, :export_member_act_score]
  before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course,
                                                :search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list]
  before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate,
                                         :transfer_to_course_group, :delete_from_course, :export_member_scores_excel,
                                         :search_users, :add_students_by_search, :get_historical_courses, :add_teacher_popup,
                                         :add_teacher, :export_couser_info, :export_member_act_score]
  before_action :admin_allowed, only: [:set_invite_code_halt, :set_public_or_private, :change_course_admin,
                                       :set_course_group, :create_group_by_importing_file, :update_informs, :new_informs,
                                       :update_task_position, :tasks_list]
  before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group,
                                                  :change_course_teacher, :course_group_list,
                                                  :teacher_application_review, :apply_teachers, :delete_course_teacher]
  before_action :validate_course_name, only: [:create, :update]
  before_action :find_board, only: :board_list
  before_action :validate_page_size, only: :mine
  before_action :course_tasks, only: [:tasks_list, :update_task_position]
  before_action :validate_inform_params, only: [:update_informs, :new_informs]

  if RUBY_PLATFORM =~ /linux/
    require 'simple_xlsx_reader'
    require 'roo-xls'
  end

  # GET /courses
  # GET /courses.json
  def index
    @user = current_user
    # 根据分类查询课堂(全部，我的，最新，最热)
    @order = params[:order].present? ? params[:order] : "all"
    if @order == "visits"
      order_str = "courses.id = 1309 DESC, courses.visits DESC"
      @courses = Course.where(is_delete: 0, is_hidden: 0)
    else
      order_str = "courses.id = 1309 DESC, courses.homepage_show DESC, courses.created_at desc"
      @courses = Course.where(is_delete: 0, is_hidden: 0, is_end: 0)
    end

    # 金课未开课的不显示在首页
    @courses = @courses.where("start_date is null or start_date <= '#{Date.today}'")

    # 根据搜索关键字进一步筛选
    if params[:search].present?
      # REDO:Extension
      #user_ids = User.includes(user_extension: :school).where("schools.name like ?", "%#{params[:search]}%").pluck(:id)
      #course_ids = CourseMember.includes(:user, :course).where("course_members.course_id in (?) and course_members.role in (1,2,3)
      #                                    and CONCAT(users.lastname, users.firstname) like ?", @courses.map(&:id), "%#{params[:search]}%")
      #                                            .pluck(:course_id)
      #@courses = @courses.where("name like ?", "%#{params[:search]}%").or(@courses.where(tea_id: user_ids)).or(@courses.where(id: course_ids))
      # 6:21 daiao
      sql = %Q{
        (course_members.role in(1,2,3) and CONCAT(users.lastname, users.firstname) like :keyword) or courses.name like :keyword
        or schools.name like :keyword
      }
      @courses = @courses.joins(:school, course_members: :user)
                     .where("#{sql}", keyword: "%#{params[:search]}%").distinct
    end
    @courses_count = @courses.count("courses.id")
    @courses = @courses.order(order_str)

    # 分页
    page  = params[:page]  || 1
    limit = params[:limit] || 16

    @courses = @courses.page(page).per(limit)
    @courses = @courses.preload(:school, :none_hidden_course_modules, teacher: :user_extension)
  end

  def visits_plus_one
    new_visits = @course.visits + 1
    @course.update_visits(new_visits)
    normal_status("成功")
  end

  # GET /courses/1
  # GET /courses/1.json
  def show
    # render :json => {first_category_url: module_url(course.course_modules.where.not(module_type: "activity").where(hidden: 0).first, course)}
  end

  # GET /courses/new
  def new
    @course = Course.new
    unless params[:subject_id].blank?
      subject = Subject.find_by(id: params[:subject_id], excellent: 1)
      render :json => {status: 0, course_name: "#{subject&.name}第#{subject&.courses&.count.to_i + 1}期"}
    else
      normal_status("成功")
    end
  end

  # Get /courses/:id/settings
  # Edit Page
  def settings
    @course_modules = @course.course_modules.where.not(module_type: 'activity')
  end

  # POST /courses
  # POST /courses.json
  def create
    ActiveRecord::Base.transaction do
      begin
        @course = Course.new(name: params[:name], class_period: params[:class_period], credit: params[:credit],
                             end_date: params[:end_date], is_public: params[:is_public], school_id: @school.id,
                             authentication: params[:authentication], professional_certification: params[:professional_certification])
        @course.tea_id = current_user.id

        if params[:subject_id].blank?
          @course_list_name = params[:course_list_name].strip
          @course_list = CourseList.find_by(name: @course_list_name)
          if @course_list
            @course.course_list_id = @course_list.id
          else
            new_course_list = CourseList.create!(name: @course_list_name, user_id: current_user.id, is_admin: 0)
            @course.course_list_id = new_course_list.id
          end
        else
          @course.start_date = params[:start_date]
          @course.subject_id = params[:subject_id]
          @course.excellent = true
        end

        @course.is_end = @course.end_date.present? && @course.end_date < Date.today

        if @course.save!
          @course.generate_invite_code
          CourseInfo.create!(user_id: current_user.id, course_id: @course.id)
          CourseMember.create!(course_id: @course.id, user_id: current_user.id, role: 1)

          # 将实践课程的教学团队成员以教师身份加入课堂
          if @course.subject
            @course.subject.subject_members.where.not(user_id: current_user.id).each do |s_member|
              CourseMember.create!(course_id: @course.id, user_id: s_member.user_id, role: 2)
            end

            Inform.create(container: @course, description: @subject.learning_notes, name: "学习须知")
          end

          course_module_types = params[:course_module_types]
          @course.create_course_modules(course_module_types)
        end
      rescue => e
        uid_logger_error(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  # PATCH/PUT /courses/1
  # PATCH/PUT /courses/1.json
  def update
    ActiveRecord::Base.transaction do
      begin
        extra_params = Hash.new
        extra_params[:school_id] = @school.id

        if @course.is_end && (course_params[:end_date].blank? || course_params[:end_date].to_date >= Date.today)
          extra_params[:is_end] = 0
        elsif !@course.is_end && !course_params[:end_date].blank? && course_params[:end_date].to_date < Date.today
          extra_params[:is_end] = 1
        end

        extra_params[:authentication] = params[:authentication]
        extra_params[:professional_certification] = params[:professional_certification]

        if @course.subject
          @course.start_date = params[:start_date]
        else
          extra_params[:is_public] = params[:is_public].present? ? params[:is_public] : 0
          @course_list_name = params[:course_list_name].strip
          @course_list = CourseList.find_by(name: @course_list_name)
          if @course_list
            extra_params[:course_list_id] = @course_list.id
          else
            new_course_list = CourseList.create(name: @course_list_name, user_id: current_user.id, is_admin: 0)
            extra_params[:course_list_id] = new_course_list.id
          end
        end

        @course.update_attributes!(course_params.merge(extra_params))
        @course.update_course_modules(params[:course_module_types])

        normal_status(0, "成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception("课堂更新失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  def join_excellent_course
    tip_exception("您已是课堂成员") if current_user.member_of_course?(@course)
    tip_exception("请通过邀请码加入课堂") unless @course.excellent
    tip_exception("该课堂已结束") if @course.is_end
    begin
      new_student = CourseMember.new(user_id: current_user.id, course_id: @course.id, role: 4)
      new_student.save!

      CourseAddStudentCreateWorksJob.perform_later(@course.id, [current_user.id])
      StudentJoinCourseNotifyJob.perform_later(current_user.id, @course.id)
      normal_status(0, "加入成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception(e.message)
    end
  end

  def informs
    @informs = @course.informs
  end

  def new_informs
    inform = Inform.new(container: @course)
    inform.name = params[:name]
    inform.description = params[:description]
    inform.save!
    normal_status("创建成功")
  end

  def update_informs
    inform = @course.informs.find_by(id: params[:inform_id])
    inform.update_attributes!(name: params[:name], description: params[:description])
    normal_status("更新成功")
  end

  def online_learning
    @subject = @course.subject
    @stages = @subject&.stages
    @user = current_user
    @start_learning = @user_course_identity == Course::STUDENT && @subject&.learning?(current_user.id)
  end

  def search_course_list
    search = params[:search] ? "%#{params[:search].strip}%" : "%%"
    @course_lists = CourseList.where("name like ?", "#{search}")
    @search_count = @course_lists.size
  end

  # 邀请码停用/启用
  def set_invite_code_halt
    begin
      @course.update_attribute('invite_code_halt', @course.invite_code_halt == 0 ? 1 : 0)
      normal_status(0, "成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception("停用/启用课堂失败")
    end
  end

  # 设置课堂私有/公有
  def set_public_or_private
    begin
      @course.update_attribute('is_public', @course.is_public == 1 ? 0 : 1)
      normal_status(0, "成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception("设置课堂公有/私有失败")
    end
  end

  # DELETE /courses/1
  # DELETE /courses/1.json
  def destroy
    if @course.is_delete == 0
      @course.delete!
      Tiding.create!(user_id: @course.tea_id, trigger_user_id: 1, container_id: @course.id,
                     container_type: 'Course', tiding_type: 'Delete', extra: @course.name)
      normal_status(0, "成功")
    else
      normal_status(-1, "课堂已删除，无需重复操作")
    end
  end

  # 课堂的基本信息
  def base_info

  end

  # --- 教师列表相关API --- START

  # 教师列表以及教师搜索
  def teachers
    @search_str = params[:search].present? ? params[:search].strip : ""

    if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582
      @teacher_list = @course.course_members.joins(:user).where("course_members.role in (1, 2, 3)
                                                     and LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{@search_str}%")
    else
      @teacher_list = @course.course_members.joins(:user).where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id}
                                          and course_members.role = 2)) and LOWER(concat(users.lastname, users.firstname))
                                          LIKE ?", "%#{@search_str}%")
    end

    @teacher_list_size = @teacher_list.size

    @has_graduation_design = @course.course_modules.graduation_module_not_hidden.any?

    sort = params[:sort] || "desc"
    @order = params[:order].to_i
    if @order.present?
      case @order
      when 1
        @teacher_list = @teacher_list.order("role #{sort}")
      when 2
        @teacher_list = @teacher_list.includes(:user).order("CONVERT(CONCAT(users.lastname, users.firstname) USING gbk) COLLATE gbk_chinese_ci #{sort}")
      when 3
        @teacher_list = @teacher_list.includes(:course, :graduation_group).order("graduation_groups.name #{sort}")
      else
        @teacher_list = @teacher_list.order("role #{sort}")
      end
    else
      @teacher_list = @teacher_list.order("role #{sort}")
    end

    @is_admin = @user_course_identity < Course::PROFESSOR

    @applications_size = CourseMessage.unhandled_join_course_requests_by_course(@course).size

    page = params[:page] || 1
    limit = params[:limit] || 20
    @teacher_list = @teacher_list.page(page).per(limit)
    @teacher_list = @teacher_list.preload(:graduation_group, :user, :teacher_course_groups)
  end

  def apply_teachers
    search_str = params[:search].present? ? params[:search].strip : ""
    @applications = CourseMessage.unhandled_join_course_requests_by_course(@course).
        joins("join users on course_messages.course_message_id=users.id").
        where("LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{search_str}%")
    if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582
      teacher_list = @course.course_members.where("course_members.role in (1, 2, 3)")
    else
      teacher_list = @course.course_members.where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id}
                                          and course_members.role = 2))")
    end
    @teacher_list_size = teacher_list.size
    @applications_size = CourseMessage.unhandled_join_course_requests_by_course(@course).size
    @is_admin = @user_course_identity < Course::PROFESSOR
  end

  # 打开添加教师或助教弹窗时访问的接口(需要返回该课堂所有答辩组和所有)
  def add_teacher_popup
    @graduation_groups = @course.graduation_groups
    @course_groups = @course.course_groups
    @school_name = School.find(current_user.school_id).try(:name)
  end

  # 添加教师或助教弹窗中的搜索接口
  def search_teacher_candidate
    name = params[:name]
    school_name = params[:school_name]

    # user_ids_of_course_members = @course.course_members.where(role: [1,2,3]).pluck(:user_id)
    # @users = User.where.not(id: user_ids_of_course_members)

    @users = User.where(status: User::STATUS_ACTIVE)
    @users = @users.where("concat(users.lastname, users.firstname) like '%#{name}%'") if name.present?
    # REDO:Extension
    @users = @users.joins(user_extension: :school).where("schools.name like '%#{school_name}%'") if school_name.present?

    @users_size = @users.size

    page = params[:page] || 1
    limit = params[:limit] || 10
    @users = @users.page(page).per(limit)
  end

  # 添加教师或者助教
  def add_teacher
    ActiveRecord::Base.transaction do
      begin
        @user_list = params[:user_list].present? ? params[:user_list] : []
        return tip_exception("请先选择成员") if @user_list.blank?

        @graduation_group_id = params[:graduation_group_id].present? ? GraduationGroup.find(params[:graduation_group_id]).id : 0

        @course_group_id = params[:course_group_id].present? ? CourseGroup.find(params[:course_group_id]).id : 0

        role = params[:role].to_i

        teacher_ids = []
        @user_list.each do |user|
          active_student_exist = CourseMember.where(user_id: user[:user_id], role: 4, course_id: @course.id, is_active: 1).any?
          is_active = active_student_exist ? 0 : 1
          user_id = User.find(user[:user_id]).id
          existing_teacher = CourseMember.find_by(course_id: @course.id, user_id: user_id, role: role)
          if existing_teacher.blank?
            teacher_ids << user_id
            member = CourseMember.create(course_id: @course.id, graduation_group_id: @graduation_group_id, user_id: user_id, role: role, is_active: is_active)

            member.teacher_course_groups << TeacherCourseGroup.new(course_group_id: @course_group_id, user_id: user_id, course_id: @course.id) if @course_group_id != 0
          end
        end
        TeacherInviteJoinCourseNotifyJob.perform_later(current_user.id, @course.id, role, teacher_ids) if teacher_ids.present?
        normal_status(0, "添加成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception(-1, "添加失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 获取当前课堂的所有答辩组
  def graduation_group_list
    @graduation_group_list = @course.graduation_groups
  end

  # 给当前课堂增加答辩组
  def create_graduation_group
    begin
      if params[:name].present?
        identical_exist = GraduationGroup.where(course_id: @course.id, name: params[:name]).any?
        if identical_exist
          normal_status(-1, "已存在同名答辩组")
        else
          GraduationGroup.create(course_id: @course.id, user_id: current_user.id, name: params[:name])
          normal_status(0, "成功")
        end
      else
        tip_exception(-1, "答辩组名称不能为空")
      end
    rescue => e
      uid_logger_error(e.message)
      tip_exception(-1, "添加失败")
      raise ActiveRecord::Rollback
    end
  end

  # 将教师加入答辩组
  def join_graduation_group
    ActiveRecord::Base.transaction do
      begin
        @course_member_list = params[:course_member_list].present? ? params[:course_member_list] : []

        graduation_group_id = GraduationGroup.find(params[:graduation_group_id].to_i).id
        @course_member_list.each do |course_member|
          course_member = CourseMember.find(course_member[:course_member_id].to_i)
          course_member.update_attributes(graduation_group_id: graduation_group_id)
        end
        normal_status(0, "成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception(-1, "加入失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 获取当前课堂的所有分班, 以及当前教师是否对分班具有管理权限的状态
  def course_group_list
    course_member_id = params[:course_member_id]
    user_id = params[:user_id]

    @existed_course_group_ids = TeacherCourseGroup.where(course_id: @course.id, course_member_id: course_member_id, user_id: user_id)
                                                  .pluck(:course_group_id)
    @all_course_groups = CourseGroup.where(course_id: @course.id)
  end

  # 设置教师的管理权限(即设置该教师所能管理的分班)
  def set_course_group
    ActiveRecord::Base.transaction do
      begin
        course_group_ids = params[:course_group_ids]
        user_id = User.find(params[:user_id].to_i).id
        course_member_id = CourseMember.find(params[:course_member_id]).id

        teacher_course_groups = TeacherCourseGroup.where(course_id: @course.id, user_id: user_id, course_member_id: course_member_id)
        teacher_course_groups.destroy_all

        course_group_ids.each do |course_group_id|
          course_group_id = CourseGroup.where(id: course_group_id.to_i, course_id: @course.id).first.id
          TeacherCourseGroup.create(course_id: @course.id, user_id: user_id, course_member_id: course_member_id, course_group_id: course_group_id)
        end
        normal_status(0, "成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception( "分配管理权限失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 变更管理员
  def change_course_admin
    ActiveRecord::Base.transaction do
      begin
        new_admin_user = User.find(params[:user_id].to_i)
        new_admin = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id, user_id: new_admin_user.id)
        current_admin = CourseMember.find_by!(course_id: @course.id, role: 1)

        new_admin.CREATOR!
        current_admin.PROFESSOR!

        @course.update_attributes!(tea_id: new_admin_user.id)
        normal_status(0, "变更管理员成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception( "变更管理员失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 教师和助教角色转换的接口
  def change_course_teacher
    begin
      course_member = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id)
      if course_member.PROFESSOR?
        course_member.ASSISTANT_PROFESSOR!
      elsif course_member.ASSISTANT_PROFESSOR?
        course_member.PROFESSOR!
      else
        tip_exception( "变更教师/助教失败")
      end
      course_member.save!
      normal_status(0, "变更教师/助教成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception( "变更教师/助教失败")
    end
  end

  # 删除教师或助教
  def delete_course_teacher
    begin
      course_member = CourseMember.find_by!(id: params[:course_member_id].to_i, course_id: @course.id)
      tip_exception("删除失败") if course_member.CREATOR? or course_member.STUDENT?

      course_student = CourseMember.find_by(user_id: course_member.user_id, course_id: @course.id, role: %i[STUDENT])
      course_member.destroy!
      course_student.update_attributes(is_active: 1) if course_student.present? && !course_student.is_active
      normal_status(0, "删除成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception("删除失败")
    end
  end

  # 切换为教师
  def switch_to_teacher
    begin
      course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1)
      tip_exception("切换失败") unless course_member.STUDENT?

      course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[CREATOR PROFESSOR], course_id: @course.id)
      course_member.update_attributes(is_active: 0)
      course_teacher.update_attributes(is_active: 1)
      normal_status(0, "切换成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception("切换失败")
    end
  end

  # 切换为助教
  def switch_to_assistant
    begin
      course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1)
      tip_exception("切换失败") unless course_member.STUDENT?

      course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[ASSISTANT_PROFESSOR], course_id: @course.id)
      course_member.update_attributes(is_active: 0)
      course_teacher.update_attributes(is_active: 1)
      normal_status(0, "切换成功")
    rescue => e
      uid_logger_error(e.message)
      tip_exception("切换失败")
    end
  end

  # 切换为学生
  def switch_to_student
    ActiveRecord::Base.transaction do
      begin
        course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1)
        tip_exception("切换失败") if course_member.STUDENT?

        course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id)
        course_member.update_attributes(is_active: 0)
        course_student.update_attributes(is_active: 1)
        normal_status(0, "切换成功")
      rescue => e
        uid_logger_error("switch_to_student error: #{e.message}")
        tip_exception("切换失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  def exit_course
    course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id)
    tip_exception("非课堂学生无法退出课堂") unless course_student.STUDENT?
    # 课堂如果还有其他身份的用户则更新is_active
    course_teacher = CourseMember.find_by(user_id: current_user.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR], course_id: @course.id)
    course_student.destroy!
    course_teacher.update_attributes(is_active: 1) if course_teacher.present? && !course_teacher.is_active
    CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [current_user.id])
    normal_status(0, "退出成功")
  end

  # 教师申请加入课堂的审批
  def teacher_application_review
    ActiveRecord::Base.transaction do
      begin
        course_message = CourseMessage.find_by!(id: params[:application_id].to_i, course_id: @course.id)
        course_message.apply_user_id = current_user.id
        applier_user = User.find_by!(id: params[:user_id].to_i)

        approval = params[:approval].to_i
        if approval == 1
          course_message.pass!

          new_teacher = CourseMember.new(course_id: @course.id, user_id: applier_user.id)
          content = course_message.content.to_i
          if content == 3 || content == 7
            tip_exception("已存在教师/助教身份") if CourseMember.where(course_id: @course.id, user_id: applier_user.id, role: 3).any?
            new_teacher.ASSISTANT_PROFESSOR!
          elsif content == 2 || content == 9
            tip_exception("已存在教师/助教身份") if CourseMember.where(course_id: @course.id, user_id: applier_user.id, role: 2).any?
            new_teacher.PROFESSOR!
          else
            tip_exception("申请角色错误")
          end

          new_teacher.save!

          # 课堂管理员才有分配权限，且课堂分班数大于0
          if @user_course_identity < Course::PROFESSOR && @course.course_groups_count > 0 && params[:group_id] && params[:group_id].size > 0
            # 分班全选则是不限，不需要做处理
            unless @course.course_groups.where(id: params[:group_id]).size == @course.course_groups_count
              @course.course_groups.where(id: params[:group_id]).each do |group|
                unless TeacherCourseGroup.where(course_id: @course.id, user_id: applier_user.id, course_group_id: group.id, course_member_id: new_teacher.id).exists?
                  TeacherCourseGroup.create(course_id: @course.id, user_id: applier_user.id, course_member_id: new_teacher.id, course_group_id: group.id)
                end
              end
            end
          end
        elsif approval == 2
          course_message.reject!
        else
          tip_exception("参数错误")
        end
        course_message.save!
        normal_status(0, "操作成功")
      rescue => e
        uid_logger_error(e.message)
        tip_exception("操作失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 已通过职业认证的教师复制课堂
  def duplicate_course
    return tip_exception("没有复制权限") unless current_user.admin? || current_user.is_teacher? || current_user.teacher_of_course?(@course)
    return tip_exception("教师职业认证未通过") unless current_user.pro_certification?

    new_course = @course.self_duplicate
    render json: {new_course_id: new_course.id}
  end
  # --- 教师列表相关API --- END

  # --- 学生列表相关API --- START

  # 学生列表(包括各个子分班的学生列表)及搜索
  def students
    search = params[:search].present? ? params[:search].strip : nil
    order = params[:order].present? ? params[:order].to_i : 0
    course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil

    @students = CourseMember.students(@course)
    if search.present?
      # REDO:Extension
      @students = @students.joins(user: :user_extension).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? or
                                                        user_extensions.student_id like ?", "%#{search}%", "%#{search}%")
    end

    if order == 1
      # REDO:Extension
      @students = @students.includes(user: :user_extension).order("user_extensions.student_id, users.login")
    elsif order == 2
      @students = @students.includes(:course_group).order("course_groups.position, users.login")
    else
      # REDO:Extension
      @students = @students.includes(user: :user_extension).order("user_extensions.student_id, users.login")
    end

    if course_group_id.present?
      @students = @students.where(course_group_id: course_group_id)
      @course_group = CourseGroup.find(course_group_id) if course_group_id != 0
    end

    @students_count = @students.size

    page = params[:page] || 1
    limit = params[:limit] || 20
    @students= @students.page(page).per(limit)
    @students = @students.includes(:course_group, user: :user_extension)
  end

  # 获取当前课程所有分班
  def all_course_groups
    if params[:all]  # 返回所有分班
      @course_groups_array = @course.course_groups.to_a
    else  # 返回权限下的分班
      charge_group_ids = @course.charge_group_ids(current_user)
      @course_groups_array = @course.course_groups.where(id: charge_group_ids).to_a
    end

    current_course_group_id = params[:course_group_id]

    if current_course_group_id.present?
      current_course_group = CourseGroup.find(current_course_group_id)
      @course_groups_array.delete(current_course_group)
    end
  end

  # 将学生批量移动到某个分班
  def transfer_to_course_group
    ActiveRecord::Base.transaction do
      begin
        course_group_id = params[:course_group_id].to_i

        # course_group_id为0意味着移动学生到未分班
        if course_group_id != 0
          course_group = CourseGroup.find_by!(id: course_group_id, course_id: @course.id)
          course_group_id = course_group.id
        end

        @course.students.where(id: params[:students].pluck(:course_member_id)).each do |student|
          student.update_attributes!(course_group_id: course_group_id)
        end
        normal_status(0, "操作成功")
      rescue => e
        uid_logger(e.message)
        tip_exception("操作失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 从当前课堂删除学生
  def delete_from_course
    ActiveRecord::Base.transaction do
      begin
        students = params[:students]
        student_ids = []

        students.each do |student|
          course_member = CourseMember.find_by(id: student[:course_member_id].to_i, course_id: @course.id)
          if course_member.present?
            member_teacher = CourseMember.find_by(user_id: course_member.user_id, course_id: @course.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR])
            student_ids << course_member.user_id
            course_member.destroy!
            member_teacher.update_attributes(is_active: 1) if member_teacher.present?
          end
        end
        CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, student_ids) if student_ids.present?
        normal_status(0, "操作成功")
      rescue => e
        uid_logger(e.message)
        tip_exception("操作失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 搜索添加学生
  def add_students_by_search
    ActiveRecord::Base.transaction do
      begin
        user_ids = params[:user_ids]
        course_group_id = params[:course_group_id].to_i
        if course_group_id != 0
          course_group = CourseGroup.find(course_group_id)
          course_group_id = course_group.id
        end

        student_ids = []
        user_ids.each do |user_id|
          existing_course_member = @course.course_members.find_by(user_id: user_id.to_i)
          new_student = CourseMember.new(user_id: user_id.to_i, course_id: @course.id, course_group_id: course_group_id, role: 4)

          if existing_course_member.present?
            if existing_course_member.STUDENT?
              existing_course_member.update_attributes(course_group_id: course_group_id)
            else
              new_student.is_active = 0 if existing_course_member.is_active
              new_student.save!
              student_ids << user_id
            end
          else
            new_student.save!
            student_ids << user_id
          end
        end

        CourseAddStudentCreateWorksJob.perform_later(@course.id, student_ids) if student_ids.present?
        TeacherInviteJoinCourseNotifyJob.perform_later(current_user.id, @course.id, 10, student_ids) if student_ids.present?
        normal_status(0, "添加成功")
      rescue => e
        uid_logger(e.message)
        tip_exception("添加失败")
        raise ActiveRecord::Rollback
      end
    end
  end

  # 获取历史课堂，即用户管理的所有课堂以及课堂下的分班(去除当前课堂)
  def get_historical_courses
    @courses = Course.where.not(id: @course.id).joins(:course_members).
        where(is_delete: 0, course_members: {user_id: current_user.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]}).includes(:course_groups)
    # @courses = Course.includes(:course_groups).where(id: current_user.course_members, is_delete: 0)
  end

  # 根据历史课堂的课堂id和分班id获取所有学生
  def get_historical_course_students
    course_id = params[:course_id]
    course_group_id = params[:course_group_id]

    @students = CourseMember.where(course_id: course_id, role: %i[STUDENT])
    if course_group_id.present?
      @students = @students.where(course_group_id: course_group_id)
    end

    @students = @students.includes(user: [user_extension: :school])
    @students_count = @students.size
  end

  # 导入创建分班
  def create_group_by_importing_file
    attachment_ids = []

    params[:attachment_ids].each do |id|
      attachment = Attachment.find(id.to_i)
      attachment_ids << attachment.id
    end
    associate_result = Attachment.associate_container(attachment_ids, @course.id, @course.class)
    return normal_status("参数错误") unless associate_result

    attachment_ids.each do |attachment_id|
      attachment = Attachment.find attachment_id

      path = attachment.disk_directory
      name = attachment.disk_filename
      if name.split(".").last == "xls"
        begin
          attachment_folder = edu_setting('attachment_folder')
          full_path = "#{attachment_folder}/#{path}/#{name}"
          xls = Roo::Spreadsheet.open(full_path, extension: :xls)
          worksheet = xls.sheet(0)
          rows = worksheet.last_row.to_i   #最后一行数
          if rows < 2
            return normal_status(-1, "请按照模板格式导入")
          else
            group_count = 0
            (2..rows).each do |row|
              name = worksheet.cell(row, 1).to_s

              if @course.course_groups.where(:name => name).blank?
                @course.course_groups << CourseGroup.new(:name => name)
                group_count += 1
              end
            end
            return normal_status("已导入#{group_count}个分班")
          end
        rescue => e
          uid_logger_error(e.message)
          normal_status(-1, "无法完成导入，原因：文件内容无法读取")
        end
      else
        normal_status(-1, "只支持xls文件的导入")
      end
    end
  end

  # --- 学生列表相关API --- END

  # 根据姓名和单位搜索用户
  def search_users
    name = params[:name]
    school_name = params[:school_name]

    # REDO:Extension
    @users = User.joins(user_extension: :school)
                 .where("CONCAT(users.lastname, users.firstname) like ? and schools.name like ?", "%#{name}%", "%#{school_name}%")

    @users_count = @users.size

    limit = params[:limit] || 20
    page = params[:page] || 1
    @users = @users.page(page).per(limit)
  end

  # 申请加入课堂
  def apply_to_join_course
    ActiveRecord::Base.transaction do
      begin

        # 邀请码验证
        return normal_status(-1, "邀请码不能为空") if params[:invite_code].blank?
        invite_code = params[:invite_code]
        course = Course.find_by(invite_code: invite_code, is_delete: 0, invite_code_halt: 0)
        course_group = CourseGroup.find_by(invite_code: invite_code)
        if course.blank?
          return normal_status(-1, "邀请码无效") if course_group.blank?

          course = Course.find_by(id: course_group.course_id, is_delete: 0, invite_code_halt: 0)
          return normal_status(-1, "邀请码无效") if course.blank?
        end

        return normal_status(-1, "课堂已结束，无法加入") if course.is_end

        # 实名认证和职业认证的身份判断
        return normal_status(-2, "该课堂要求成员完成实名和职业认证") if course.authentication &&
            course.professional_certification && (!current_user.authentication && !current_user.professional_certification)
        return normal_status(-2, "该课堂要求成员完成实名认证") if course.authentication && !current_user.authentication
        return normal_status(-2, "该课堂要求成员完成职业认证") if course.professional_certification && !current_user.professional_certification

        # 身份验证
        if params[:professor].blank? && params[:assistant_professor].blank? && params[:student].blank?
          return normal_status(-1, "请先选择身份")
        end
        if params[:professor].present? && params[:assistant_professor].present?
          return normal_status(-1, "同一课堂不允许申请多个教师身份")
        end

        # 验证是否存在同学号的学生
        # u_extension = current_user.user_extension
        # if params[:student].present? && u_extension.student?
        #   same_student_id_users = UserExtension.where.not(user_id: current_user.id).where(student_id: u_extension.student_id, identity: %i[student], school_id: u_extension.school_id).pluck(:user_id)
        #   tip_exception("该课堂已存在同学号的学生，暂时无法加入，请联系老师") if course.students.exists?(user_id: same_student_id_users)
        # end

        # 创建学生身份
        if params[:student].present? && params[:student].to_i == 1
          existing_student = CourseMember.find_by(course_id: course.id, role: %i[STUDENT], user_id: current_user.id)
          if existing_student.present?
            # 如果在该课堂已经存在学生身份，且邀请码为分班邀请码，则将其直接加入分班
            existing_student.update_attributes(course_group_id: course_group.id) if course_group.present?
          else
            correspond_teacher_exist = current_user.teacher_of_course? course
            new_student = CourseMember.new(user_id: current_user.id, course_id: course.id, role: 4)
            new_student.is_active = 0 if correspond_teacher_exist

            new_student.course_group_id = course_group.id if course_group.present?
            new_student.save!

            CourseAddStudentCreateWorksJob.perform_later(course.id, [current_user.id])
            StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id)
          end
          student_role = 1
        end

        # 创建教师身份
        if (params[:professor].present? && params[:professor].to_i == 1) || (params[:assistant_professor].present? && params[:assistant_professor].to_i == 1)
          teacher_already_exist = current_user.teacher_of_course_non_active? course
          unless teacher_already_exist
            existing_course_message = CourseMessage.find_by(course_id: course.id, course_message_id: current_user.id,
                                                            course_message_type: "JoinCourseRequest", status: 0)
            if existing_course_message.blank?
              course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0,
                                                 course_message_id: current_user.id, course_message_type: "JoinCourseRequest",
                                                 viewed: false)
              if params[:professor].present? && params[:professor].to_i == 1
                course_message.content = 2
                role = 9
                message = "教师申请已提交，请等待审核"
              else
                course_message.content = 3
                role = 7
                message = "助教申请已提交，请等待审核"
              end

              course_message.save!

              # role = course_message.content == 2 ? '9' : '7' # 7:助教 9:教师
              ApplyTeacherRoleJoinCourseNotifyJob.perform_later(current_user.id, course.id, role)
              # message = "#{course_message.content == 2 ? '教师' : '助教'}申请已提交，请等待审核"
            else
              message = "#{existing_course_message.content == '2' ? '教师' : '助教'}申请已提交，请等待审核"
            end
          else
            message = "您已是课堂成员"
          end
          teacher_role = 1
        end

        if teacher_role && student_role
          render json: { status: 0, message: message, course_id: course.id}
        elsif student_role
          render json: { status: 0, message: "加入成功", course_id: course.id}
        else
          normal_status(message)
        end
      rescue => e
        uid_logger(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  def top_banner
    @user = current_user
    @is_teacher = @user_course_identity < Course::STUDENT
    @is_student = @user_course_identity == Course::STUDENT
    @course.increment!(:visits)
  end

  def left_banner
    @user = current_user
    @is_teacher = @user_course_identity < Course::ASSISTANT_PROFESSOR
    @course_modules = @course.course_modules.where(hidden: 0)
    @hidden_modules = @course.course_modules.where(hidden: 1)
    @second_category_type = ["shixun_homework", "graduation", "attachment", "board", "course_group"]
  end

  def board_list
    begin
      @course = @board.course
      @current_user = current_user
      return normal_status(403, "你没有权限操作") if !@current_user.teacher_of_course?(@course) && !@current_user.course_identity(@current_user) == 4
      @boards = @course.boards
    rescue Exception => e
      uid_logger(e.message)
      tip_exception("获取数据失败")
      raise ActiveRecord::Rollback
    end
  end

  def attahcment_category_list
    @has_course_groups = @course.course_groups.exists?
    @course_modules = @course.attachment_course_modules
  end

  def mine
    @page  = params[:page]  || 1
    @page_size = params[:page_size] || 15

    @courses = Course.by_user(current_user).hidden(false).processing.not_deleted.by_keywords(params[:search]).distinct

    # @total_count = @courses.count
    # offset = 0
    # while offset < @total_count
    #
    #   offset = offset + @page_size.to_i + 1
    #   @courses = @courses.offset(offset)
    # end

    @courses= @courses.page(@page).per(@page_size)
  end

  # 导出课堂信息
  def export_couser_info
    set_export_cookies
    course_info_to_xlsx @course
    filename_ = "#{current_user.real_name}_#{@course.name}_课堂信息_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
    render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_course_info.xlsx.axlsx",
           locals: {course_info: @course_info}
  end

  # 导出活跃度
  def export_member_act_score
    search = params[:search] ? "#{params[:search].strip}" : ""   #用户名或学生学号id搜索
    group_id = params[:group_id]  #分班的班级id
    @all_members = student_act_score group_id, search
    if @all_members.size == 0
      normal_status(-1,"课堂暂时没有学生")
    elsif params[:export].present? && params[:export]
      normal_status(0,"正在下载中")
    else
      set_export_cookies
      act_score_to_xlsx(@all_members)
      filename_ = "#{current_user.real_name}_#{@course.name}_活跃度_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
      render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_act_score.xlsx.axlsx",
             locals: {activity_level:@user_activity_level}
    end
  end

  # 导出学生成绩
  def export_member_scores_excel
    ActiveRecord::Base.transaction do
      begin
        @all_members = @course.students
        search = params[:search] ? "#{params[:search].strip}" : ""   #用户名或学生学号id搜索
        group_id = params[:group_id]  #分班的班级id
        @all_members = @all_members.where(course_group_id: group_id) unless group_id.blank?
        unless search.blank?
          @all_members = @all_members.joins(user: [:user_extension]).where('concat(users.lastname, users.firstname) like ? or user_extensions.student_id like ?',"%#{search}%","%#{search}%")
        end

        if @all_members.length == 0
          normal_status(-1,"课堂暂时没有学生")
        elsif params[:export].present? && params[:export]
          normal_status(0,"正在下载中")
        else
          @c_homeworks = @course.homework_commons.homework_published.order("homework_commons.publish_time asc, homework_commons.created_at asc")
          @c_exercises = @course.exercises.is_exercise_published.order("exercises.publish_time asc, exercises.created_at asc")
          # @c_polls = @course.polls.publish_or_not.order("polls.publish_time asc, polls.created_at asc")
          @c_tasks = @course.graduation_tasks.task_published.order("graduation_tasks.publish_time asc, graduation_tasks.created_at asc")

          set_export_cookies
          member_to_xlsx(@course, @all_members, @c_homeworks, @c_exercises, @c_tasks)
          filename_ = "#{current_user.real_name}_#{@course.name}_总成绩_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
          render xlsx: "#{format_sheet_name filename_.strip}",template: "courses/export_member_scores_excel.xlsx.axlsx",
                 locals: {course_scores:@course_user_scores,shixun_works:@shixun_work_arrays,
                          common_works:@common_work_arrays,group_works:@group_work_arrays,task_works:@task_work_arrays,
                          exercise_works:@exercise_work_arrays}
        end

      rescue Exception => e
        uid_logger_error(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  def search_slim
    courses = current_user.manage_courses.not_deleted.processing

    keyword = params[:keyword].to_s.strip
    if keyword.present?
      courses = courses.where('name LIKE ?', "%#{keyword}%")
    end

    count = courses.count
    courses = paginate(courses)

    render_ok(count: count, courses: courses.select(:id, :name).as_json)
  end

  def tasks_list
    case params[:container_type]
    when 'shixun_homework'
      @tasks = @course.practice_homeworks
    when 'common_homework'
      @tasks = @course.normal_homeworks
    when 'group_homework'
      @tasks = @course.group_homeworks
    when 'exercise'
      @tasks = @course.exercises
    when 'poll'
      @tasks = @course.polls
    when 'graduation_topic'
      @tasks = @course.graduation_topics
    when 'graduation_task'
      @tasks = @course.graduation_tasks
    when 'attachment'
      @tasks = @course.attachments
    else
      tip_exception("请指定任务类型")
    end
  end

  def update_task_position
    Rails.logger.info("#######task_ids_length#{params[:task_ids].uniq.length}#########task_count:#{@tasks.count}")
    tip_exception("task_ids参数有误") if params[:task_ids].blank? || params[:task_ids].uniq.length != @tasks.count
    ActiveRecord::Base.transaction do
      begin
        @tasks.each do |task|
          position = params[:task_ids].reverse.index(task.id).to_i + 1
          task.update_attributes!(position: position)
        end
        normal_status(0, "移动成功")
      rescue Exception => e
        uid_logger(e.message)
        tip_exception(e.message)
        raise ActiveRecord::Rollback
      end
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_course
    @course = Course.find_by!(id: params[:id])
    tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin?
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def course_params
    params.require(:course).permit(:name, :class_period, :credit, :end_date, :is_public, :authentication, :professional_certification)
  end

  def validate_course_name
    tip_exception("课堂名称不能为空！") if params[:course][:name].blank?
    if params[:subject_id].blank? && @course.blank? || (@course && @course.subject.blank?)
      tip_exception("课程名称不能为空！") if params[:course_list_name].blank?
      tip_exception("课堂名称应以课程名称开头命名") unless params[:course][:name].index(params[:course_list_name]) &&
        params[:course][:name].index(params[:course_list_name]) == 0
    else
      @subject = @course.present? ? @course.subject : Subject.find_by!(id: params[:subject_id])
      tip_exception("开始时间不能为空") if params[:start_date].blank?
      tip_exception("结束时间不能为空") if params[:end_date].blank?
      tip_exception("结束时间必须晚于开始时间") if strf_date(params[:end_date]) <= strf_date(params[:start_date])
      tip_exception("开始时间和结束时间不能与往期开课时间重叠") if @course.nil? && @subject.max_course_end_date && strf_date(params[:start_date]) <= strf_date(@subject.max_course_end_date)
      validate_start_end_date if @course.present?
      tip_exception("开放课堂必须包含公告栏和在线学习模块") unless params[:course_module_types].include?("announcement") && params[:course_module_types].include?("online_learning")
    end
    tip_exception("课堂所属单位不能为空！") if params[:school].blank?
    tip_exception("请至少添加一个课堂模块") if params[:course_module_types].blank?
    @school = School.find_by!(name: params[:school].strip)
  end

  def validate_start_end_date
    prev_course = @subject.courses.where("id < #{@course.id}").last
    next_course = @subject.courses.where("id > #{@course.id}").first
    tip_exception("开始时间不能与往期开课时间重叠") if prev_course && strf_date(params[:start_date]) <= strf_date(prev_course.end_date)
    tip_exception("结束时间不能与后期开课时间重叠") if next_course && strf_date(params[:end_date]) >= strf_date(next_course.start_date)
  end

  # 超级管理员和课堂管理员的权限判断
  def admin_allowed
    unless @user_course_identity < Course::PROFESSOR
      tip_exception(403, "..")
    end
  end

  # 课堂教师的权限判断
  def teacher_allowed
    unless @user_course_identity < Course::STUDENT
      tip_exception(403, "..")
    end
  end

  # 课堂教师，课堂管理员以及超级管理员的权限判断
  def teacher_or_admin_allowed
    unless @user_course_identity < Course::ASSISTANT_PROFESSOR
      tip_exception(403, "..")
    end
  end

  def course_tasks
    case params[:container_type]
    when 'shixun_homework'
      @tasks = @course.practice_homeworks
    when 'common_homework'
      @tasks = @course.normal_homeworks
    when 'group_homework'
      @tasks = @course.group_homeworks
    when 'exercise'
      @tasks = @course.exercises
    when 'poll'
      @tasks = @course.polls
    when 'graduation_topic'
      @tasks = @course.graduation_topics
    when 'graduation_task'
      @tasks = @course.graduation_tasks
    when 'attachment'
      @tasks = @course.attachments
    else
      tip_exception("请指定任务类型")
    end
  end

  def validate_inform_params
    tip_exception("公告标题不能为空") if params[:name].blank?
    tip_exception("公告内容不能为空") if params[:description].blank?
  end

  # def find_container
  #   case params[:container_type]
  #   when 'shixun_homework', 'common_homework', 'group_homework'
  #     @task = HomeworkCommon.find_by(id: params[:container_id])
  #   when 'exercise'
  #     @task = Exercise.find_by(id: params[:container_id])
  #   when 'poll'
  #     @task = Poll.find_by(id: params[:container_id])
  #   when 'graduation_topic'
  #     @task = GraduationTopic.find_by(id: params[:container_id])
  #   when 'graduation_task'
  #     @task = GraduationTask.find_by(id: params[:container_id])
  #   when 'attachment'
  #     @task = Attachment.find_by(id: params[:container_id])
  #   else
  #     tip_exception("container_type参数有误")
  #   end
  # end

  def student_act_score group_id, search
    sql_select = %Q{SELECT cm.*,
        (SELECT max(student_id) FROM user_extensions WHERE user_extensions.user_id = cm.user_id) AS student_id,
        (SELECT count(messages.id) FROM messages join boards on messages.board_id = boards.id WHERE boards.course_id = #{@course.id}
                AND messages.author_id = cm.user_id and messages.parent_id is null) AS message_num,
        (SELECT count(messages.id) FROM messages join boards on messages.board_id = boards.id WHERE boards.course_id = #{@course.id}
                AND messages.author_id = cm.user_id and messages.parent_id is not null) AS message_reply_num,
        (SELECT count(attachments.id) FROM attachments WHERE container_id = #{@course.id} and container_type = "Course"
                AND attachments.author_id = cm.user_id) AS resource_num,
        (SELECT count(jfm.id) FROM journals_for_messages AS jfm, homework_commons hs WHERE jfm.jour_id = hs.id AND
                jfm.user_id = cm.user_id and jfm.jour_type = "HomeworkCommon" and hs.course_id = #{@course.id}) AS homework_journal_num,
        (SELECT COUNT(gw.id) FROM graduation_works AS gw, graduation_tasks AS gt WHERE gw.graduation_task_id = gt.id AND
                gt.course_id = #{@course.id} AND gw.work_status != 0 AND gw.user_id = cm.user_id) AS graduation_num,
        (SELECT COUNT(ss.id) FROM student_works AS ss ,homework_commons AS hc WHERE ss.homework_common_id = hc.id AND
                hc.course_id = #{@course.id} AND ss.work_status != 0 AND ss.user_id = cm.user_id) AS homework_num,
        (SELECT COUNT(eu.id) FROM exercise_users AS eu,exercises WHERE eu.exercise_id = exercises.id AND exercises.course_id = #{@course.id}
                AND eu.commit_status = 1 AND eu.user_id = cm.user_id) AS exercise_num,
        (SELECT COUNT(pu.id) FROM poll_users AS pu, polls WHERE pu.poll_id = polls.id AND polls.course_id = #{@course.id}
                AND pu.commit_status = 1 AND pu.user_id = cm.user_id) AS poll_num
        FROM course_members cm}
    if search.present? && group_id.present?
      sql_select += %Q{ join users on cm.user_id = users.id
                      join user_extensions ue on ue.user_id = users.id
                      WHERE cm.role = 4 and cm.course_id = #{@course.id} and cm.course_group_id = #{group_id} and
                      (concat(users.lastname, users.firstname) like '%#{search}%' or ue.student_id like '%#{search}%')}

    elsif search.present?
      sql_select += %Q{ join users on cm.user_id = users.id
                      join user_extensions ue on ue.user_id = users.id
                      WHERE cm.role = 4 and
                      (concat(users.lastname, users.firstname) like '%#{search}%' or ue.student_id like '%#{search}%')}
    elsif group_id.present?
      sql_select += %Q{ WHERE cm.role = 4 and cm.course_id = #{@course.id} and cm.course_group_id = #{group_id}}
    else
      sql_select += %Q{ WHERE cm.role = 4 and cm.course_id = #{@course.id}}
    end
    act_scores = CourseMember.find_by_sql(sql_select)
    act_scores
  end

  def course_info_to_xlsx course
    #课堂信息
    @course_info = []
    course_info_title = "课堂信息概要"
    course_id = course.id
    course_name = course.name
    course_list_name = course.course_list.present? ? course.course_list.name : "--"
    course_assistants = course.teachers
    course_assistants_count = course_assistants&.size
    course_assistants_name = course_assistants_count > 0 ? course_assistants.map{|m| m.user.real_name}.join('、') : "--"
    course_teacher_member = course.course_members.course_user_role(%i[CREATOR])
    course_teacher = course_teacher_member.present? ? course_teacher_member.first.user.real_name : "--"
    course_class_counts = course.course_groups_count
    course_students_count = course.students.size
    course_1 = ["课堂编号",course_id]
    course_2 = ["课程名称",course_list_name]
    course_3 = ["课堂名称",course_name]
    course_4 = ["教师团队(#{course_assistants_count})", course_assistants_name]
    course_5 = ["主讲教师", course_teacher]
    course_6 = ["分班",course_class_counts]
    course_7 = ["学生", course_students_count]
    course_main_info = [course_1,course_2,course_3,course_4,course_5,course_6,course_7]
    course_group_info_head = %w(序号 分班名称 邀请码 学生数量)
    course_group_info_body = []
    none_group_counts = course.none_group_count

    #当有未分班时，应该也做个统计
    if none_group_counts > 0
      none_group_index = 2
      no_group_array = [1,"未分班",course.invite_code,none_group_counts]
      course_group_info_body.push(no_group_array)
    else
      none_group_index = 1
    end

    if course.course_groups.exists?
      course.course_groups.each_with_index do |group, index|
        group_index = (index+none_group_index)
        group_name = group.name
        group_code = group.invite_code
        group_count = group.course_members_count
        group_array = [group_index,group_name,group_code,group_count]
        course_group_info_body.push(group_array)
      end

    end
    course_group_info = [course_group_info_head,course_group_info_body]
    @course_info += [course_info_title,course_main_info,course_group_info]
  end

  def act_score_to_xlsx all_members
    #课堂活跃度
    @user_activity_level = []
    course_user_level = []
    course_activity_title = "课堂活跃度统计"
    user_cell_head = %w(排名 真实姓名 登录名 邮箱 学号 学校 分班 作业完成数(*10) 试卷完成数(*10) 问卷完成数(*7) 资源发布数(*5) 帖子发布数(*2) 帖子回复数(*1) 作业回复数(*1) 活跃度)
    all_members.each do |u|
      #用户的基本信息
      user = u.user
      user_login = user.login
      user_name = user.real_name
      user_mail = user.mail
      user_stu_id = u.student_id.present? ? (u.student_id.to_s + "\t") : "--"
      user_school = user.school_name
      user_course_group = u.course_group_name

      #课堂活跃度统计
      user_homeworks_num = u.homework_num.to_i  #完成的作业数
      user_graduate_num = u.graduation_num.to_i  #毕业任务完成数
      user_exercise_num = u.exercise_num.to_i  #根据试卷的id来查找
      user_poll_num = u.poll_num.to_i  #已完成问卷
      user_file_num = u.resource_num.to_i
      user_messages_num = u.message_num.to_i  #帖子发布数
      user_reply_num = u.message_reply_num.to_i   #帖子回复数
      user_work_reply_num = u.homework_journal_num.to_i  #作业回复数的数量
      c_works_num = (user_homeworks_num + user_graduate_num)*10
      c_exercise_num = user_exercise_num*10
      c_poll_num = user_poll_num*7
      c_file_num = user_file_num*5
      c_message_num = user_messages_num*2
      c_reply_num = user_reply_num
      user_activity_levels = c_works_num + c_exercise_num + c_poll_num + c_file_num + c_message_num + c_reply_num + user_work_reply_num
      user_ac_level = {
        u_1: user_name,
        u_2: user_login,
        u_2_1: user_mail,
        u_3: user_stu_id,
        u_4: user_school,
        u_5: user_course_group,
        u_6: c_works_num,
        u_7: c_exercise_num,
        u_8: c_poll_num,
        u_9: c_file_num,
        u_10: c_message_num,
        u_11: c_reply_num,
        u_12: user_work_reply_num,
        u_13: user_activity_levels
      }
      course_user_level.push(user_ac_level)

      #.课堂活跃度统计的集合
      course_user_level = course_user_level.sort_by {|k| k[:u_13]}.reverse
      @user_activity_level = [course_activity_title,user_cell_head,course_user_level]
    end
  end

  def member_to_xlsx(course,all_members,homeworks,exercises,tasks)
    #课堂的作业信息
    shixun_homeworks = homeworks.search_homework_type(4)   #全部实训作业
    shixun_titles = shixun_homeworks.pluck(:name) + ["总得分"]

    # 更新实训作业成绩
    shixun_homeworks.includes(:homework_challenge_settings, :published_settings, :homework_commons_shixun).each do |homework|
      homework.update_homework_work_score
    end

    shixun_homeworks = shixun_homeworks&.includes(score_student_works: :user)

    common_homeworks = homeworks.search_homework_type(1) #全部普通作业
    common_titles = common_homeworks.pluck(:name)+ ["总得分"]
    common_homeworks = common_homeworks&.includes(score_student_works: :user)

    group_homeworks = homeworks.search_homework_type(3)  #全部分组作业
    group_titles = group_homeworks.pluck(:name)+ ["总得分"]
    group_homeworks = group_homeworks&.includes(score_student_works: :user)

    task_titles = tasks.pluck(:name) + ["总得分"]
    tasks = tasks&.includes(user: :user_extension, score_graduation_works: :user)

    exercise_titles = exercises.pluck(:exercise_name) + ["总得分"]
    exercises = exercises&.includes(user: :user_extension, score_exercise_users: :user)

    total_user_score_array = []   #学生总成绩集合

    all_members.each do |u|
      #用户的基本信息
      user = u.user
      user_login = user.login
      user_name = user.real_name
      user_mail = user.mail
      user_stu_id = user.student_id.present? ? (user.student_id.to_s + "\t") : "--"
      user_school = user.school_name
      user_course_group = u.course_group_name
      user_info_array = [user_name,user_login,user_mail,user_stu_id,user_school,user_course_group]   #用户的信息集合
      user_work_scores = []

      #学生总成绩
      shixun_score = 0.0 # 实训作业的总分
      common_score = 0.0 #普通作业的总分
      group_score = 0.0 #分组作业的总分
      task_score = 0.0 # 毕业任务的总得分
      exercise_score = 0.0 #试卷的总得分
      shixun_score_array = []
      common_score_array = []
      group_score_array = []
      task_score_array = []
      exercise_score_array = []

      #实训作业
      if shixun_homeworks.size > 0
        shixun_homeworks.each do |s|
          user_student_work = s.score_student_works.select{|work| work.user_id == user.id}.first   #当前用户的对该作业的回答
          if user_student_work.nil?
            h_score = 0.0  #该作业的得分为0
          else
            h_score = user_student_work.work_score.nil? ? 0.0 : user_student_work.work_score  #用户对该作业的分数
          end
          shixun_score_array.push(h_score)
        end
      end
      shixun_score += shixun_score_array.sum
      shixun_score_array.push(shixun_score)   #shixun_score_array的最后一行为总分
      user_work_scores += user_info_array + shixun_score_array   #单个用户的实训作业得分信息

      #普通作业
      if common_homeworks.size > 0
        common_homeworks.each do |c|
          user_student_work_1 = c.score_student_works.select{|work| work.user_id == user.id}.first  #当前用户的对该作业的回答
          if user_student_work_1.nil?
            h_score_1 = 0.0  #该作业的得分为0
          else
            h_score_1 = user_student_work_1.work_score.nil? ? 0.0 : user_student_work_1.work_score  #用户对该作业的分数
          end
          common_score_array.push(h_score_1)
        end
      end
      common_score += common_score_array.sum
      common_score_array.push(common_score)   #shixun_score_array的最后一行为总分
      user_work_scores += common_score_array   #单个用户的普通作业得分信息

      #分组作业
      if group_homeworks.size > 0
        group_homeworks.each do |g|
          user_student_work_3 = g.score_student_works.select{|work| work.user_id == user.id}.first   #当前用户的对该作业的回答
          if user_student_work_3.nil?
            h_score_3 = 0.0  #该作业的得分为0
          else
            h_score_3 = user_student_work_3.work_score.nil? ? 0.0 : user_student_work_3.work_score  #用户对该作业的分数
          end
          group_score_array.push(h_score_3)
        end
      end
      group_score += group_score_array.sum
      group_score_array.push(group_score)   #shixun_score_array的最后一行为总分
      user_work_scores += group_score_array   #单个用户的分组作业得分信息

      #毕设作业
      if tasks.size > 0
        tasks.each do |task|
          graduation_work = task.score_graduation_works.select{|work| work.user_id == user.id}.first
          if graduation_work.nil?
            t_score = 0.0
          else
            t_score = graduation_work.work_score.nil? ? 0.0 : graduation_work.work_score
          end
          task_score_array.push(t_score)
        end
      end
      task_score += task_score_array.sum
      task_score_array.push(task_score)
      user_work_scores += task_score_array   #单个用户的分组作业得分信息

      #试卷
      if exercises.size > 0
        exercises.each do |ex|
          exercise_work = ex.score_exercise_users.select{|work| work.user_id == user.id}.first
          if exercise_work.nil?
            e_score = 0.0
          else
            e_score = exercise_work.score.nil? ? 0.0 : exercise_work.score
          end
          exercise_score_array.push(e_score)
        end
      end
      exercise_score += exercise_score_array.sum
      exercise_score_array.push(exercise_score)

      user_work_scores += exercise_score_array   #单个用户的分组作业得分信息
      total_user_scores = shixun_score + common_score + group_score + task_score + exercise_score
      user_work_scores.push(total_user_scores)  #个人的行内容添加总成绩
      total_user_score_array.push(user_work_scores)  # 全部成员的集合
    end

    #2.学生总成绩的集合
    ## 作业标题的集合
    course_user_score_title = "学生总成绩"
    score_title_cells = shixun_titles + common_titles + group_titles + task_titles + exercise_titles
    score_title_counts = [shixun_titles.count,common_titles.count,group_titles.count,task_titles.count,exercise_titles.count]
    score_cell_head = %w(序号 真实姓名 登录名 邮箱 学号 学校 分班) + score_title_cells + ["个人总成绩"]
    @course_user_scores = [course_user_score_title,score_cell_head,score_title_counts,total_user_score_array]

    #作业的全部集合
    @shixun_work_arrays = []
    @group_work_arrays = []
    @common_work_arrays = []
    @task_work_arrays = []
    @exercise_work_arrays = []
    count_1 = shixun_homeworks.size
    count_2 = common_homeworks.size
    count_3 = group_homeworks.size
    count_4 = tasks.size
    #实训作业
    shixun_homeworks.each_with_index do |s,index|
      all_student_works = s.score_student_works   #该实训题的全部用户回答
      title_no = index.to_i + 1
      student_work_to_xlsx(all_student_works,s)
      shixun_work_display_name = format_sheet_name (title_no.to_s + "." + s.name).strip.first(30)
      shixun_work_content = [shixun_work_display_name,@work_head_cells,@work_cells_column]
      @shixun_work_arrays.push(shixun_work_content)
    end

    #普通作业
    common_homeworks.each_with_index do |c,index|
      all_student_works = c.score_student_works   #当前用户的对该作业的回答
      title_no = count_1 + index.to_i + 1
      student_work_to_xlsx(all_student_works,c)

      work_name = format_sheet_name (title_no.to_s + "." + c.name).strip.first(30)
      work_content = [work_name,@work_head_cells,@work_cells_column]
      @common_work_arrays.push(work_content)
      title_no
    end

    #分组作业
    group_homeworks.each_with_index do |c,index|
      all_student_works = c.score_student_works   #当前用户的对该作业的回答
      title_no = count_1 + count_2 + index.to_i + 1
      student_work_to_xlsx(all_student_works,c)
      work_name = format_sheet_name (title_no.to_s + "." + c.name).strip.first(30)
      work_content = [work_name,@work_head_cells,@work_cells_column]
      @group_work_arrays.push(work_content)
    end

    #毕设任务
    tasks.each_with_index do |c,index|
      all_student_works = c.score_graduation_works   #当前用户的对该作业的回答
      title_no = count_1 + count_2 + count_3 + index.to_i + 1
      graduation_work_to_xlsx(all_student_works,c,current_user)
      work_name = format_sheet_name (title_no.to_s + "." + c.name).strip.first(30)
      work_content = [work_name,@head_cells_column,@task_cells_column]
      @task_work_arrays.push(work_content)
    end

    #试卷的导出
    exercises.each_with_index do |c,index|
      all_student_works = c.score_exercise_users   #当前用户的对该作业的回答
      title_no = count_1 + count_2 + count_3 + count_4 + index.to_i + 1
      get_export_users(c,course,all_student_works)
      work_name = format_sheet_name (title_no.to_s + "." + c.exercise_name).strip.first(30)
      work_content = [work_name,@table_columns,@user_columns]
      @exercise_work_arrays.push(work_content)
    end
  end
end
