class Avo::Fields::BelongsToField

def database_id

def database_id
  # If the field is a polymorphic value, return the polymorphic_type as key and pre-fill the _id in fill_field.
  return "#{polymorphic_as}_type" if polymorphic_as.present?
  foreign_key
rescue
  id
end

def database_value

def database_value
  target_resource.id
rescue
  nil
end

def field_label

What the user sees in the text field
def field_label
  value.send(target_resource.class.title)
rescue
  nil
end

def field_value

The value
def field_value
  value.send(database_value)
rescue
  nil
end

def fill_field(model, key, value, params)

def fill_field(model, key, value, params)
  return model unless model.methods.include? key.to_sym
  if polymorphic_as.present?
    model.send("#{polymorphic_as}_type=", params["#{polymorphic_as}_type"])
    # If the type is blank, reset the id too.
    if params["#{polymorphic_as}_type"].blank?
      model.send("#{polymorphic_as}_id=", nil)
    else
      model.send("#{polymorphic_as}_id=", params["#{polymorphic_as}_id"])
    end
  else
    model.send("#{key}=", value)
  end
  model
end

def foreign_key

def foreign_key
  return polymorphic_as if polymorphic_as.present?
  if @model.present?
    get_model_class(@model).reflections[@relation_method].foreign_key
  elsif @resource.present? && @resource.model_class.reflections[@relation_method].present?
    @resource.model_class.reflections[@relation_method].foreign_key
  end
end

def get_model

def get_model
  return @model if @model.present?
  @resource.model
rescue
  nil
end

def get_model_class(model)

def get_model_class(model)
  if model.instance_of?(Class)
    model
  else
    model.class
  end
end

def id_input_foreign_key

def id_input_foreign_key
  if is_polymorphic?
    "#{foreign_key}_id"
  else
    foreign_key
  end
end

def initialize(id, **args, &block)

def initialize(id, **args, &block)
  args[:placeholder] ||= I18n.t("avo.choose_an_option")
  super(id, **args, &block)
  @searchable = args[:searchable] == true
  @polymorphic_as = args[:polymorphic_as]
  @types = args[:types]
  @relation_method = id.to_s.parameterize.underscore
  @allow_via_detaching = args[:allow_via_detaching] == true
  @attach_scope = args[:attach_scope]
  @polymorphic_help = args[:polymorphic_help]
  @target = args[:target]
end

def is_polymorphic?

def is_polymorphic?
  polymorphic_as.present?
rescue
  false
end

def label

def label
  value.send(target_resource.class.title)
end

def name

def name
  return polymorphic_as.to_s.humanize if polymorphic_as.present? && view == :index
  super
end

def options

def options
  values_for_type
end

def reflection

Get the model reflection instance
def reflection
  reflection_for_key(id)
rescue
  nil
end

def reflection_for_key(key)

def reflection_for_key(key)
  get_model_class(get_model).reflections[key.to_s]
rescue
  nil
end

def relation_model_class

def relation_model_class
  @resource.model_class
end

def searchable

def searchable
  @searchable && ::Avo::App.license.has_with_trial(:searchable_associations)
end

def target_resource

def target_resource
  if is_polymorphic?
    if value.present?
      return App.get_resource_by_model_name(value.class)
    else
      return nil
    end
  end
  reflection_key = polymorphic_as || id
  if @model._reflections[reflection_key.to_s].klass.present?
    App.get_resource_by_model_name @model._reflections[reflection_key.to_s].klass.to_s
  elsif @model._reflections[reflection_key.to_s].options[:class_name].present?
    App.get_resource_by_model_name @model._reflections[reflection_key.to_s].options[:class_name]
  else
    App.get_resource_by_name reflection_key.to_s
  end
end

def to_permitted_param

def to_permitted_param
  if polymorphic_as.present?
    return ["#{polymorphic_as}_type".to_sym, "#{polymorphic_as}_id".to_sym]
  end
  foreign_key.to_sym
end

def type_input_foreign_key

def type_input_foreign_key
  if is_polymorphic?
    "#{foreign_key}_type"
  end
end

def value

def value
  if is_polymorphic?
    # Get the value from the pre-filled assoociation record
    super(polymorphic_as)
  else
    # Get the value from the pre-filled assoociation record
    super(relation_method)
  end
end

def values_for_type(model = nil)

def values_for_type(model = nil)
  resource = target_resource
  resource = App.get_resource_by_model_name model if model.present?
  query = Avo::Services::AuthorizationService.apply_policy(user, resource.class.query_scope)
  if attach_scope.present?
    query = Avo::Hosts::AssociationScopeHost.new(block: attach_scope, query: query, parent: get_model).handle
  end
  query.all.map do |model|
    [model.send(resource.class.title), model.id]
  end
end