class Avo::ApplicationController

def _authenticate!

def _authenticate!
  instance_eval(&Avo.configuration.authenticate)
end

def _current_user

def _current_user
  instance_eval(&Avo.configuration.current_user)
end

def add_initial_breadcrumbs

def add_initial_breadcrumbs
  instance_eval(&Avo.configuration.initial_breadcrumbs) if Avo.configuration.initial_breadcrumbs.present?
end

def assign_default_value_to_disabled_fields

def assign_default_value_to_disabled_fields
  @resource.get_field_definitions.select do |field|
    field.is_disabled? && field.visible? && !field.computed
  end.each do |field|
    # Get the default value from the field default definition
    # If there is no default value specified on the resource, get the value from the record (DB, Callbacks, etc.)
    default_value = field.default || @record.send(field.id)
    field.fill_field @record, field.id, default_value, params
  end
end

def authorize_action(class_to_authorize, action = nil)

def authorize_action(class_to_authorize, action = nil)
  # Use the provided action or figure it out from the request
  action_to_authorize = action || action_name
  @authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
end

def authorize_base_action

def authorize_base_action
  class_to_authorize = @record || @resource.model_class
  authorize_action class_to_authorize
end

def context

def context
  instance_eval(&Avo.configuration.context)
end

def default_url_options

def default_url_options
  if params[:force_locale].present?
    {**super, force_locale: params[:force_locale]}
  else
    super
  end
end

def eager_load_files(resource, query)

def eager_load_files(resource, query)
  # Get the non-computed file fields and try to eager load them
  attachment_fields = resource
    .attachment_fields
    .reject do |field|
      field.computed
    end
  if attachment_fields.present?
    attachment_fields.map do |field|
      attachment = case field.class.to_s
      when "Avo::Fields::FileField"
        "attachment"
      when "Avo::Fields::FilesField"
        "attachments"
      else
        "attachment"
      end
      return query.includes "#{field.id}_#{attachment}": :blob
    end
  end
  query
end

def exception_logger(exception)

def exception_logger(exception)
  respond_to do |format|
    format.html { raise exception }
    format.json {
      render json: {
        errors: exception.respond_to?(:record) && exception.record.present? ? exception.record.errors : [],
        message: exception.message,
        traces: exception.backtrace
      }, status: ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
    }
  end
end

def fill_record

def fill_record
  # We have to skip filling the the record if this is an attach action
  return if is_attach_action?
  @record = @resource.fill_record(@record_to_fill, cast_nullable(model_params), extra_params: extra_params)
  assign_default_value_to_disabled_fields if @view == :create
end

def is_attach_action?

def is_attach_action?
  params[model_param_key].blank? && params[:related_name].present? && params[:fields].present?
end

def model_find_scope

def model_find_scope
  eager_load_files(@resource, model_scope)
end

def model_param_key

def model_param_key
  @resource.form_scope
end

def model_scope

def model_scope
  # abort @resource.inspect
  @resource.class.find_scope
end

def related_resource

def related_resource
  # Find the field from the parent resource
  field = @resource.get_field params[:related_name]
  return field.use_resource if field&.use_resource.present?
  reflection = @record._reflections[params[:related_name]]
  reflected_model = reflection.klass
  Avo.resource_manager.get_resource_by_model_class reflected_model
end

def related_resource_name

def related_resource_name
  params[:related_name]
end

def render_unauthorized(exception)

def render_unauthorized(exception)
  flash[:notice] = t "avo.not_authorized"
  redirect_url = if request.referrer.blank? || (request.referrer == request.url)
    root_url
  else
    request.referrer
  end
  redirect_to(redirect_url)
end

def resource

Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
Gets the Avo resource for this request based on the request from the `resource_name` "param"
def resource
  resource = Avo.resource_manager.get_resource @resource_name.to_s.camelize.singularize
  return resource if resource.present?
  Avo.resource_manager.get_resource_by_controller_name @resource_name
end

def resource_name

Ex: projects, teams, users
Get the pluralized resource name for this request
def resource_name
  return params[:resource_name] if params[:resource_name].present?
  return controller_name if controller_name.present?
  begin
    request.path
      .match(/\/?#{Avo.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
      .captures
      .first
  rescue
  end
end

def set_active_storage_current_host

Set the current host for ActiveStorage
def set_active_storage_current_host
  if defined?(ActiveStorage::Current)
    if Rails::VERSION::MAJOR === 6
      ActiveStorage::Current.host = request.base_url
    elsif Rails::VERSION::MAJOR === 7
      ActiveStorage::Current.url_options = {protocol: request.protocol, host: request.host, port: request.port}
    end
  end
rescue => exception
  Avo.logger.debug "Failed to set ActiveStorage::Current.url_options, #{exception.inspect}"
end

def set_authorization

def set_authorization
  # We need to set @resource_name for the #resource method to work properly
  set_resource_name
  @authorization = if @resource
    @resource.authorization(user: _current_user)
  else
    Services::AuthorizationService.new _current_user
  end
end

def set_avo_locale(&action)

Sets the locale set in avo.rb initializer
def set_avo_locale(&action)
  locale = Avo.configuration.locale || I18n.default_locale
  I18n.with_locale(locale, &action)
end

def set_container_classes

def set_container_classes
  contain = true
  if Avo.configuration.full_width_container
    contain = false
  elsif Avo.configuration.full_width_index_view && action_name.to_sym == :index && self.class.superclass.to_s == "Avo::ResourcesController"
    contain = false
  end
  @container_classes = contain ? "2xl:container 2xl:mx-auto" : ""
end

def set_default_locale

Enable the user to change the default locale with the `?set_locale=pt-BR` param
def set_default_locale
  locale = params[:set_locale] || I18n.default_locale
  I18n.default_locale = locale
end

def set_force_locale(&action)

Temporary set the locale and reverting at the end of the request.
def set_force_locale(&action)
  locale = params[:force_locale] || I18n.default_locale
  I18n.with_locale(locale, &action)
end

def set_record

def set_record
  @record = @resource.find_record(params[:id], query: model_find_scope, params: params)
  @resource.hydrate(record: @record)
end

def set_record_to_fill

def set_record_to_fill
  @record_to_fill = @resource.model_class.new if @view == :create
  @record_to_fill = @record if @view == :update
  # If resource.record is nil, most likely the user is creating a new record.
  # In that case, to access resource.record in visible and readonly blocks we hydrate the resource with a new record.
  # TODO: commented this
  @resource.hydrate(record: @record_to_fill) if @resource.record.nil?
end

def set_related_record

def set_related_record
  association_name = BaseResource.valid_association_name(@record, params[:related_name])
  @related_record = if @field.is_a? Avo::Fields::HasOneField
    @record.send association_name
  else
    @related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @record.send(association_name)), params: params
  end
  @related_resource.hydrate(record: @related_record)
end

def set_related_resource

def set_related_resource
  @related_resource = related_resource.new(params: params, view: action_name.to_sym, user: _current_user, record: @related_record)
end

def set_related_resource_name

def set_related_resource_name
  @related_resource_name = related_resource_name
end

def set_resource

def set_resource
  raise ActionController::RoutingError.new "No route matches" if resource.nil?
  @resource = resource.new(view: action_name.to_sym, user: _current_user, params: params)
  set_authorization
end

def set_resource_name

def set_resource_name
  @resource_name = resource_name
end

def set_sidebar_open

def set_sidebar_open
  value = cookies["#{Avo::COOKIES_KEY}.sidebar.open"]
  @sidebar_open = value.blank? || value == "1"
end

def set_view

def set_view
  @view = action_name.to_sym
end

def turbo_frame_request?

Exposing it as public method
This is coming from Turbo::Frames::FrameRequest module.
def turbo_frame_request?
  super
end