class Csv::Nursing::StudentVaccinationService < Csv::ApplicationService
  def initialize(school, options)
    @school = school
    @options = options
  end

  def call
    CSV.generate do |csv|
      csv << headers
      students.each do |student|
        csv << content(student)
      end
    end
  end

  private
    def vaccines
      @vaccines ||= @school.nursing_vaccine_configs
        .includes(:vaccine)
        .ordered
        .decorate
        .to_a
    end

    def student_vaccines
      @student_vaccines ||= @school.nursing_vaccine_records
        .joins(:student)
        .to_a
    end

    def students
      @students ||= @school.students
        .where(id: @options['ids'])
        .includes(:student_medical)
        .ordered
        .to_a
    end

    def grades
      @grades ||= @school.grades_hash
    end

    def headers
      data = [
        'Student ID',
        'Student Name',
        'Student DOB',
        'Student Age',
        'Student Grade',
        'Overall Exemption'
      ]
      data + vaccines.map(&:name)
    end

    def content(student)
      data = [
        student.id,
        student.full_name(:reverse),
        student.date_of_birth,
        student.decorate.age,
        grades[student.grade]
      ]
      if student.student_medical&.exempt? && !student.student_medical.not_exempt?
        data.push(student.student_medical.exempt.capitalize)
      else
        data.push(nil)
      end

      vaccine_records = student.nursing_vaccine_records.index_by(&:vaccine_id)

      data + vaccines.map do |vaccine|
        student_vaccine = vaccine_records[vaccine.vaccine_id]

        if student_vaccine.nil? && student.grade >= vaccine.grade &&
            (student.student_medical.nil? || student.student_medical.not_exempt?)
          'Missing'
        elsif student_vaccine&.not_exempt?
          student_vaccine&.vaccine_date
        else
          student_vaccine&.exempt&.capitalize
        end
      end
    end
end
