# For designating which object a published piece of content is related to.
# Other objects may also say which objects they are interested in so they can pull in related content.

module RelatesObjectTags
  extend ActiveSupport::Concern

  included do

    after_destroy :destroy_all_relationships!

    def destroy_all_relationships!
      Relationship.by_base_object(self).destroy_all
      Relationship.by_related_object(self).destroy_all
    end

    def related_to(type=nil)
      if type
        Relationship.by_base_object_and_related_type(self, type).load_objects
      else
        Relationship.by_base_object(self).load_objects
      end
    end

    def related_from(type=nil)
      if type
        Relationship.by_related_object_and_base_type(self, type).load_objects(group_by: :base_type)
      else
        Relationship.by_related_object(self).load_objects(group_by: :base_type)
      end
    end



    # ----------------------------------------
    # DEPRICATED:
    # Related Object Tag stuff is now depricated in favor
    # of the new Relationship class. Everything below will
    # be removed in v2.0.0.
    #
    # This concern will probably be renamed at that point too.
    # ----------------------------------------

    # This is the object tag that this object "owns".
    #  We are validating that this is unique.
    field :my_object_tag, type: String

    # An array of object tags that this object is related to and interested in pulling in content for.
    # In the case of news/events, this would be object tags they want to publish to.
    field :related_object_tags, type: Array, default: []

    # Pass in a tag or array of tags
    scope :by_object_tags, -> tags do
      where({ "my_object_tag" => { "$in" => Array(tags) }})
    end

    # Returns an array of related_object_tags plus my_object_tag
    def all_object_tags
      (Array(my_object_tag.presence) + Array(related_object_tags)).compact.uniq
    end

    def related_object_tags_string(separator=",")
      related_object_tags.join(separator)
    end

    # If you want to specify the separator...
    #   related_object_tags_string = "some string", " | "
    def related_object_tags_string=(string)
      separator = ","
      # This adds support for customizing the separator
      if string.is_a?(Array) && string.length == 2
        separator = string.last
        string = string.first
      end
      self.related_object_tags = String(string).split(separator).map(&:strip)
    end

    def related_objects(klass)
      klass.by_object_tags(related_object_tags)
    end

  end
end
