class Admin::Admissions::StatisticsController < Admin::Admissions::Controller
  def applicants_by_state
    entrance = entrance_applicants.group(:state).count
    enrollment = enrollment_applicants.group(:state).count
    data = approved_states.map do |state|
      {
        state: state,
        entrance: entrance[state] || 0,
        enrollment: enrollment[state] || 0
      }
    end
    data << {
      state: 'Total',
      entrance: entrance.values.reduce(0, :+),
      enrollment: enrollment.values.reduce(0, :+)
    }
    render_success :ok, json: data
  end

  def applicants_by_grade
    entrance = entrance_applicants.where.not(state: :closed).group(:grade).count
    enrollment = enrollment_applicants.where.not(state: :closed).group(:grade).count
    data = grade_levels.map do |grade, label|
      {
        grade: grade,
        grade_label: label,
        entrance: entrance[grade] || 0,
        enrollment: enrollment[grade] || 0
      }
    end
    data << {
      grade: nil,
      grade_label: 'Total',
      entrance: entrance.values.reduce(0, :+),
      enrollment: enrollment.values.reduce(0, :+)
    }
    render_success :ok, json: data
  end

  def applicants_by_entrance
    entrance = entrance_applicants.ordered_by_system_status.group(:state, :status_id).count
    totals = { title: 'Totals', number: 0 }
    data = {}

    entrance.each do |key, count|
      state, status_id = key
      title = if key.last.nil?
        "#{key.first.humanize}: No Status"
      else
        statuses.find_by(id: key.last).decorate.title
      end

      data[key] = {
        state: state,
        status_id: status_id,
        title: title,
        number: count
      }

      totals[:number] += count
    end

    data[:total] = totals
    render_success :ok, json: data.values
  end

  def applicants_by_enrollment
    applicants_by_status = enrollment_applicants
      .ordered_by_system_status
      .group_by { |a| [a.state, a.status_id] }

    totals = { title: 'Totals', new: 0, returning: 0, all: 0 }
    data = {}

    applicants_by_status.each do |key, applicants|
      state, status_id = key
      title = if status_id.nil?
        "#{state.humanize}: No Status"
      else
        statuses.find_by(id: status_id).decorate.title
      end

      data[key] = { state: state, status_id: status_id, title: title, new: 0, returning: 0, all: 0 }
      applicants.each do |applicant|
        if applicant.returning
          data[key][:returning] += 1
          totals[:returning] += 1
        else
          data[key][:new] += 1
          totals[:new] += 1
        end

        data[key][:all] += 1
        totals[:all] += 1
      end
    end

    data[:totals] = totals
    render_success :ok, json: data.values
  end

  def pre_applicants_count
    query = applicants.submitted.where(review: true).includes(:application).decorate
    count = query.size
    entrance = !query.all?(&:enrollment)
    render_success :ok, json: { count: count, entrance: entrance }
  end

  def report
    Reporting::Admissions::StatisticJob.perform_async(
      current_school.id,
      current_user.id,
      report: params[:report],
      school_year_id: params[:school_year_id]
    )
  end

  private
    def permissions
      ['read', 'write', 'manage']
    end

    def school_year
      @school_year ||= current_school.school_years.find_by(id: params[:school_year_id])
    end

    def applicants
      school_year.admission_applicants
    end

    def entrance_applicants
      applicants.by_enrollment(false).by_review(false)
    end

    def enrollment_applicants
      applicants.by_enrollment(true).by_review(false)
    end

    def statuses
      current_school.admission_statuses
    end

    def approved_states
      Admission::Applicant.states.keys - ['unsubmitted']
    end
end
