class Admission::Applicants::ProcessingService < ApplicationService
  def initialize(id)
    @applicant_id = id
    initialize_student if applicant.student.nil?
    update_student
    Admission::Families::ProcessingService.call(applicant.family, school_year.id)
    applicant.update(review: false)
  end

  private
    def applicant
      @applicant ||= Admission::Applicant.find_by(id: @applicant_id)
    end

    def student
      @student ||= applicant.student
    end

    def school_year
      @school_year ||= applicant.school_year
    end

    def initialize_student
      applicant.build_student(family: applicant.family)
    end

    def update_student
      current_school_year_id = applicant.school.school_years.current.id

      if school_year.id == current_school_year_id || !applicant.returning
        student.grade = applicant.grade
      end

      applicant.sync_changes(false)
      update_student_additional_values
      update_student_medical if applicant.applicant_medical
    end

    def update_student_medical
      student_medical = student.find_or_build_student_medical
      health_attributes = Admission::ApplicantMedical::HEALTH_ISSUE_ATTRIBUTES
      health_attributes.each do |attribute|
        value = applicant.applicant_medical[attribute]
        student_medical[attribute] = value.nil? ? '' : value
      end
    end

    def update_student_additional_values
      student_values = student.student_additional_values.index_by(&:student_additional_field_id)
      applicant.additional_values.map do |record|
        additional_field = record.student_additional_field
        student_value = student_values[additional_field.id] ||
          student.student_additional_values.build(student_additional_field: additional_field)

        if additional_field.date?
          student_value.value_date = record.value
        else
          student_value.value = record.value
        end

        student_value
      end
    end
end
