class Pdf::Admissions::StatusByGradeService < Pdf::NewApplicationService
  def initialize(school_year)
    @school_year = school_year
  end

  private
    def header
      content = ActionController::Base.new.render_to_string(
        partial: 'pdf/headers/school_info.html.haml',
        locals: {
          school: school,
          side_content_partial: 'pdf/admissions/status_header.html.haml',
          side_content: { date: Date.current }
        }
      )
      { content: content, spacing: 25 }
    end

    def body
      ActionController::Base.new.render_to_string(
        partial: 'pdf/admissions/status.html.haml',
        locals: {
          grades: grades,
          statuses: statuses_by_grade
        }
      )
    end

    def configuration
      {}.tap do |config|
        config[:encoding] = 'UTF-8'
        config[:margin] = { top: 40, bottom: 20 }
        config[:orientation] = 'Landscape'
      end
    end

    def statuses_by_grade
      data = {}
      states.each do |state|
        title = "#{state.humanize}: No Status"
        data[state] = { title: title, all: 0 }.merge(grades_total)
        statuses[state]&.each do |status|
          data[status.id] = { title: status.title, all: 0 }.merge(grades_total)
        end
      end
      data[:totals] = { title: 'Totals', all: 0 }.merge(grades_total)

      applicants_by_student.each_value do |applicants|
        applicant = if applicants.many?
          applicants.find { |a| a.application.enrollment.present? }
        else
          applicants.first
        end

        data[applicant.status_id || applicant.state][applicant.grade] += 1
        data[applicant.status_id || applicant.state][:all] += 1
        data[:totals][applicant.grade] += 1
        data[:totals][:all] += 1
      end

      data
    end

    def school
      @school ||= @school_year.school
    end

    def applicants_by_student
      @school_year.admission_applicants
        .includes(:application)
        .where.not(state: :unsubmitted).where.not(review: true)
        .group_by(&:student_id)
    end

    def statuses
      @school.admission_statuses.where(archived: false).ordered_by_name.decorate.group_by(&:state)
    end

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

    def grades
      @grades ||= school.grades
    end

    def grades_total
      {}.tap do |props|
        grades.each { |g| props[g.grade] = 0 }
      end
    end
end
