class Admins::UserSchoolsStatisticQuery < ApplicationQuery
  include CustomSortable

  attr_reader :params

  sort_columns :cnt,
               default_by: :cnt, default_direction: :desc

  def initialize(params)
    @params = params
  end

  def call
    schools = School
    if params[:province].present?
      schools = schools.where("province like ?", "%#{params[:province]}%")
    end

    if params[:school_id].present?
      schools = schools.where(id: params[:school_id])
    end

    total = schools.count
    # 根据排序字段进行查询
    schools = query_by_sort_column(schools.group(:id), params[:sort_by])
    #schools = custom_sort(schools, params[:sort_by], params[:sort_direction])
    schools = schools.limit(page_size).offset(offset).to_a
    # 查询并组装其它数据
    schools = package_other_data(schools)
    [total, schools]

  end

  private

  def package_other_data(schools)
    ids = schools.map(&:id)
    user_e = UserExtension.where(school_id: schools.map(&:id))
    #study_myshixun   = Myshixun.joins("join user_extensions ue on ue.user_id = myshixuns.user_id").where(ue: {school_id: ids})
    #finish_myshixun  = Myshixun.joins("join user_extensions ue on ue.user_id = myshixuns.user_id")
    #                       .where(ue: {school_id: ids}, myshixuns: {status: 1})
    study_challenge  = Game.joins("join user_extensions ue on ue.user_id = games.user_id")
                           .where(ue: {school_id: ids},).where( games:{status: [0, 1, 2]})
    finish_challenge = Game.joins("join user_extensions ue on ue.user_id = games.user_id")
                           .where(ue: {school_id: ids}).where(games: {status: 2})
    reg_teacher = user_e.where(identity: 'teacher')
    reg_student =  user_e.where.not(identity: 'teacher')

    if time_range.present?
      #study_myshixun   = study_myshixun.where(updated_at: time_range)
      #finish_myshixun  = finish_myshixun.where(updated_at: time_range)
      study_challenge  = study_challenge.where(updated_at: time_range)
      finish_challenge = finish_challenge.where(updated_at: time_range)
      reg_teacher = reg_teacher.where(created_at: time_range)
      reg_student = reg_student.where(created_at: time_range)
      user_e = user_e.joins(:user).where(users: {last_login_on: time_range})
    end

    #study_myshixun_map   = study_myshixun.reorder(nil).group(:school_id).count
    #finish_myshixun_map  = finish_myshixun.reorder(nil).group(:school_id).count
    study_challenge_map  = study_challenge.reorder(nil).group(:school_id).count
    finish_challenge_map = finish_challenge.reorder(nil).group(:school_id).count
    evaluate_count_map   = study_challenge.reorder(nil).group(:school_id).sum(:evaluate_count)
    reg_teacher_map   = reg_teacher.reorder(nil).group(:school_id).count
    reg_student_map   = reg_student.reorder(nil).group(:school_id).count
    user_e_map = user_e.reorder(nil).group(:school_id).count

    schools.each do |school|
      school._extra_data = {
          #study_shixun_count: study_myshixun_map.fetch(schools.id, 0),
          #finish_shixun_count: finish_myshixun_map.fetch(schools.id, 0),
          study_challenge_count: study_challenge_map.fetch(school.id, 0),
          finish_challenge_count: finish_challenge_map.fetch(school.id, 0),
          evaluate_count: evaluate_count_map.fetch(school.id, 0),
          reg_teacher_count: reg_teacher_map.fetch(school.id, 0),
          reg_student_count: reg_student_map.fetch(school.id, 0),
          user_active_count: user_e_map.fetch(school.id, 0)
      }
    end
    schools
  end

  def query_by_sort_column(schools, sort_by_column)
    #base_query_column = 'schools.*'

    case sort_by_column.to_s
    when 'cnt' then
      schools.left_joins(:user_extensions).select("schools.*, count(*) cnt").order("cnt desc")
    else
      schools
    end
  end

  def time_range
    @_time_range ||= begin
      case params[:date]
      when 'dayly'     then 1.days.ago..Time.now
      when 'weekly'    then 1.weeks.ago..Time.now
      when 'monthly'   then 1.months.ago..Time.now
      when 'quarterly' then 3.months.ago..Time.now
      when 'yearly'    then 1.years.ago..Time.now
      else ''
      end
    end
  end

  def page_size
    params[:per_page].to_i.zero? ? 20 : params[:per_page].to_i
  end

  def offset
    (params[:page].to_i.zero? ? 0 : params[:page].to_i - 1) * page_size
  end
end