class EdFi::Indiana::V2026::StudentSchoolAssociationService <
  EdFi::Indiana::V2026::ApplicationService
  def call
    school_year_students.by_ids(@params[:id]).each do |student|
      if student.edfi_id?
        update(student)
      else
        create(student)
      end
    end
  end

  def index_by_student(id)
    records = rest_client_request(
      :get,
      url,
      nil,
      header_params: { params: { studentUniqueId: id } }
    )
    records ? JSON.parse(records).map { |r| record_props(r) } : []
  end

  def find_record(id)
    response = rest_client_request(:get, "#{url}/#{id}", nil)
    response ? JSON.parse(response) : {}
  end

  def delete
    RestClient.delete(url + "/#{@params[:id]}", headers)
    true
  rescue
    false
  end

  def endpoint
    'ed-fi/studentschoolassociations'
  end

  private
    def edfi_grades
      @edfi_grades ||= school_year.school.school_grades.map { |g| [g.grade, g.edfi_grade] }.to_h
    end

    def grade_descriptors
      @grade_descriptors ||= EdFi::Descriptor
        .by_grade_levels(school_year.school)
        .map { |g| [g.key, g.code] }
        .to_h
    end

    def exit_descriptors
      @exit_descriptors ||= EdFi::Descriptor
        .by_exit_withdrawl_descriptor(school_year.school)
        .map { |e| [e.key, e.code] }
        .to_h
    end

    def props(student)
      grade = grade_descriptors[edfi_grades[student.grade_id]]
      exit_type = exit_descriptors[student.exit_type]
      exit_descriptor = if exit_type
        "uri://doe.in.gov/ExitWithdrawTypeDescriptor##{exit_type}"
      else
        nil
      end
      obj = {
        schoolReference: {
          schoolId: state_id.number
        },
        schoolYearTypeReference: {
          schoolYear: school_year.academic_year
        },
        studentReference: {
          studentUniqueId: student.student.state_id
        },
        entryDate: student.entry_date,
        entryGradeLevelDescriptor: "uri://doe.in.gov/GradeLevelDescriptor##{grade}",
        exitWithdrawDate: student.exit_date,
        exitWithdrawTypeDescriptor: exit_descriptor,
        primarySchool: student.primary_school?
      }
      if student.grade.grade == 4
        reason = student.student.indiana_question_values.find_by(field_id: 18714)&.value
        if reason.present?
          obj[:entryGradeLevelReasonDescriptor] = "uri://doe.in.gov/EntryGradeLevelReasonDescriptor##{reason}"
        end
      end
      obj
    end

    def create(data)
      response = rest_client_request(:post, url, data, body: props(data).to_json)
      return unless response

      edfi_id = response.headers[:location].split('/').last
      data.update(edfi_id: edfi_id)
    end

    def update(data)
      path = "#{url}/#{data.edfi_id}"
      response = rest_client_request(:put, path, data, body: props(data).to_json)
      return unless response

      edfi_id = response.headers[:location].split('/').last
      data.update(edfi_id: edfi_id, skip_after_update: true)
    end

    def record_props(response)
      {
        id: response['id'],
        entryDate: response['entryDate'],
        withdrawDate: response['exitWithdrawDate'],
        lastModifiedDate: response['_lastModifiedDate'].split('T').first
      }
    end
end
