class Csv::Admissions::Families::AdditionalFieldsService < Csv::ApplicationService
  def initialize(school, options)
    @school = school
    @school_year_id = options['school_year_id']
  end

  def call
    CSV.generate do |csv|
      csv << headers
      families.each do |family|
        csv << content(family)
      end
    end
  end

  private
    def school_year
      @school.school_years.find(@school_year_id)
    end

    def families
      @families ||= @school.families
        .joins(admission_applicants: :application)
        .where(admission_applications: { school_year: school_year })
        .includes(:family_additional_values)
        .ordered
        .distinct
        .to_a
    end

    def family_tags
      @family_tags ||= school_year.admission_families.includes(:tags).index_by(&:family_id)
    end

    def fields
      @fields ||= @school.family_additional_fields
        .includes(:family_additional_choices)
        .joins(:admission_family_additional_fields)
        .where(admission_family_additional_fields: { display: true })
        .index_by(&:id)
    end

    def headers
      data = [
        'Family Code',
        'Family Name',
        'Family Tags'
      ]
      data + fields.values.map(&:name)
    end

    def content(family)
      data = [
        family.code,
        family.name,
        family_tags[family.id]&.tags&.map(&:name)&.join(', ')
      ]

      values = family.family_additional_values.index_by(&:family_additional_field_id)
      data + fields.map do |id, field|
        next unless (value = values[id])

        if field.multi_choice?
          field.family_additional_choices.find { |c| c.value == value.value }&.label
        else
          value.value
        end
      end
    end
end
