class Csv::EdFi::Indiana::GraduateService < Csv::ApplicationService
  include EdFi::IndianaHelper

  def initialize(school_id)
    @school_id = school_id
  end

  def call
    CSV.generate do |csv|
      csv << headers
      students.each do |student|
        next unless valid_ed_fi_graduation_date?(student.graduation_date)

        csv << props(student)
      end
    end
  end

  private
    def school
      @school ||= School.find(@school_id)
    end

    def current_year
      @current_year ||= school.current_year
    end

    def students
      current_year.students
        .preload(:indiana_question_values)
        .joins(:school_year_students)
        .where('SchoolYearStudents.SYGrade >= 11')
        .where.not(SchoolYearStudents: { SYGrade: grades_mapped_ungraded }, graduated: false)
        .by_valid_graduation_date
        .distinct
        .decorate
    end

    def choices
      @choices ||= StudentAdditionalChoice
        .where(field_id: [3_527, 13_060, 13_061])
        .group_by(&:field_id)
    end

    def valid_ed_fi_graduation_date?(grad_date)
      (
        Date.new(current_year.academic_year - 1, 7, 1)..Date.new(current_year.academic_year, 6, 30)
      ).cover?(grad_date)
    end

    def grades_mapped_ungraded
      school.grades.where(edfi_grade: -4).pluck(:grade)
    end

    def headers
      [
        'First Name',
        'Last Name',
        'State ID',
        'Graduation Date',
        'Diploma Type',
        'Diploma',
        'Employability Skills',
        'Postsecondary Ready Competencies',
        'Local Pathways'
      ]
    end

    def props(student)
      values = student.indiana_question_values.index_by(&:field_id)
      diploma = choices[3_527]&.find do |choice|
        choice.value == values[3_527]&.value
      end
      employability = choices[13_060]&.find do |choice|
        choice.value == values[13_060]&.value
      end
      postsecondary = choices[13_061]&.find do |choice|
        choice.value == values[13_061]&.value
      end
      level_type = case diploma&.value
      when '07', '06' # certificate of completion or course completion
        'Certificate of completion'
      else
        'Regular diploma'
      end
      [
        student.first_name,
        student.last_name,
        student.state_id,
        student.graduation_date&.strftime("%m/%d/%Y"),
        level_type,
        diploma&.name,
        employability&.name,
        postsecondary&.name,
        postsecondary&.name&.include?('Local') ? values[13_062]&.value : nil
      ]
    end
end
