class Lookbook::Preview

def all

def all
  if @previews.nil? && @preview_objects.present?
    previews = @preview_objects.map do |code_object|
      klass = code_object.path.constantize
      new(klass, code_object) if klass.ancestors.include?(ViewComponent::Preview)
    rescue => exception
      Lookbook.logger.error Lookbook::Error.new(exception)
      nil
    end.compact
    sorted_previews = previews.compact.sort_by { |preview| [preview.position, preview.label] }
    @previews = PreviewCollection.new(sorted_previews)
    @previews
  elsif !@preview_objects.present?
    PreviewCollection.new([])
  else
    @previews
  end
end

def any?

def any?
  all.any?
end

def collapsible?

def collapsible?
  true
end

def component

def component
  components.first
end

def components

def components
  component_classes = @preview_inspector&.components&.any? ? @preview_inspector&.components : [guess_component]
  component_classes.map do |class_name|
    Component.new(class_name.to_s)
  end
end

def default_example

def default_example
  examples.first
end

def display_options

def display_options
  Lookbook.config.preview_display_options.deep_merge(@preview_inspector&.display_options)
end

def errors

def errors
  @errors ||= []
end

def example(example_name)

def example(example_name)
  examples.find { |m| m.name == example_name.to_s }
end

def examples

def examples
  return @examples if @examples.present?
  public_methods = @preview.public_instance_methods(false)
  public_method_objects = @preview_inspector&.methods&.select { |m| public_methods.include?(m.name) }
  examples = (public_method_objects || []).map { |m| PreviewExample.new(m.name.to_s, self, m) }
  sorted = Lookbook.config.sort_examples ? examples.sort_by(&:label) : examples
  @examples = []
  if @preview_inspector&.groups&.any?
    sorted.group_by { |m| m.group }.each do |name, examples|
      if name.nil?
        @examples += examples
      else
        name = label if name.strip == ""
        @examples << PreviewGroup.new(name.underscore, self, examples)
      end
    end
  else
    @examples = sorted
  end
  @examples = @examples.compact
end

def exists?(path)

def exists?(path)
  !!find(path)
end

def find(path)

def find(path)
  all.find { |p| p.lookup_path == path }
end

def full_path

def full_path
  base_path = preview_paths.detect do |preview_path|
    Dir["#{preview_path}/#{rel_path}"].first
  end
  Pathname.new(Dir["#{base_path}/#{rel_path}"].first)
end

def guess_component

def guess_component
  name.chomp("Preview").constantize
rescue
  nil
end

def hierarchy_depth

def hierarchy_depth
  path.split("/").size
end

def id

def id
  @preview_inspector&.id || generate_id(lookup_path)
end

def initialize(preview, code_object)

def initialize(preview, code_object)
  @preview = preview
  @preview_inspector = SourceInspector.new(code_object, eval_scope: preview_class.new)
  preview_path = preview_class_path(name)
  if @preview_inspector.logical_path
    basename = preview_path.split("/").last
    preview_path = "#{@preview_inspector.logical_path}/#{basename}"
  end
  super(preview_path)
end

def items

def items
  examples.reject { |i| i.hidden? }
end

def label

def label
  @preview_inspector&.label&.presence || lookup_path.split("/").last.titleize
end

def layout

def layout
  @preview.instance_variable_get(:@layout)
end

def load!(preview_objects)

def load!(preview_objects)
  @preview_objects = preview_objects
  @previews = nil
end

def parent_collections_names

def parent_collections_names
  File.dirname(path).split("/")
end

def preview_class

def preview_class
  @preview
end

def preview_class_name

def preview_class_name
  @preview.name
end

def preview_paths

def preview_paths
  PathUtils.normalize_all(Lookbook.config.preview_paths)
end

def rel_path

def rel_path
  "#{name.underscore}.rb"
end

def type

def type
  :preview
end

def url_path

def url_path
  lookbook_inspect_path lookup_path
end