class Csv::EdFi::Indiana::CoursesService < Csv::ApplicationService
  include EdFi::IndianaHelper

  def initialize(school_id)
    @school_id = school_id
  end

  def call
    CSV.generate do |csv|
      csv << headers
      ed_fi_classes.each do |classroom|
        next if class_subject_ids.include?(classroom.id)

        csv << props(classroom)
      end
      class_subjects.each { |s| csv << props(s) }
    end
  end

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

    def school_config
      @school_config ||= school.school_config
    end

    def ed_fi_classes
      @ed_fi_classes ||= school.classrooms
        .preload(primary_teacher: :state_id)
        .joins(:school_state_classroom)
        .by_type(['preschool', 'period_long', 'day_long'])
    end

    def class_subjects
      @class_subjects ||= school.class_subjects
        .preload(classroom: { primary_teacher: :state_id })
        .joins(classroom: :school_state_classroom)
        .where("Classes.type = '1' OR Classes.type = '-1'")
    end

    def class_subject_ids
      @class_subject_ids ||= class_subjects.pluck(:class_id)
    end

    def position_descriptors
      @position_descriptors ||= descriptor_service(
        school.current_year.id,
        descriptor: :classroompositiondescriptors
      )
        .map { |d| [d['id'], d['shortDescription']] }
        .to_h
    end

    def headers
      [
        'Class ID',
        'Class Name',
        'Course #/SubjectCode',
        'Subject',
        'Class Type',
        'Credit Hours',
        'Position Type',
        'State ID',
        'Teacher'
      ]
    end

    def props(object)
      if object.is_a?(Classroom)
        classroom = object
        code = object.course_number
      else
        classroom = object.classroom
        code = object.code
      end
      [
        classroom.id,
        classroom.name,
        code.blank? ? code : "Course #{code}",
        object.is_a?(ClassSubject) && code ? object.name : nil,
        classroom.type.titleize,
        classroom.credit,
        position_descriptors[classroom.classroom_position_type_id],
        classroom.primary_teacher&.state_id&.number,
        classroom.primary_teacher&.full_name(:reverse)
      ]
    end
end
