class Admission::Applicants::FamilyAdditionalFieldService < ApplicationService
  def initialize(applicant, application)
    @applicant = applicant
    @application = application
  end

  def props
    @props ||= additional_groups.map do |group|
      {
        id: group.id,
        name: group.name,
        sequence: group.sequence,
        description: group.description,
        fields: fields_by_group[group.id]&.map do |field|
          {}.tap do |data|
            data[:id] = field.id
            data[:name] = field.name
            data[:type] = field.type
            data[:description] = field.description
            data[:choices] = field.family_additional_choices
            data[:value] = find_or_build_additional_value(field.id).value
            data[:required] = required_additional_field_ids.include?(field.id)
            data[:incomplete] = data[:required] && data[:value].blank?
          end
        end
      }
    end
  end

  def available?
    school.admission_family_additional_fields.with_display.exists?
  end

  def fields_present?
    school.family_additional_fields.by_admission.exists?
  end

  def completed?
    props.map { |p| p[:fields] }.flatten.none? { |f| f[:incomplete] }
  end

  private
    def school
      @school ||= @application.school
    end

    def family
      @family ||= @applicant.family
    end

    def additional_groups
      query = school.family_additional_groups
        .by_admission_fields
        .ordered
        .distinct

      fields_by_group.key?(0) ? query.with_default_group : query
    end

    def fields_by_group
      @fields_by_group ||= school.family_additional_fields
        .join_application_fields
        .by_admission
        .order_by_sequence
        .group_by(&:family_additional_group_id)
    end

    def additional_values_by_field
      @additional_values_by_field ||= family.admission_family_additional_values
        .index_by(&:family_additional_field_id)
    end

    def find_or_build_additional_value(field_id)
      additional_values_by_field[field_id] ||
        family.admission_family_additional_values.build(family_additional_field_id: field_id)
    end

    def required_additional_field_ids
      @required_additional_field_ids ||= school.admission_family_additional_fields
        .by_required
        .pluck(:family_additional_field_id)
    end
end
