class Lookbook::Collection

def add(item)

def add(item)
  @ordered_entities = nil
  @tree = nil
  if item.is_a?(String)
    item = Collection.new([@path, item].join("/"))
  end
  @items << item
  item
end

def as_tree(filter_hidden: true)

def as_tree(filter_hidden: true)
  return self if hierarchy_depth > 0
  return @tree if @tree.present?
  @tree = self.class.new
  candidates = filter_hidden ? visible_items : items
  candidates.each do |item|
    current = @tree
    if item.hierarchy_depth == 1
      current.add(item)
    else
      item.parent_collections_names.each.with_index(1) do |name, i|
        target = current.get_or_create(name)
        if item.hierarchy_depth == i + 1
          target.add(item)
        else
          current = target
        end
      end
    end
  end
  @tree
end

def basename

def basename
  @path.present? ? @path.split("/").last : ""
end

def describe_as

def describe_as
  "items"
end

def find(lookup = nil, &block)

def find(lookup = nil, &block)
  if lookup
    lookup.is_a?(Symbol) ? find_by_id(lookup.to_s.tr("_", "-")) : find_by_path(lookup)
  elsif block
    items.find(&block)
  end
end

def find_by_id(id)

def find_by_id(id)
  items.find { |i| i.id == id }
end

def find_by_path(path)

def find_by_path(path)
  items.find { |i| i.lookup_path == path }
end

def find_first

def find_first
  ordered_entities.first
end

def find_next(item)

def find_next(item)
  index = ordered_entities.find_index { |i| i.lookup_path == item.lookup_path }
  ordered_entities[index + 1] unless index.nil?
end

def find_parent(child)

def find_parent(child)
  parent_path = child.lookup_path.split("/").pop.join("/")
  find_by_path(parent_path)
end

def find_previous(item)

def find_previous(item)
  index = ordered_entities.find_index { |i| i.lookup_path == item.lookup_path }
  ordered_entities[index - 1] if !index.nil? && index > 0
end

def get(name)

def get(name)
  name = name.underscore
  items.find { |item| item.name.underscore == name }
end

def get_or_create(name)

def get_or_create(name)
  get(remove_position_prefix(name)).presence || add(name)
end

def hierarchy_depth

def hierarchy_depth
  @path ? @path.split("/").size : 0
end

def id

def id
  generate_id(lookup_path || "root")
end

def initialize(path = "", items = [])

def initialize(path = "", items = [])
  if path.is_a?(Array)
    @items = path
    path = ""
  else
    @items = items
  end
  @path = path.delete_prefix("/").delete_suffix("/")
end

def items

def items
  @items.sort_by { |item| [item.hierarchy_depth, item.position, item.label] }
end

def label

def label
  name&.titleize
end

def lookup_path

def lookup_path
  @lookup_path ||= to_lookup_path(@path)
end

def name

def name
  @name ||= remove_position_prefix(basename)
end

def ordered_entities

def ordered_entities
  return @ordered_entities if @ordered_entities.present?
  entities = []
  as_tree.items.each do |item|
    entities.append(item.is_a?(Collection) ? item.ordered_entities : item)
  end
  @ordered_entities ||= entities.flatten
end

def position

def position
  @position ||= parse_position_prefix(basename).first
end

def type

def type
  :collection
end

def visible_items

def visible_items
  reject { |i| i.hidden? }
end