# frozen_string_literal: true

# Establece una relación de muchos a muchos artículos.  Cada campo es un
# Array de UUID que se mantienen sincronizados.
#
# Por ejemplo:
#
# Un libro puede tener muches autores y une autore muchos libros.  La
# relación has_many tiene que traer todes les autores relacionades con
# el libro actual.  La relación belongs_to tiene que traer todes les
# autores que tienen este libro.  La relación es bidireccional, no hay
# diferencia entre has_many y belongs_to.
class MetadataHasAndBelongsToMany < MetadataHasMany
  # Mantiene la relación inversa si existe.
  #
  # La relación belongs_to se mantiene actualizada en la modificación
  # actual.  Lo que buscamos es mantener sincronizada esa relación.
  #
  # Buscamos en belongs_to la relación local, si se eliminó hay que
  # quitarla de la relación remota, sino hay que agregarla.
  #
  def save
    # XXX: No usamos super
    self[:value] = sanitize value

    return true unless changed?
    return true unless inverse?

    # XXX: Usamos asignación para aprovechar value= que setea el valor
    # anterior en @value_was
    (had_many - has_many).each do |remove|
      remove[inverse].value = remove[inverse].value.reject do |rej|
        rej == post.uuid.value
      end
    end

    (has_many - had_many).each do |add|
      next unless add[inverse]
      next if add[inverse].value.include? post.uuid.value

      add[inverse].value = (add[inverse].value.dup << post.uuid.value)
    end

    true
  end
end