class SvelteOnRails::Lib::SvelteAttributes

def calculate_class(model, attributes, call_stack: 0)

def calculate_class(model, attributes, call_stack: 0)
  next_stack = call_stack + 1
  set_labels(model, attributes)
  hash = attributes.find { |element| element.is_a?(Hash) } || {}
  hash.each do |key, value|
    reflect = model.reflect_on_association(key.to_s)
    if reflect
      calculate_class(
        reflect,
        value,
        call_stack: next_stack
      )
    end
  end
  if call_stack == 0
    @labels
  end
end

def calculate_instance(record, attributes, call_stack: 0, offset: nil, limit: nil)

def calculate_instance(record, attributes, call_stack: 0, offset: nil, limit: nil)
  next_stack = call_stack + 1
  if record.respond_to?(:each)
    recs2 = if offset || limit
              if (record.is_a?(ActiveRecord::Relation) || record.is_a?(ActiveRecord::Associations::CollectionProxy) rescue false)
                _recs = (offset ? record.offset(offset) : record)
                (limit ? _recs.limit(limit) : _recs)
              elsif record.respond_to?(:drop) && record.respond_to?(:take) # that might be a array
                _recs = offset ? record.drop(offset) : record
                limit ? _recs.take(limit) : _recs
              else
                raise "[svelte-on-rails:to_svelte] unknown class for records: #{record}"
              end
            else
              record
            end
    set_labels(record.first, attributes)
    values = recs2.map do |rec|
      calculate_instance(rec, attributes, call_stack: next_stack)
    end
  else
    # we have a single record
    values = {}
    set_labels(record, attributes)
    attributes.each do |attr|
      if attr.is_a? Hash
        # we have associations
        attr.each do |key, value|
          next if ['offset', 'limit'].include?(key.to_s)
          _offset, _limit, _value = extract_limit(value)
          _key = key.to_s
          # inspect association and set_labels
          reflect = record.class.reflect_on_association(_key)
          raise "invalid association: #{_key}" unless reflect
          set_labels(reflect, value)
          # values
          recs = record.send(_key)
          if recs.present?
            if recs.respond_to?(:each)
              values[_key] = calculate_instance(
                recs,
                value,
                call_stack: next_stack,
                offset: _offset,
                limit: _limit
              )
            else
              values[_key] = calculate_instance(
                recs,
                value,
                call_stack: next_stack
              )
            end
          end
        end
      else
        # we have attributes
        raise 'Invalid attribute' unless [Symbol, String].include?(attr.class)
        _key = attr.to_s
        values[_key] = record.send(_key)
      end
    end
  end
  if call_stack >= 1
    values
  else
    { 'values' => values }.merge(@labels)
  end
end

def calculate_relation(relation, attributes, call_stack: 0)

def calculate_relation(relation, attributes, call_stack: 0)
  set_labels(relation.klass, attributes)
  values = relation.map do |rec|
    calculate_instance(rec, attributes)['values']
  end
  {
    'values' => values
  }.merge(@labels)
end

def extract_limit(attributes)

def extract_limit(attributes)
  _hash_args = attributes.grep(Hash).first.dup
  attr, lim = if _hash_args.present?
                hash_args = _hash_args.transform_keys { |key| key.to_s } # multiple arrays is not possible
                hash_remainder = hash_args.reject { |key, _| %w[offset limit].include?(key.to_s) }
                _attr = attributes.reject { |item| item.is_a?(Hash) }
                [
                  if hash_remainder.any?
                    _attr + [hash_remainder]
                  else
                    _attr
                  end,
                  hash_args
                ]
              else
                [
                  attributes,
                  {}
                ]
              end
  [
    lim['offset'],
    lim['limit'],
    attr
  ]
end

def initialize

def initialize
  @labels = {}
end

def set_labels(record, keys)

def set_labels(record, keys)
  first_hash = keys.find { |element| element.is_a?(Hash) }
  _keys = keys.reject { |element| element.is_a?(Hash) }
  _keys += first_hash.keys if first_hash
  _keys.each do |attr|
    unless attr.respond_to?(:each)
      obj = if record.respond_to?(:human_attribute_name)
              record
            elsif record.class.respond_to?(:human_attribute_name)
              record.class
            end
      next unless obj
      @labels["#{obj.to_s.underscore}_labels"] ||= {}
      @labels["#{obj.to_s.underscore}_labels"][attr.to_s] ||= obj.human_attribute_name(attr)
    end
  end
end