# encoding: utf-8
class CollegesController < ApplicationController

  before_filter :find_department, :only => [:statistics, :course_statistics, :student_shixun, :engineering_capability, :student_eval]
  before_filter :manager_auth, :except => [:home, :get_home_data]

  include ApplicationHelper

  # GET /colleges/id/home

  def home
    render "common/index", :layout => false
  end

  # home action的数据
  # GET /colleges/id/get_home_data
  def get_home_data
    banners = []
    school = School.where(:identifier => params[:id]).first
    school.school_images.where(:status => 1).reorder("position asc").each do |image|
      banners << {link: image.link, image_path: url_to_avatar(image)}
    end
    attach = school.attachments.first
    render :json => {logo_link: url_to_avatar(school),
                     video: "/attachments/download/" + "#{attach.id}" + "/" + "#{attach.filename}",
                     video_name: school.video_name,
                     video_desc: school.video_desc,
                     course_link: school.course_link,
                     course_name: school.course_name,
                     banners: banners}
  end

  def verification_school_identifier
    schools = School.where(identifier: params[:identifier])
    schools = schools.where('id != ?', params[:school_id]) if params[:school_id].present?
    render :json => { status: schools.exists? ? 1 : 0 }
  end

  def online_school
    @school = School.find params[:id]
    @school.update_attribute(:is_online, params[:status].to_i)
  end

  def statistics
    logger.info("#########################{params}")
    @teachers_count = User.find_by_sql("SELECT COUNT(users.`id`) AS teacher_count FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
                                        user_extensions.`school_id` = #{@school.id} AND user_extensions.`identity` = 0").first.try(:teacher_count)
    @students_count = User.find_by_sql("SELECT COUNT(users.`id`) AS student_count FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
                                        user_extensions.`school_id` = #{@school.id} AND user_extensions.`identity` = 1").first.try(:student_count)
    # Redo:这样做内存会卡死的
    # user_ids = User.find_by_sql("SELECT users.id FROM users LEFT JOIN user_extensions ON users.id=user_extensions.user_id WHERE user_extensions.`school_id` = #{@school.id}").map(&:id)
    # Redo:是否直接使用count会更好
    all_course_ids = Course.where("id != 1309 and is_delete = 0 and school_id = #{@school.id}")
    @courses_count = all_course_ids.size

    # Redo:对于量比较大的尽量不使用笛卡尔积
    # @shixuns_count = Shixun.where(:status => [2, 3], :user_id => user_ids).size
    @shixuns_count = Shixun.find_by_sql("select count(s.id) as shixun_count from users u right join shixuns s on u.id=s.user_id and s.status in (2, 3) inner join user_extensions ue on
                                         u.id=ue.user_id and ue.school_id=#{@school.id}").first.try(:shixun_count)
    # @shixun_time_sum = (Game.where(:user_id => user_ids).pluck(:cost_time).sum / (24*60*60.0)).ceil
    @shixun_time_sum = (Game.find_by_sql("select sum(g.cost_time) cost_time from users u RIGHT join games g on u.id=g.user_id inner join user_extensions ue on
                                          u.id=ue.user_id and ue.school_id=#{@school.id}").first.try(:cost_time).to_i / (24 * 60 * 60.0)).ceil

    # select count(sw.id) from users u left join student_works sw on u.id=sw.user_id and sw.myshixun_id is not null and sw.work_status !=0 inner join user_extensions ue on u.id=ue.user_id and ue.school_id=117 ;
    # @shixun_report_count = StudentWork.where("work_status != 0 and user_id in (#{user_ids.join(',').strip == "" ? -1 : user_ids.join(',')}) and myshixun_id is not null").count
    @shixun_report_count = StudentWork.find_by_sql("SELECT count(*) as sw_count FROM `student_works` where user_id in (SELECT users.id FROM users RIGHT JOIN user_extensions ON users.id=user_extensions.user_id WHERE
                                                    user_extensions.`school_id`=#{@school.id}) and work_status between 1 and 2 and myshixun_id !=0").first.try(:sw_count)

    @teachers = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, IFNULL((SELECT count(shixuns.id) FROM shixuns where shixuns.user_id =users.id group by shixuns.user_id), 0) AS publish_shixun_count,
                                (SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.role in (1,2,3) and c.school_id = #{@school.id} AND m.user_id=users.id AND c.is_delete = 0) as course_count
                                FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{@school.id} ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
    # ).order("publish_shixun_count desc, experience desc").limit(10)
    @teachers =
        @teachers.map do |teacher|
          course_ids = Course.find_by_sql("SELECT c.id FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.role in (1,2,3) AND m.user_id=#{teacher.id} AND c.is_delete = 0 and c.school_id = #{@school.id}")
          course_count = course_ids.size
          homeworks = HomeworkCommon.where(:homework_type => 4, :course_id => course_ids.map(&:id))
          un_shixun_work_count = homeworks.where("publish_time > '#{Time.now}' or publish_time is null").count
          shixun_work_count = homeworks.size - un_shixun_work_count
          student_count = StudentsForCourse.where(:course_id => course_ids.map(&:id)).count
          myshixun_ids = StudentWork.select("myshixun_id").where("homework_common_id in (#{homeworks.map(&:id).join(',').strip == "" ? -1 : homeworks.map(&:id).join(',')}) and myshixun_id is not null")
          complete_myshixun = Myshixun.select("id").where(:status => 1, :id => myshixun_ids.map(&:myshixun_id)).size
          all_myshixun = Myshixun.select("id").where(:id => myshixun_ids.map(&:myshixun_id)).size
          complete_rate = all_myshixun == 0 ? 0 : ((complete_myshixun * 100) / all_myshixun).try(:round, 2).to_f
          real_name = teacher.show_real_name
          teacher = teacher.attributes.dup.merge({
                                                     real_name: real_name,
                                                     course_count: course_count,
                                                     shixun_work_count: shixun_work_count,
                                                     un_shixun_work_count: un_shixun_work_count,
                                                     student_count: student_count,
                                                     complete_rate: complete_rate
                                                 }).to_json
          JSON.parse(teacher)
        end

    shixun_ids = HomeworkCommonsShixuns.find_by_sql("SELECT hcs.shixun_id FROM homework_commons_shixuns hcs, homework_commons hc
                 WHERE hc.course_id in (#{all_course_ids.map(&:id).join(',').strip == "" ? -1 : all_course_ids.map(&:id).join(',')})
                 AND hcs.homework_common_id = hc.id").map(&:shixun_id)
    shixun_tags = TagRepertoire.find_by_sql("SELECT tr.`name`, COUNT(str.shixun_id) as shixun_count FROM tag_repertoires tr,
                                             shixun_tag_repertoires str WHERE tr.id = str.tag_repertoire_id AND str.shixun_id
                                             IN (#{shixun_ids.join(',').strip == "" ? -1 : shixun_ids.join(',')}) GROUP BY tr.id
                                             order by shixun_count desc")
    all_shixun_count = shixun_tags.map(&:shixun_count).sum
    other_count = all_shixun_count.to_i - shixun_tags[0..8].map(&:shixun_count).sum.to_i
    @shixun_tags_name = []
    @shixun_tags_data = []
    shixun_tags[0..8].each do |tag|
      @shixun_tags_name << tag.name
      @shixun_tags_data << {value: tag.shixun_count, name: tag.name}
    end
    if shixun_tags.size > 9
      @shixun_tags_name << 'Others'
      @shixun_tags_data << {value: other_count, name: 'Others'}
    end

    respond_to do |format|
      format.html {render :layout => "base_edu"}
    end
  end

  # 在线课堂
  def course_statistics
    @courses = Course.find_by_sql("SELECT c.id, (select concat(lastname,firstname) from users u where u.id=c.tea_id) as username,
               (select count(sfc.id) from students_for_courses sfc where c.id=sfc.course_id group by c.id) as student_count,
               (select count(hc.id) from homework_commons hc where c.id=hc.course_id and hc.homework_type=4 group by c.id) as hcm_count,
               (select count(hc.id) from homework_commons hc where c.id=hc.course_id and hc.homework_type in (1,3) group by c.id) as hcm_nonshixun_count,
               (select count(e.id) from exercises e where c.id=e.course_id group by c.id) as exercises_count,
               (select count(p.id) from polls p where c.id=p.course_id group by c.id) as polls_count,
               (select count(a.id) from attachments a where c.id=a.container_id and a.container_type='Course' group by c.id) as attachments_count,
               (select count(m.id) from messages m inner join boards b on  b.id=m.board_id and b.parent_id=0 where b.course_id=c.id group by c.id) as messages_count,
               c.tea_id, c.name, c.is_end,
               (SELECT MAX(created_at) FROM `course_activities` ca WHERE ca.course_id = c.id) AS update_time
               FROM `courses` c WHERE c.school_id = #{@school.id} and c.is_delete = 0")

    @courses.each do |course|
      course[:evaluating_count] = Output.find_by_sql("select sum(g.evaluate_count) as evaluating_count from games g inner join
                                  (select myshixun_id from student_works sw inner join homework_commons hc on sw.homework_common_id=hc.id and
                                  sw.myshixun_id !=0 and hc.course_id=#{course.id} and homework_type=4) aa on g.myshixun_id=aa.myshixun_id").first.try(:evaluating_count).to_i
      course[:task_count] = course.hcm_count.to_i + course.attachments_count.to_i + course.messages_count.to_i + course.hcm_nonshixun_count.to_i + course.exercises_count.to_i + course.polls_count.to_i
    end
    @courses = @courses.sort{|x,y| [y[:evaluating_count], y[:task_count]] <=> [x[:evaluating_count], x[:task_count]] }
    @courses = @courses.sort_by { |course| course.is_end ? 1 : 0 }

    # SELECT c.id, (select concat(firstname,lastname) from users u where u.id=c.tea_id) as username,
    #                                                                                      (select count(sfc.id) from students_for_courses sfc where c.id=sfc.course_id group by c.id) as student_count,
    #                                                                                                                                                                                     (select count(hc.id) from homework_commons hc where c.id=hc.course_id and hc.homework_type=4 group by c.id) as hcm_count,
    #                                                                                                                                                                                                                                                                                                    c.tea_id, c.name, c.is_end,
    #                                                                                                                                                                                                                                                                                                    (SELECT MAX(created_at) FROM `course_activities` ca WHERE ca.course_id = c.id) AS update_time
    # FROM `courses` c WHERE (c.school_id = 117 and c.is_delete = 0) ORDER BY update_time desc LIMIT 8 OFFSET 0

    # @courses = Course.where("courses.school_id = #{@department.school_id} and courses.is_delete = 0").select("courses.id, courses.tea_id, courses.name, courses.is_end,
    #   (SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS update_time").order("update_time desc")
    @courses = paginateHelper @courses, 8
    # @courses = @courses.includes(:student, :boards, :exercises, :polls, :attachments, :homework_commons, :teacher => [:user_extensions])
  end

  # 学生实训
  def student_shixun
    user_ids = User.find_by_sql("SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@school.id}").map(&:id)
    @students = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, users.grade,
                users.experience, ue.student_id, (SELECT COUNT(myshixuns.id) FROM `myshixuns` WHERE myshixuns.user_id
                = users.id AND myshixuns.status = 1 GROUP BY users.id) AS myshixun_count FROM users join user_extensions ue on
                users.id = ue.user_id where ue.school_id = #{@school.id} AND ue.identity = 1 AND `users`.`type` IN ('User', 'AnonymousUser') ORDER BY experience DESC, myshixun_count DESC LIMIT 10")

    ## outputs基数过大,用inner join有奇效
    @shixun_tags = TagRepertoire.find_by_sql(%Q{
      select name,  COUNT(outputs.id) AS test_count from outputs inner join (
        SELECT tr.id as trid, tr.`name` as name,  games.id as id
        FROM tag_repertoires tr, shixun_tag_repertoires str,  games, myshixuns
        WHERE tr.id = str.tag_repertoire_id
          AND str.shixun_id = myshixuns.`shixun_id`
          AND myshixuns.id = games.`myshixun_id`
          AND myshixuns.`user_id` IN (
            SELECT users.id FROM users, user_extensions WHERE users.id=user_extensions.user_id AND user_extensions.`school_id` = #{@school.id}
          )
        ) a on a.id = outputs.game_id and outputs.`test_set_position` = 1 group by trid
        ORDER BY test_count DESC
        LIMIT 10
    })

  end

  # 工程能力
  def engineering_capability

  end

  # 学生测评
  # day:日  week:周  mon:月  year:年
  def student_eval
    # game_ids = Game.find_by_sql("SELECT games.id FROM games, users, user_extensions ue WHERE games.`user_id` = users.`id` AND users.id = ue.`user_id` AND ue.`school_id` = #{@department.school_id}").map(&:id)
    # game_ids = game_ids.join(',').strip == "" ? -1 : game_ids.join(',')
    @index = params[:index] || "day"
    end_day = Time.now - 1.day
    @time_data = []
    @eval_data = []
    case @index
    when "day"
      same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(end_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
      last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(end_day - 1.day).beginning_of_day}' AND outputs.created_at < '#{(end_day - 1.day).end_of_day}'").first.try(:count).to_i
      @time_range = "#{end_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
      @time_data = ["2:00", "4:00", "6:00", "8:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00", "24:00"]
      for i in 0..11
        @eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{end_day.beginning_of_day + (i * 2).hour}' AND outputs.created_at < '#{end_day.beginning_of_day + ((i + 1) * 2).hour}'").first.try(:count).to_i
      end
    when "week"
      start_day = end_day - 6.days
      same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
      last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 7.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 7.days).end_of_day}'").first.try(:count).to_i
      @time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"

      for i in 0..6
        @time_data << (start_day + i.days).strftime("%m.%d")
        @eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + i.days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (i + 1).days).end_of_day}'").first.try(:count).to_i
      end
    when "mon"
      start_day = end_day - 30.days
      same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
      last_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 30.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 30.days).end_of_day}'").first.try(:count).to_i
      @time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
      for i in 0..9
        @time_data << (start_day + (3 * i).days).strftime("%m.%d")
        @eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + (3 * i).days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (3 * (i + 1)).days).end_of_day}'").first.try(:count).to_i
      end
    when "year"
      start_day = end_day - 365.days
      same_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                    ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day - 365.days).beginning_of_day}' AND outputs.created_at < '#{(end_day - 365.days).end_of_day}'").first.try(:count).to_i
      last_count = same_count
      @time_range = "#{start_day.strftime("%Y-%m-%d")}~#{end_day.strftime("%Y-%m-%d")}"
      for i in 0..11
        @time_data << (start_day + i.month).strftime("%m.%d")
        @eval_data << Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{(start_day + i.days).beginning_of_day}' AND outputs.created_at < '#{(start_day + (i + 1).days).end_of_day}'").first.try(:count).to_i
      end
    end
    @new_count = @eval_data.sum
    @same_rate = (@new_count == 0 || same_count == 0) ? 0 : (@new_count * 1.0 / same_count - 1).to_f
    @last_rate = (@new_count == 0 || last_count == 0) ? 0 : (@new_count * 1.0 / last_count - 1).to_f

    @total_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                   ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 ").first.try(:count).to_i
    @trend_count = Output.find_by_sql("select count(outputs.id) as count from outputs RIGHT JOIN (SELECT games.id FROM games RIGHT JOIN user_extensions ue ON games.`user_id` = ue.`user_id` AND ue.`school_id`=#{@school.id}) b
                   ON outputs.`game_id` = b.id WHERE outputs.test_set_position = 1 AND outputs.created_at > '#{Time.now - 7.days}'").first.try(:count).to_i
  end

  private

  def manager_auth
    # unless (User.current.admin? || DepartmentMember.where(:user_id => User.current.id, :department_id => @department.id).first.present?)
    unless (User.current.admin? || User.current.business? ||
        (@department.present? && DepartmentMember.where(:user_id => User.current.id, :department_id => @department.id).first.present?) ||
        (User.current.user_extensions.try(:school_id) == @school.id && User.current.user_extensions.try(:identity) == 0) ||
        (@school.try(:customer_id) && User.current.try(:partner).try(:customer_ids) &&  User.current.try(:partner).try(:customer_ids).include?(@school.try(:customer_id))))
      render_403
    end
  end

  def find_department
    @department = Department.find_by_identifier(params[:id])
    if @department.present?
      @school = @department.school
    else
      @school = School.find_by_id(params[:id])
    end
  rescue ActiveRecord::RecordNotFound
    render_404
  end
end