class Csv::EdFi::Indiana::StudentsCsv < Csv::ApplicationService
  def initialize(school_id)
    @school_id = school_id
  end

  def call
    CSV.generate do |csv|
      csv << headers
      school_year_students.each { |s| csv << props(s) }
    end
  end

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

    def grades
      @grades ||= school.grades_hash
    end

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

    def school_year_students
      school.current_year.school_year_students
        .preload(
          :ed_fi_choice,
          student: [
            :detail,
            :races,
            :language,
            :family,
            :indiana_settlement_number,
            :indiana_question_values
          ]
        )
        .joins(:student)
        .where.not(grade_id: grades_mapped_ungraded)
        .order(:grade_id)
        .order('Students.LastName ASC, Students.FirstName ASC')
        .decorate
    end

    def exit_descriptors
      @exit_descriptors ||= EdFi::Descriptor
        .by_exit_withdrawl_descriptor(school)
        .pluck(:key, :name)
        .to_h
    end

    def language_descriptors
      @language_descriptors ||= EdFi::Descriptor
        .by_language_descriptor(school)
        .pluck(:key, :name)
        .to_h
    end

    def choices
      @choices ||= StudentAdditionalChoice
        .where(field_id: 18714)
        .group_by(&:field_id)
    end

    def headers
      [
        'Grade Level',
        'Student Last Name',
        'Student First Name',
        'Date of Birth',
        'Entry Date',
        'Exit Date',
        'Exit withdrawl type',
        'Primary school',
        'Student state id',
        'Birth Country',
        'Initial US School Entry',
        'English Proficiency',
        'ELL Instrument',
        'Student County (from Family Mailing Address)',
        'Student State (from Family Mailing Address)',
        'Gender',
        'Ethnicity',
        'Race',
        'Language',
        'Language Use',
        'Choice',
        'Corp of Legal Settlement',
        '4th Grade Reason'
      ]
    end

    def english_proficiencies
      @english_proficiencies ||= EdFi::Descriptor.by_descriptor(school, 'limitedEnglishProficiency')
        .pluck(:key, :name)
        .to_h
    end

    def ell_instruments
      {
        other: 'Other Nonpublic School Assessment',
        wida_access: 'WIDA ACCESS for ELLs',
        w_apt: 'W-APT (WIDA ACCESS Placement Test)',
        not_available: 'N/A',
        not_assessed_without_cause: 'Not assessed as required without external cause',
        not_assessed_with_cause: 'Not assessed With Cause (due to uncontrollable circumstances)',
        wida_alternate: 'WIDA Alternate ACCESS (As determined by IEP Committee)',
        annual_las: 'Annual LAS Links Assessment',
        wida_screener: 'WIDA Screener (Grades 1-13)'
      }
    end

    def props(student)
      detail = student.student.detail&.decorate
      date = if detail&.init_school_entry_us
        (detail.init_school_entry_us.to_date + 1.day).strftime('%m/%d/%Y')
      else
        nil
      end
      language = if student.student.language&.language_id.nil?
        # Use English as a default
        language_descriptors[1]
      else
        language_descriptors[student.student.language&.language_id]
      end
      language_use = if student.student.language&.use.nil?
        'Home language'
      else
        student.student.language&.use
      end
      fourth_grade_reason = if student.grade.grade == 4
        value = student.student.indiana_question_values.find_by(field_id: 18714)
        option = choices[18714]&.find do |choice|
          choice.value == value&.value
        end
        option&.name
      end

      [
        grades[student.grade_id],
        student.last_name,
        student.first_name,
        student.student.date_of_birth&.strftime('%m/%d/%Y'),
        student.entry_date,
        student.exit_date,
        exit_descriptors[student.exit_type],
        student.primary_school?,
        student.state_id,
        detail&.birth_country_name,
        date,
        english_proficiencies[detail&.english_proficiency],
        ell_instruments[detail&.ell_instrument_used&.to_sym],
        student.student.decorate.county,
        student.student.decorate.state,
        student.student.decorate.gender_label,
        student.student.decorate.ethnic_label,
        student.student.races.map(&:name).join(' '),
        language,
        language_use,
        student.ed_fi_choice&.value || false,
        student.student.indiana_settlement_number&.number,
        fourth_grade_reason
      ]
    end
end
