module Avo::Fields::Concerns::HasHTMLAttributes

def add_default_data_attributes(attributes, name, element, view)

def add_default_data_attributes(attributes, name, element, view)
  if !attributes.nil? && name == :data && element == :input && view.in?([:edit, :new]) && resource.present? && resource.respond_to?(:get_stimulus_controllers)
    extra_attributes = resource.get_stimulus_controllers
      .split(" ")
      .map do |controller|
        [:"#{controller}-target", "#{id.to_s.underscore}_#{type.to_s.underscore}_input".camelize(:lower)]
      end
      .to_h
    attributes.merge extra_attributes
  else
    attributes
  end
end

def default_attribute_value(name)

def default_attribute_value(name)
  name == :data ? {} : ""
end

def get_html(name = nil, element:, view:)

get_html :styles, view: :index, element: :wrapper
get_html :classes, view: :show, element: :wrapper
get_html :data, view: :edit, element: :input
examples:

Used to get attributes for elements and views
def get_html(name = nil, element:, view:)
  if [view, element].any?(&:nil?)
    default_attribute_value name
  end
  parsed = parse_html
  attributes = if parsed.is_a? Hash
    get_html_from_hash name, element: element, hash: parsed, view: view
  elsif parsed.is_a? Avo::HTML::Builder
    get_html_from_block name, element: element, html_builder: parsed, view: view
  elsif parsed.nil?
    # Handle empty parsed by returning an empty state
    default_attribute_value name
  end
  add_default_data_attributes attributes, name, element, view
end

def get_html_from_block(name = nil, element:, html_builder:, view:)

def get_html_from_block(name = nil, element:, html_builder:, view:)
  values = []
  # get view ancestor
  values << html_builder.dig_stack(view, element, name)
  # get element ancestor
  values << html_builder.dig_stack(element, name)
  # get direct ancestor
  values << html_builder.dig_stack(name)
  values_type = if name == :data
    :hash
  else
    :string
  end
  merge_values_as(as: values_type, values: values)
end

def get_html_from_hash(name = nil, element:, hash:, view:)

def get_html_from_hash(name = nil, element:, hash:, view:)
  # @todo: what if this is not a Hash but a string?
  hash.dig(view, element, name) || {}
end

def merge_values_as(as: :array, values: [])

Ex: if the style attribute is empty return `nil` instead of an empty space `" "`

If the result is "blank", return nil so the attributes are not outputted to the DOM.
Merge the values from all possible locations.
def merge_values_as(as: :array, values: [])
  result = if as == :array
    values.flatten
  elsif as == :string
    values.select do |value|
      value.is_a? String
    end.join " "
  elsif as == :hash
    values.reduce({}, :merge)
  end
  result if result.present?
end

def parse_html

Returns Hash, HTML::Builder, or nil.
def parse_html
  return if @html.nil?
  if @html.is_a? Hash
    @html
  elsif @html.respond_to? :call
    Avo::HTML::Builder.parse_block(record: record, resource: resource, &@html)
  end
end