class Employee::AddressBook::Contacts::AdditionalValuesController < Employee::Controller
  def index
    render_success :ok, json: groups.map { |g| group_props(g) }
  end

  def update
    objects = []
    fields = additional_fields.index_by(&:id)

    params[:additional_values].each do |param|
      additional_value = find_or_build_additional_value(param[:field_id])
      if fields[param[:field_id]].date?
        additional_value.value_date = param[:value]
      else
        additional_value.value = param[:value] || ''
      end
      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 contact
      @contact ||= current_school.contacts.find_by(id: params[:contact_id])
    end

    def additional_fields
      current_school.contact_additional_fields.by_ids(params[:additional_values]&.pluck(:field_id))
    end

    def groups
      current_school.contact_additional_groups.preload(:fields).joins(:fields).ordered.distinct
    end

    def additional_values
      @additional_values ||= contact.additional_values.index_by(&:field_id)
    end

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

    def group_props(group)
      {
        id: group.id,
        name: group.name,
        description: group.description,
        fields: group.fields.map { |f| field_props(f) }
      }
    end

    def field_props(field)
      additional_value = find_or_build_additional_value(field.id)
      {
        id: field.id,
        name: field.name,
        type: field.type,
        description: field.description,
        choices: field.choices,
        value: field.date? ? additional_value.value_date : additional_value.value
      }
    end
end
