class Admins::StatisticSchoolDataGrowService < ApplicationService
  include CustomSortable

  PAGE_SIZE = 20

  attr_reader :params

  sort_columns :teacher_increase_count, :student_increase_count,
               :course_increase_count, :shixun_increase_count, :uniq_active_user_count,
               :shixun_homework_count, :shixun_evaluate_count,
               default_by: :teacher_increase_count, default_direction: :desc

  def initialize(params)
    @params = params
  end

  def call
    reports = School.where(nil)

    reports = search_filter(reports)

    count = reports.count

    subquery = SchoolDailyActiveUser.select('COUNT(distinct(user_id))').joins(:school_daily_report)
                 .where(date_condition_sql).where("school_id is not null and school_id = schools.id").to_sql
    reports = reports.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id AND #{date_condition_sql}")
    reports = reports.select(
      'schools.id school_id, schools.name school_name,'\
      'SUM(teacher_increase_count) teacher_increase_count,'\
      'SUM(student_increase_count) student_increase_count,'\
      'SUM(course_increase_count) course_increase_count,'\
      'SUM(shixun_increase_count) shixun_increase_count,'\
      'SUM(shixun_homework_count) shixun_homework_count,'\
      'SUM(shixun_evaluate_count) shixun_evaluate_count,'\
      "(#{subquery}) uniq_active_user_count,"\
      'SUM(active_user_count) active_user_count').group('schools.id')

    reports = custom_sort(reports, params[:sort_by], params[:sort_direction])
    reports = reports.order('school_id asc').limit(PAGE_SIZE).offset(offset)

    [count, reports]
  end

  def grow_summary
    @_grow_summary ||= begin
      reports = School.joins("LEFT JOIN school_daily_reports sdr ON sdr.school_id = schools.id")
                  .where(date_condition_sql)

      subquery = SchoolDailyActiveUser.select('COUNT(distinct user_id)')
                   .joins('LEFT JOIN school_daily_reports sdr ON sdr.id = school_daily_active_users.school_daily_report_id')
                   .where(date_condition_sql).to_sql
      reports = search_filter(reports)
      reports.select(
        'SUM(teacher_increase_count) teacher_increase_count,'\
        'SUM(student_increase_count) student_increase_count,'\
        'SUM(course_increase_count) course_increase_count,'\
        'SUM(shixun_increase_count) shixun_increase_count,'\
        'SUM(shixun_homework_count) shixun_homework_count,'\
        'SUM(shixun_evaluate_count) shixun_evaluate_count,'\
        "(#{subquery}) uniq_active_user_count,"\
        'SUM(active_user_count) active_user_count'
      ).first
    end
  end

  private

  def search_filter(relations)
    keyword = params[:keyword].try(:to_s).try(:strip)
    if keyword.present?
      relations = relations.where("schools.name LIKE :keyword OR schools.id LIKE :keyword", keyword: "%#{keyword}%")
    end

    relations
  end

  def date_condition_sql
    date = query_date
    if date.is_a?(Range)
      "date BETWEEN '#{date.min.strftime('%Y-%m-%d')}' AND '#{date.max.strftime('%Y-%m-%d')}'"
    else
      "date = '#{date.strftime('%Y-%m-%d')}'"
    end
  end

  def query_date
    if params[:grow_begin_date].present?
      begin_time = Time.zone.parse(params[:grow_begin_date])
      end_date = if params[:grow_end_date].present?
                   Time.zone.parse(params[:grow_end_date])
                 end

      end_date.blank? || end_date == begin_time ? begin_time : begin_time..end_date
    else
      yesterday
    end
  end

  def yesterday
    # 每日凌晨5点为节点, 25日凌晨4点、3点、2点等等,未到更新数据时间点,看到的数据是:23日-24日的统计数据
    (Time.zone.now - 5.hours).beginning_of_day - 1.days
  end

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