class Admin::Admissions::Families::Current::AdditionalValuesController <
  Admin::Admissions::Controller
  include Admin::Admissions::FamilyScoped

  def index
    render_success :ok, json: groups.map { |group| group_props(group) }
  end

  def update
    objects = []
    params[:additional_values].each do |param|
      additional_value = family.family_additional_values
        .find_or_initialize_by(family_additional_field_id: param[:field_id])
      additional_value.value = param[:value]
      objects << additional_value
    end

    if transactional_save(objects)
      render_success :ok, object: :additional_values
    else
      render_error :unprocessable_entity, errors: multi_errors(objects)
    end
  end

  private
    def fields
      current_school.family_additional_fields
        .by_admission(true)
        .join_application_fields(display?)
    end

    def group_fields
      @group_fields ||= fields.order(:sequence).group_by(&:family_additional_group_id)
    end

    def groups
      query = current_school.family_additional_groups
        .by_admissions(true)
        .by_admission_fields(display?)
        .ordered
        .distinct

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

    def additional_values
      @additional_values ||= family.family_additional_values
        .pluck(:family_additional_field_id, :value)
        .to_h
    end

    def display?
      params.key?(:display) ? params[:display].to_bool : true
    end

    def group_props(group)
      {
        id: group.id,
        name: group.name,
        order: group.sequence,
        description: group.description,
        fields: group_fields[group.id]&.map { |f| field_props(f) }
      }
    end

    def field_props(field)
      {
        id: field.id,
        name: field.name,
        type: field.type,
        description: field.description,
        choices: field.family_additional_choices,
        value: additional_values[field.id]
      }
    end
end
