class Admin::Admissions::Families::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 = find_or_build_additional_value(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

  def fields
    render_success :ok, json: additional_fields.map { |f| field_props(f) }
  end

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

    def group_fields
      @group_fields ||= additional_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 admission_additional_values
      family.admission_family_additional_values.by_school_year(school_year)
    end

    def additional_values
      @additional_values ||= admission_additional_values.index_by(&:family_additional_field_id)
    end

    def find_or_build_additional_value(field_id)
      additional_values[field_id] ||
        admission_additional_values.build(family_additional_field_id: field_id)
    end

    def family_values
      @family_values ||= family.family_additional_values
        .where(family_additional_field_id: additional_fields.pluck(:id))
        .pluck(:family_additional_field_id, :value)
        .to_h
    end

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

    def group_props(group)
      {}.tap do |prop|
        prop[:id] = group.id
        prop[:name] = group.name
        prop[:order] = group.sequence
        prop[:description] = group.description
        prop[:fields] = (group_fields[group.id] || []).map { |f| field_props(f) }
      end
    end

    def field_props(field)
      {}.tap do |props|
        props[:id] = field.id
        props[:name] = field.name
        props[:type] = field.type
        props[:description] = field.description
        props[:choices] = field.family_additional_choices
        props[:value] = find_or_build_additional_value(field.id).value
        props[:family_value] = family_values[field.id]
      end
    end
end
