module ExportHelper
  include ApplicationHelper
  require "base64"
  require 'zip'

  # 附件导出最大值
  MAX_DOWN_SIZE = 500 * 1024 * 1024
  SAVE_FOLDER = "#{Rails.root}/files"
  OUTPUT_FOLDER = "#{Rails.root}/files/archiveZip"
  MAX_PATH = 50

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

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

    shixun_homeworks = shixun_homeworks&.includes(:student_works)

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

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

    task_titles = tasks.pluck(:name) + ["总得分"]
    tasks = tasks&.includes(:graduation_works)

    exercise_titles = exercises.pluck(:exercise_name) + ["总得分"]
    exercises = exercises&.includes(:exercise_users)

    shixuns = shixuns&.includes(:myshixuns).where(myshixuns: {user_id: all_members.pluck(:user_id)}).
        includes(:myshixuns=>[:games]).where(games: {status: 2}).
        includes(:myshixuns=>[:games=>[:game_answers]]).
        includes(:myshixuns=>[:user]).
        where(users: {id: all_members.pluck(:user_id)}).
        includes(:myshixuns=>[:user=>[:user_extension]]).
        includes(:challenges)
    course_stage_shixun_titles = shixuns.distinct.pluck(:name) + ["总得分"]

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

    # 该开放课程下的所有在线学习的实训项目
    # myshixuns = Myshixun.joins(:shixun).where(shixuns: {id: shixuns.pluck(:id)}).
    #     includes(:user).where(user_id: all_members.pluck(:user_id))
    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_grade = user.grade
      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_grade,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 #试卷的总得分
      course_stage_shixun_score = 0.0 #在线学习下的实训项目总得分
      shixun_score_array = []
      common_score_array = []
      group_score_array = []
      task_score_array = []
      exercise_score_array = []
      course_stage_shixun_score_array = []

      #实训作业
      if shixun_homeworks.size > 0
        shixun_homeworks.each do |s|
          user_student_work = s.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的最后一行为总分

      #普通作业
      if common_homeworks.size > 0
        common_homeworks.each do |c|
          user_student_work_1 = c.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的最后一行为总分

      #分组作业
      if group_homeworks.size > 0
        group_homeworks.each do |g|
          user_student_work_3 = g.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的最后一行为总分

      #毕设作业
      if tasks.size > 0
        tasks.each do |task|
          graduation_work = task.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)

      #试卷
      if exercises.size > 0
        exercises.each do |ex|
          exercise_work = ex.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)

      # 在线学习实训项目
      if shixuns.size > 0
        shixuns.each do |shixun|
          myshixun = shixun.myshixuns.select{|myshixun| myshixun.user_id == user.id}.first
          if myshixun.nil?
            cs_score = 0.0
          else
            cs_score = (myshixun.total_score * 100.0/ myshixun.shixun.all_score).round
          end
          course_stage_shixun_score_array.push(cs_score)
        end
      end
      course_stage_shixun_score += course_stage_shixun_score_array.sum
      course_stage_shixun_score_array.push(course_stage_shixun_score)

      total_user_scores = shixun_score + common_score + group_score + task_score + exercise_score + course_stage_shixun_score
      user_info_array.push(total_user_scores)  #个人的行内容添加总成绩
      user_work_scores += user_info_array + shixun_score_array + common_score_array + group_score_array + task_score_array + exercise_score_array + course_stage_shixun_score_array
      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 + course_stage_shixun_titles
    score_title_counts = [
      shixun_titles.count,
      common_titles.count,
      group_titles.count,
      task_titles.count,
      exercise_titles.count,
      course_stage_shixun_titles.count
    ]
    score_cell_head = %w(序号 真实姓名 登录名 邮箱 学号 金币 学校 分班 个人总成绩) + score_title_cells
    #                      第一张sheet标题           第一张sheet头部标题 各个作业以及试卷的总数量 各个用户总分数数组
    @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 = []
    @course_stage_shixun_arrays = []
    count_1 = shixun_homeworks.size
    count_2 = common_homeworks.size
    count_3 = group_homeworks.size
    count_4 = tasks.size
    count_5 = exercises.size

    all_user_ids = all_members.pluck(:user_id)
    # 各个模块的成绩表
    #实训作业
    # [
      # [
      #   "1.顺序结构程序设计",
      #   [
      #     "序号", "登录名", "真实姓名", "邮箱", "学号", "分班", "提交状态", "截止前完成关卡",
      #     "通关时间", "最新完成关卡", "最后完成时间", "学员在EduCoder做实训花费的时间", "总评测次数",
      #     "获得经验值", "关卡得分", "最终成绩", "更新时间", "作业发布到学员完成作业所耗的时间", "总评语",
      #     "第1关评语", "第2关评语", "第3关评语", "第4关评语", "第5关评语", "第6关评语", "第7关评语", "第8关评语"
      #   ],
      #   [
      #     [
      #       1, "innov", "实践教学呀", "721773699@qq.com", "--", "未分班", "未通关", "6/8",
      #       "--", "6/8", "--", "39分钟 17秒", 40, 600, 75.0, 75.0, "2020-04-29 18:31", "未完成",
      #       "--", "--", "--", "--", "--", "--", "--", "--", "--"
      #     ],
      #     [
      #       2, "ms5a462p9", "longhaoran",
      #       "18621781488@163.com", "--", "未分班", "未通关", "0/8", "--", "0/8", "--", "--", 0, 0, 0.0,
      #       0.0, "2020-04-18 00:03", "未完成", "--", "--", "--", "--", "--", "--", "--", "--", "--"
      #     ]
      #   ]
      # ],
      # [
      #   "2.顺序结构程序设计",
      #   [
      #     "序号", "登录名", "真实姓名", "邮箱", "学号", "分班", "提交状态", "截止前完成关卡",
      #     "通关时间", "最新完成关卡", "最后完成时间", "学员在EduCoder做实训花费的时间", "总评测次数",
      #     "获得经验值", "关卡得分", "最终成绩", "更新时间", "作业发布到学员完成作业所耗的时间", "总评语",
      #     "第1关评语", "第2关评语", "第3关评语", "第4关评语", "第5关评语", "第6关评语", "第7关评语", "第8关评语"
      #   ],
      #   [
      #     [
      #       1, "innov", "实践教学呀", "721773699@qq.com", "--", "未分班", "未通关", "6/8",
      #       "--", "6/8", "--", "39分钟 17秒", 40, 600, 75.0, 75.0, "2020-04-29 18:31", "未完成",
      #       "--", "--", "--", "--", "--", "--", "--", "--", "--"
      #     ],
      #     [
      #       2, "ms5a462p9", "longhaoran",
      #       "18621781488@163.com", "--", "未分班", "未通关", "0/8", "--", "0/8", "--", "--", 0, 0, 0.0,
      #       0.0, "2020-04-18 00:03", "未完成", "--", "--", "--", "--", "--", "--", "--", "--", "--"
      #     ]
      #   ]
      # ]
    # ]
    shixun_homeworks.each_with_index do |s,index|
      all_student_works = s.student_works.where(user_id: all_user_ids)   #该实训题的全部用户回答
      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.student_works.where(user_id: all_user_ids)    #当前用户的对该作业的回答
      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.student_works.where(user_id: all_user_ids)   #当前用户的对该作业的回答
      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.graduation_works.where(user_id: all_user_ids)   #当前用户的对该作业的回答
      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.exercise_users.where(user_id: all_user_ids)   #当前用户的对该作业的回答
      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

    # 在线学习的导出
    shixuns.each_with_index do |shixun, index|
      title_no = count_1 + count_2 + count_3 + count_4 + count_5 + index.to_i + 1
      shixun_scores_by_course_to_xlsx(shixun, course: course)
      work_name = format_sheet_name (title_no.to_s + "." + shixun.name).strip.first(30)
      work_content = [work_name, @work_head_cells, @work_cells_column]
      @course_stage_shixun_arrays.push(work_content)
    end
  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 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

  # 导出实训下学生成绩，可以根据指定的课程id来导出
  # 目前用于: 将金课课程下的某一个阶段下的某一个实训的学生成绩导出
  def shixun_scores_by_course_to_xlsx(shixun, course: nil)
    @work_head_cells = %w(
      序号 登录名 真实姓名 邮箱 学号 分班 提交状态 通关时间 最新完成关卡
      最后完成时间 学员在EduCoder做实训花费的时间 总评测次数 获得经验值 获得分数
    )
    shixun.challenges.count.times do |i|
      @work_head_cells << "第#{i+1}关是否查看过答案/查看答案时间"
    end
    @work_cells_column = []
    myshixuns = shixun.myshixuns
    myshixuns = myshixuns.where(user_id: course.students.pluck(:user_id)) if course.present?
    myshixuns.each_with_index do |myshixun, index|
      user = myshixun.user
      # 序号
      w_1 = (index + 1)
      # 登录名
      w_2 = user&.login.present? ? user&.login : "--"
      # 真实姓名
      w_3 = user&.real_name.present? ? user&.real_name : "--"
      # 邮箱
      w_4 = user&.mail.present? ? user.mail : "--"
      # 学号
      w_5 = user.student_id.present? ? (user.student_id.to_s + "\t") : "--"
      course_name = course.students.where(user: user).first.try(:course_group_name) if course.present?
      # 分班名称
      w_6 = course_name.present? ? course_name : "--"
      #0： 未提交， 1 按时提交， 2 延迟提交
      # 提交状态
      w_7 = "--"
      # 通关时间
      w_8 = myshixun.passed_time.to_s == "--" ? "--" : myshixun.passed_time.strftime("%Y-%m-%d %H:%M")
      # 最新完成关卡
      w_9 = myshixun.passed_count.to_s+"/"+shixun.challenges_count.to_s
      # 最后完成时间
      w_10 = myshixun.passed_time
      # 学员在Educoder做实训花费的时间
      w_11 = myshixun.total_spend_time
      # 总评测次数
      w_12 = myshixun ? myshixun.output_times : 0  #评测次数
      # 获得经验值
      w_13 = myshixun.total_score
      # 获得分数
      w_14 = (myshixun.total_score*100.0/myshixun.shixun.all_score).round
      # 第#{i}关是否查看答案/查看答案时间
      w_15 = myshixun.games.collect{|game| game.answer_open == 0 ? "未查看答案" : game.game_answers.take&.view_time&.strftime("%Y-%m-%d %H:%M:%S").to_s}
      row_cells_column = [w_1, w_2, w_3, w_4, w_5, w_6, w_7, w_8, w_9, w_10, w_11, w_12, w_13, w_14] + w_15

      row_cells_column = row_cells_column.reject(&:blank?)
      @work_cells_column.push(row_cells_column)
    end
  end

  # 作业导出为xlsx，homework_type 1：普通作业  2：编程作业（弃用） 3：分组作业  4：实训作业
  def student_work_to_xlsx(works,homework)
    @work_head_cells = []
    @work_cells_column = []
    course = homework.course
    head_cells_format = %w(序号 登录名 真实姓名 邮箱 学号 分班 提交状态)
    allow_late_boolean = homework.allow_late
    if allow_late_boolean  #允许迟交
      allow_late_cell = ["迟交扣分"]
    else
      allow_late_cell = []
    end
    if homework.homework_type != "practice"    #普通作业/分组作业
      homework_type_name = homework.homework_type
      if homework_type_name == "group"   #分组作业
        group_cells = ["关联项目"]
      else
        group_cells = []
      end
      normal_head_cells = %w(作品描述 教师评分 教辅评分)
      anon_boolean = homework.anonymous_comment
      if anon_boolean
        head_cells_add = %w(匿名评分 已评数 缺评扣分 违规匿评申诉扣分)
      else
        head_cells_add = []
      end
      normal_head_b_cells = %w(最终成绩 提交时间 更新时间 评语)
      @work_head_cells = (head_cells_format + group_cells + normal_head_cells + head_cells_add + allow_late_cell + normal_head_b_cells).reject(&:blank?)
      works.includes(user: :user_extension, student_works_scores: :user).each_with_index do |w, index|
        w_user = w.user
        w_1 = (index + 1)
        if w_user.present?
          w_2 = w_user&.login.present? ? w_user&.login : "--"
          w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
          w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
          w_4 = w_user.student_id.present? ? (w_user.student_id.to_s + "\t") : "--"
        else
          w_2 = "--"
          w_3 = "--"
          w_3_1 = "--"
          w_4 = "--"
        end
        course_name = course.students.find_by(user_id: w.user_id).try(:course_group_name)
        w_5 = course_name.present? ? course_name : "--"
        #0： 未提交， 1 按时提交， 2 延迟提交
        if w.work_status == 0
          w_6 = "未提交"
        elsif w.work_status == 1
          w_6 = "按时提交"
        elsif w.work_status == 2
          w_6 = "延迟提交"
        else
          w_6 = "--"
        end
        if homework_type_name == "group"
          project_name = w.project
          if project_name.present?
            w_7 = w.project.name
          else
            w_7 = "--"
          end
        else
          w_7 = nil
        end
        w_8 = w.description.present? ? strip_html(w.description) : "--"
        w_9 = w.teacher_score.nil? ? "未评分" : w.teacher_score.round(1)
        w_10 = w.teaching_asistant_score.nil? ? "未评分" : w.teaching_asistant_score.round(1)
        if anon_boolean
          w_11 = w.student_score.nil? ? "未评分" : w.student_score.round(1)
          w_12 = w.user_comment_num
          w_13 = (homework.teacher_priority == 1 && !w.teacher_score.nil?) ? 0 : w.absence_penalty  #缺评扣分
          home_work_de = homework.homework_detail_manual
          w_14 = home_work_de.present? ? home_work_de.appeal_penalty : "--"  #违规匿评申诉扣分
        else
          w_11,w_12,w_13,w_14 = nil
        end
        if allow_late_boolean  #允许迟交
          w_15 = (homework.teacher_priority == 1 && !w.teacher_score.nil?) ? 0 : w.late_penalty  #迟交扣分
        else
          w_15 = nil
        end
        w_16 = w.work_score.nil? ? "未评分" : w.work_score.round(1)
        w_17 = w.commit_time ? format_time(w.commit_time) : "--"
        w_18 = w.update_time ? format_time(w.update_time) : "--"
        teacher_comments = w.student_works_scores
        if teacher_comments.present?
          w_19 = ""
          teacher_comments.each do |t|
            user_name = t.user&.real_name
            user_time = format_time(t.updated_at)
            user_score = t&.score
            user_comment = t.comment.present? ? t.comment : "--"
            comment_title = "#{user_name}： #{user_time.to_s}  #{user_score.to_s}分\n#{user_comment}\n\n"
            w_19 = w_19 + comment_title
          end
        else
          w_19 = "--"
        end

        row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18,w_19]
        row_cells_column = row_cells_column.reject(&:blank?)
        @work_cells_column.push(row_cells_column)
      end
    else   #实训题
      shixun = homework.shixuns.take
      shixun_head_cells = %w(截止前完成关卡 通关时间 最新完成关卡 最后完成时间 学员在EduCoder做实训花费的时间 总评测次数 获得经验值 关卡得分)
      eff_boolean = homework.work_efficiency
      if eff_boolean
        eff_score_cell = ["效率分"]
      else
        eff_score_cell = []
      end
      if allow_late_boolean  #允许迟交
        eff_score_cell.push("迟交扣分")
      end
      shixun_time_cells = %w(最终成绩 更新时间 作业发布到学员完成作业所耗的时间 总评语)
      for i in 1 .. shixun.challenges.size
        shixun_time_cells << "第#{i}关评语"
      end
      @work_head_cells = (head_cells_format + shixun_head_cells + eff_score_cell + shixun_time_cells).reject(&:blank?)
      works.includes(:shixun_work_comments, :student_works_scores, user: :user_extension, myshixun: :games).each_with_index do |w, index|
        myshixun = w.try(:myshixun)
        w_user = w.user
        w_1 = (index + 1)
        w_2 = w_user&.login.present? ? w_user&.login : "--"
        w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
        w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
        w_4 = w_user.student_id.present? ? (w_user.student_id.to_s + "\t") : "--"
        course_name = course.students.find_by(user_id: w.user_id).try(:course_group_name)
        w_5 = course_name.present? ? course_name : "--"
        #0： 未提交， 1 按时提交， 2 延迟提交
        if w.compelete_status == -1
          w_6 = "重做中"
        elsif w.compelete_status == 0
          w_6 = "未开启"
        elsif w.compelete_status == 1
          w_6 = "未通关"
        elsif w.compelete_status == 2
          w_6 = "按时通关"
        elsif w.compelete_status == 3
          w_6 = "迟交通关"
        else
          w_6 = "--"
        end
        w_7 = myshixun&.time_passed_count(homework.homework_group_setting(w.user_id)&.end_time).to_i.to_s+"/"+shixun.challenges_count.to_s
        w_8 = myshixun ? myshixun.try(:passed_time).to_s == "--" ? "--" : format_time(myshixun.try(:passed_time)) : "--"  # 通关时间
        w_8_1 = (myshixun ? myshixun.passed_count :  w_user.myshixuns.where(shixun: shixun).take&.passed_count).to_i.to_s+"/"+shixun.challenges_count.to_s # 最新完成关卡
        # 最后一次通过时间,也就是也有可能没有在作业规定内通过,但是在规定时间之外通过了该实训
        my_last_shixun = myshixun.present? ? myshixun : w_user.myshixuns.where(shixun: shixun).take
        w_8_2 = my_last_shixun&.passed_time == "--" ? "--" : format_time(my_last_shixun&.passed_time)
        w_9 = myshixun ? (myshixun.try(:passed_count).to_i > 0 ? myshixun.total_spend_time : '--') : "--"  #总耗时
        w_10 = myshixun ? myshixun.output_times : 0  #评测次数
        w_11 = myshixun ? myshixun.total_score : "--"  #获得经验值
        w_12 = w.final_score.present? ? w.final_score : 0
        if eff_boolean
          w_13 = w.eff_score
        else
          w_13 = nil
        end
        if allow_late_boolean  #允许迟交
          w_14 = w.late_penalty  #迟交扣分
        else
          w_14 = nil
        end
        w_15 = w.work_score.nil? ? "--" : w.work_score.round(1)
        w_16 = w.update_time ? format_time(w.update_time) : "--"
        myshixun_complete = myshixun && myshixun.status == 1
        w_17 = myshixun_complete && w.cost_time ? (game_spend_time w.cost_time) : "未完成"
        teacher_comment = w.shixun_work_comments.select{|comment| comment.challenge_id == 0}.first
        if teacher_comment.present?
          w_18 = "学生可见：\n #{teacher_comment.comment.to_s} \n\n  老师可见：\n#{teacher_comment.hidden_comment.to_s}"
        else
          w_18 = "--"
        end
        row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_8_1,w_8_2,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18]

        # 关卡评语
        shixun.challenges.pluck(:id).each do |challenge_id|
          challenge_comment = w.shixun_work_comments.select{|comment| comment.challenge_id == challenge_id}.first
          row_cells_column << (challenge_comment.present? ? "学生可见：\n #{challenge_comment.comment.to_s} \n\n  老师可见：\n#{challenge_comment.hidden_comment.to_s}" : "--")
        end

        row_cells_column = row_cells_column.reject(&:blank?)
        @work_cells_column.push(row_cells_column)
      end
    end
  end

  #毕设任务的导出
  def graduation_work_to_xlsx(items,task,current_user)
    head_cells_format = %w(序号 登录名 真实姓名 邮箱 学号 分班)
    task_type_boolean = task.task_type == 2
    if task_type_boolean   #是否分组
      head_cells_format = head_cells_format + ["分组"]
    end
    head_cells_format = head_cells_format + ["提交状态"]
    task_project_boolean = task.base_on_project
    if task_project_boolean  #关联项目
      head_cells_format = head_cells_format + ["关联项目"]
    end

    head_cells_format = head_cells_format + %w(作品描述 教师评分)

    task_comment_boolean = task.cross_comment
    if task_comment_boolean  #是否交叉评阅
      head_cells_format = head_cells_format + ["交叉评分"]
    end

    head_cells_format = head_cells_format + %w(迟交扣分 最终成绩 提交时间 更新时间 评语)

    @head_cells_column = head_cells_format
    @task_cells_column = []

    items.includes(user: :user_extension).each_with_index do |work,index|
      w_1 = (index+1)
      w_user = work.user
      w_2 = w_user&.login.present? ? w_user&.login : "--"
      w_3 = w_user&.real_name.present? ? w_user&.real_name : "--"
      w_3_1 = w_user&.mail.present? ? w_user.mail : "--"
      w_4 = w_user.student_id.present? ? (w_user.student_id.to_s + "\t") : "--"
      w_5 = work.class_grouping_name
      if task_type_boolean   #是否分组
        w_6 = work.grouping_name
      else
        w_6 = nil
      end
      w_status = work.work_status.to_i
      if w_status == 0
        w_7 = "未提交"
      elsif w_status == 1
        w_7 = "按时提交"
      elsif w_status == 2
        w_7 = "延时提交"
      else
        w_7 = "--"
      end
      if task_project_boolean  #关联项目
        w_project = project_info work, current_user, @user_course_identity   #因为课堂引用了export_helper
        w_8 = w_project[:name]
      else
        w_8 = nil
      end

      if work.description
        w_9 = strip_html work.description
      else
        w_9 = "--"
      end

      w_10 = work.teacher_score.nil? ? "未评分" : work.teacher_score.round(1)
      if task_comment_boolean  #是否交叉评阅
        w_11 = work.cross_score.nil? ? "未评分" : work.cross_score.round(1)
      else
        w_11 = nil
      end
      w_12 = work.late_penalty
      w_13 = work.work_score.nil? ? "未评分" : work.work_score.round(1)
      w_14 = work.commit_time.present? ? format_time(work.commit_time) : "--"
      w_15 = work.update_time.present? ? format_time(work.update_time) : "--"
      teacher_comments = work.graduation_work_scores
      if teacher_comments.present?
        w_16 = ""
        teacher_comments.each do |t|
          user_name = t.user&.real_name
          user_time = format_time(t.updated_at)
          user_score = t&.score
          user_comment = t.comment.present? ? t.comment : "--"
          comment_title = "#{user_name}： #{user_time.to_s}  #{user_score.to_s}分\n#{user_comment}\n\n"
          # ("教师:" + user_name + "\n" + "时间:" + user_time.to_s + "\n" + "分数:" + user_score.to_s + "分" + "\n" + "评语:" + user_comment + "\n\n")
          w_16 = w_16 + comment_title
        end
      else
        w_16 = "--"
      end
      row_cells_column = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16]

      row_cells_column = row_cells_column.reject(&:blank?)
      @task_cells_column.push(row_cells_column)
    end
  end

  #试卷的导出
  def get_export_users(exercise,course,export_ex_users)
    question_types = exercise.exercise_questions.pluck(:question_type).uniq
    @table_columns = %w(序号 登录名 真实姓名 邮箱 学号 分班 提交状态)
    @user_columns = []
    ques_type_boolean = question_types.include?(4)
    if ques_type_boolean  #仅存在主观题或客观题的时候
      @table_columns = @table_columns + %w(客观题成绩 主观题成绩 最终成绩)
    else
      @table_columns = @table_columns + %w(最终成绩)
    end
    for i in 1 .. exercise.exercise_questions.size
      @table_columns = @table_columns + ["第#{i}题"]
    end

    @table_columns = @table_columns + %w(开始答题时间 提交时间)

    questions = exercise.exercise_questions.includes(:exercise_answers,:exercise_shixun_answers).order("question_number ASC")

    export_ex_users.includes(user: :user_extension).each_with_index do |e_user,index|
      user_info = e_user.user
      user_course = course.user_group_name(e_user.user_id)
      user_obj_score = e_user.objective_score < 0.0 ? 0.0 : e_user.objective_score.round(1).to_s
      user_suj_score = e_user.subjective_score < 0.0 ? 0.0 : e_user.subjective_score.round(1).to_s
      user_score = e_user.score.present? ? e_user.score.round(1).to_s : 0.0
      if e_user.commit_status.present? && e_user.commited?
        user_commit_stu = "按时提交"
      else
        user_commit_stu = "未提交"
      end
      user_start_time = e_user.start_at.present? ? e_user.start_at.strftime('%Y-%m-%d %H:%M') : "--"
      user_end_time = e_user.end_at.present? ? e_user.end_at.strftime('%Y-%m-%d %H:%M') : "--"
      user_student_id = user_info.student_id.present? ? (user_info.student_id.to_s + "\t") : "--"
      user_login = user_info&.login.present? ? user_info.login : "--"
      user_real_name = user_info.real_name.present? ? user_info.real_name : "--"
      user_mail = user_info&.mail.present? ? user_info.mail : "--"

      user_option = [index+1,user_login,user_real_name, user_mail,
                     user_student_id,user_course,user_commit_stu]
      if ques_type_boolean
        other_user_option = [user_obj_score,user_suj_score,user_score]
      else
        other_user_option = [user_score]
      end

      time_option = [user_start_time,user_end_time]

      score_option = []
      questions.each do |q|
        q_type = q.question_type
        if q_type == Exercise::PRACTICAL
          answers_content = q.exercise_shixun_answers.select{|answer| answer.user_id == e_user.user_id}
        else
          answers_content = q.exercise_answers.select{|answer| answer.user_id == e_user.user_id}
        end

        if q_type <= Exercise::JUDGMENT || q_type == Exercise::SUBJECTIVE
          if answers_content.present?   #学生有回答时,分数已经全部存到exercise_answer 表，所以可以直接取第一个值
            ques_score = answers_content.first.score
            ques_score = ques_score.nil? || ques_score < 0 ? 0.0 : ques_score
          else
            ques_score = 0.0
          end
        else
          ques_score = answers_content.select{|answer| answer.score >= 0.0}.pluck(:score).sum
        end
        score_option << ques_score
      end

      user_option = user_option + other_user_option + score_option + time_option
      @user_columns.push(user_option)
    end
  end

  #毕设选题的导出
  def graduation_topic_to_xlsx(students,course)
    @topic_head_cells = %w(序号 登录名 真实姓名 邮箱 学号 分班 课题名称 指导教师 教师职位 设计 论文 创作 生产/社会实际 结合科研 其它 真题 模拟题 纵向课题 横向课题 自选 新题 往届题，有新要求
                           往届题，无新要求 课题来源单位 调研或实习地点 确认结果)

    @topic_body_cells = []
    if students.count > 0
      students.includes(user: :user_extension).each_with_index do |student, index|
        user = student.user
        student_topic = course.student_graduation_topics.user_topics_accept(user.id).first
        if student_topic.present?
          topic = student_topic.graduation_topic
        else
          student_topic = nil
          topic = nil
        end
        w_1 = (index+1)
        w_2 = user&.login.present? ? user&.login : "--"
        w_3 = user&.real_name.present? ? user&.real_name : "--"
        w_3_1 = user&.mail.present? ? user.mail : "--"
        w_4 = user.student_id.present? ? (user.student_id.to_s + "\t") : "--"
        w_5 = student&.course_group_name.present? ? student.course_group_name : "--"
        w_6 = topic.present? ? topic.name : "--"
        w_7 = topic.present? ? topic.teacher.full_name : "--"
        w_8 = topic.present? ? topic.teacher.identity : "--"

        if topic.present?
          w_9 = topic.topic_type == 1 ? "√" : ""
          w_10 = topic.topic_type == 2 ? "√" : ""
          w_11 = topic.topic_type == 3 ? "√" : ""
          w_12 = topic.topic_source == 1 ? "√" : ""
          w_13 = topic.topic_source == 2 ? "√" : ""
          w_14 = topic.topic_source == 3 ? "√" : ""
          w_15 = topic.topic_property_first == 1 ? "√" : ""
          w_16 = topic.topic_property_first == 2 ? "√" : ""
          w_17 = topic.topic_property_second == 1 ? "√" : ""
          w_18 = topic.topic_property_second == 2 ? "√" : ""
          w_19 = topic.topic_property_second == 3 ? "√" : ""
          w_20 = topic.topic_repeat == 1 ? "√" : ""
          w_21 = topic.topic_repeat == 2 ? "√" : ""
          w_22 = topic.topic_repeat == 3 ? "√" : ""
          w_23 = topic.source_unit
          w_24 = "#{topic.province}#{topic.city}"
        else
          w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18,w_19,w_20,w_21,w_22,w_23,w_24 = "--"
        end
        if student_topic.present?
          w_25 = student_topic.status == 0 ? "待确认" : "已同意"
        else
          w_25 = "--"
        end
        student_info_array = [w_1,w_2,w_3,w_3_1,w_4,w_5,w_6,w_7,w_8,w_9,w_10,w_11,w_12,w_13,w_14,w_15,w_16,w_17,w_18,w_19,w_20,w_21,w_22,w_23,w_24,w_25]
        @topic_body_cells.push(student_info_array)
      end
    end
  end

  def encode64(str)
    Base64.urlsafe_encode64(str)
  end

  def decode64(str)
    Base64.urlsafe_decode64(str)
  end

  # 检测文件大小是否超过500m
  def checkfileSize(works)
    file_count = 0
    file_size = 0
    works.each do |work|
      file_count += work.attachments.count
      work.attachments.each do |attach|
        file_size += attach.filesize
      end
    end

    if file_size > MAX_DOWN_SIZE
      status = -2
    elsif file_count > 0
      status = 0
    else
      status = -1
    end
    status
  end

  def zip_homework_common homework_common, student_works
    bid_homework_path = []
    digests = []
    student_works.each do |work|
      unless work.attachments.empty?
        out_file = zip_student_work_by_user(work, homework_common)

        bid_homework_path << out_file.file_path
        digests << out_file.file_digest
      end
    end

    out_file_name = "作品附件_#{homework_common.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.zip"
    out_file_name.gsub!(" ", "-")
    out_file_name.gsub!("/", "_")
    out_file = find_or_pack(homework_common, homework_common.user_id, digests.sort){
      zipping(out_file_name, bid_homework_path, OUTPUT_FOLDER)
    }

    [{files:[out_file.file_path], count: 1, index: 1,
      real_file: out_file.file_path,
      file: File.basename(out_file.file_path),
      base64file: encode64(File.basename(out_file.file_path)),
      size:(out_file.pack_size / 1024.0 / 1024.0).round(2)
     }]
  end

  def zip_student_work_by_user(work, object)
    homeworks_attach_path = []
    not_exist_file = []
    filename = []
    # 需要将所有homework.attachments遍历加入zip
    digests = []
    work.attachments.each do |attach|
      if File.exist?(attach.diskfile)
        homeworks_attach_path << attach.diskfile
        digests << attach.digest
        filename << attach.filename
      else
        not_exist_file << attach.filename
        digests << 'not_exist_file'
        filename << attach.filename
      end
    end

    #单个文件的话,不需要压缩,只改名
    if homeworks_attach_path.size == 1
      out_file = find_or_pack(object, work.user_id, digests.sort){
        des_path = "#{OUTPUT_FOLDER}/#{make_zip_name(work, filename.first)}_#{File.basename(homeworks_attach_path.first)}"
        FileUtils.cp homeworks_attach_path.first, des_path
        des_path
      }
    else
      out_file = find_or_pack(object, work.user_id, digests.sort){
        zipping("#{make_zip_name(work)}.zip",
                homeworks_attach_path, OUTPUT_FOLDER, true, not_exist_file)
      }
    end
    out_file

  end

  def find_or_pack(homework, user_id, digests)
    raise "please given a pack block" unless block_given?

    out_file = ZipPack.packed?(homework, user_id, digests.sort)

    unless out_file && out_file.file_valid?
      file = yield

      ZipPack.where(container_id: homework.id, container_type: homework.class.to_s, user_id: user_id).delete_all

      out_file = ZipPack.create(container_id: homework.id,
                                container_type: homework.class.to_s,
                                user_id: user_id,
                                file_digest: Educoder::Utils.digest(file),
                                file_path: file,
                                pack_size: File.size(file),
                                file_digests: digests.join(',')
      )
    else
      out_file.pack_times = out_file.pack_times + 1
      out_file.save
    end

    out_file
  end

  def make_zip_name(work, file_name="")
    Rails.logger.info("######################file_name: #{file_name}")
    # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_")
    course = work.is_a?(StudentWork) ? work&.homework_common&.course : work&.graduation_task&.course
    "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
  end

  def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[])
    rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip"
    # 文件名过长

    if rename_zipfile.size > MAX_PATH
      rename_zipfile = rename_zipfile[0,rename_zipfile.size-4][0,MAX_PATH-4] + rename_zipfile[-4,4]
    end

    zipfile_name = "#{output_path}/#{rename_zipfile}"

    # 同名文件重命名时用
    index = 1
    Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name))
    Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
      files_paths.each do |filename|
        rename_file = File.basename(filename)
        rename_file = filename_to_real( File.basename(filename)) if is_attachment

        begin
          zipfile.add(rename_file, filename)
        rescue Exception => e
          rename_file = rename_same_file(rename_file, index)
          index += 1
          zipfile.add(rename_file, filename)

          # zipfile.get_output_stream('FILE_NOTICE.txt'){|os| os.write "该作品中有重复命名文件，请通过文件名学号和姓名信息进入该作业详细界面手动下载"}
          next
        end
      end
      unless not_exist_file.empty?
        zipfile.get_output_stream('FILE_LOST.txt'){|os| os.write "以下文件无法成功下载，请联系相关人员重新上传：" +
                                                                     not_exist_file.join(',').to_s}
      end
    end
    zipfile_name
  end

  def filename_to_real(name)
    attach = Attachment.find_by_disk_filename(name)
    attach.filename
  end

  def format_sheet_name name
    name = name.gsub(":", "-").gsub("/", "_")
  end

  def rename_same_file(name, index)
    basename = File.basename(name, ".*")
    new_basename = basename + "_" + index.to_s
    extname = File.extname(name)
    new_basename + extname
  end
end
