class EdFi::Indiana::V2026::SummerReleaseService <
  EdFi::Indiana::V2026::ApplicationService
  def initialize(school_year_id, id, action, exit_type=nil, summer_grad=false)
    @id = id
    @exit_type = exit_type
    @action = action
    @summer_grad = summer_grad
    super(school_year_id)
  end

  def call
    case @action
    when :show
      ed_fi_id = student.state_number&.number
      return unless ed_fi_id

      JSON.parse(
        rest_client_request(:get, url, nil, header_params: { params: query(ed_fi_id) })
      )
    when :post
      resp = rest_client_request(:post, url, student, body: props.to_json)
      return unless resp

      resp_edfi_id = resp.headers[:location].split('/').last
      tmp_endpoint = endpoint.to_s.split('/').last
      student.ed_fi_ids
        .create(number: resp_edfi_id, endpoint: tmp_endpoint, school_year: school_year)
      current_school_year_students.each do |record|
        next record.destroy if record.edfi_id.blank?

        record.destroy if rest_client_request(:delete, "#{url}/#{record.edfi_id}", student)
      end
      current_school_year_students.count
    end
  end

  def endpoint
    'ed-fi/studentschoolassociations'
  end

  private
    def student
      @student ||= school.students.find_by(id: @id)
    end

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

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

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

    def current_school_year_students
      student.school_year_students.where(school_year_id: school_year.id)
    end

    def previous_school_year
      school.school_years.find_by(academic_year: school_year.academic_year - 1)
    end

    # Fetch the most recent SchoolYearStudent grade in the previous year
    def previous_grade
      student.school_year_students
        .order(id: :desc)
        .find_by(school_year: previous_school_year)
        .grade_id
    end

    def release_date
      @release_date ||= "#{school_year.academic_year - 1}-07-04".to_date
    end

    def query(ed_fi_id)
      {
        studentUniqueId: ed_fi_id,
        schoolYear: school_year.academic_year.to_s,
        entryDate: release_date,
        exitWithdrawDate: release_date
      }
    end

    def props
      grade = if @summer_grad
        current_record = student.school_year_students.max_by { |s| s.entry_date }
        grade_descriptors[edfi_grades[current_record&.grade_id]]
      else
        grade_descriptors[edfi_grades[previous_grade + 1]]
      end
      exit_type = exit_descriptors[@exit_type]
      exit_descriptor = "uri://doe.in.gov/ExitWithdrawTypeDescriptor##{exit_type}"

      {
        schoolReference: {
          schoolId: state_id.number
        },
        schoolYearTypeReference: {
          schoolYear: school_year.academic_year
        },
        studentReference: {
          studentUniqueId: student.state_number&.number
        },
        entryDate: release_date,
        entryGradeLevelDescriptor: "uri://doe.in.gov/GradeLevelDescriptor##{grade}",
        exitWithdrawDate: release_date,
        exitWithdrawTypeDescriptor: exit_descriptor,
        primarySchool: true
      }
    end
end
