class EdFi::Indiana::V2026::StudentProgramAssociationsService <
  EdFi::Indiana::V2026::ApplicationService
  def call
    query.each { |p| create_or_update(p, props(p)) }
  end

  def delete
    rest_client_request(:delete, "#{url}/#{@params[:id]}", @params[:program])
  end

  def endpoint
    'ed-fi/studentprogramassociations'
  end

  private
    def student_ids
      @student_ids ||= school_year_students.pluck(:student_id)
    end

    def programs
      EdFi::StateProgram
        .preload(:student)
        .where(student_id: student_ids, school_year: school_year)
        .where.not(program: :special_education)
    end

    def query
      programs.where(start_date: school_year_range)
        .or(programs.where(end_date: [school_year_range, nil]))
    end

    def exit_descriptors
      @exit_descriptors ||= descriptor_service(:reasonExitedDescriptors)
        .pluck('id', 'codeValue')
        .to_h
    end

    def program_descriptors
      @program_descriptors ||= descriptor_service(:programs).pluck('id', 'programName').to_h
    end

    def service_descriptors
      @service_descriptors ||= descriptor_service(:serviceDescriptors)
        .pluck('id', 'codeValue')
        .to_h
    end

    def exit_url(descriptor_id)
      return unless descriptor_id

      "uri://doe.in.gov/ReasonExitedDescriptor##{exit_descriptors[descriptor_id]}"
    end

    def props(program)
      program_title = program.program.titleize
      program_namespace = if ['foreign_exchange'].include?(program.program)
        "uri://ed-fi.org/ProgramTypeDescriptor##{program_title}"
      else
        "uri://doe.in.gov/ProgramTypeDescriptor##{program_title}"
      end
      service_namespace = if program.service_descriptor
        "uri://doe.in.gov/ServiceDescriptor##{service_descriptors[program.service_descriptor]}"
      end

      obj = {
        educationOrganizationReference: {
          educationOrganizationId: organization_id.number
        },
        programReference: {
          educationOrganizationId: '1088000000',
          programTypeDescriptor: program_namespace,
          programName: program_descriptors[program.program_descriptor]
        },
        studentReference: {
          studentUniqueId: program.student.state_number.number
        },
        beginDate: program.start_date.strftime('%Y/%m/%d'),
        endDate: program.end_date&.strftime('%Y/%m/%d'),
        reasonExitedDescriptor: exit_url(program.exit_descriptor)
      }

      if program.service_descriptor?
        if program.program == 'virtual_education'
          obj.merge(
            services: [
              {
                serviceDescriptor: service_namespace,
                serviceBeginDate: program.start_date.strftime('%Y/%m/%d'),
                serviceEndDate: program.end_date&.strftime('%Y/%m/%d'),
              }
            ]
          )
        else
          obj.merge(
            services: [
              {
                serviceDescriptor: service_namespace
              }
            ]
          )
        end
      else
        obj
      end
    end
end
