class Avo::BaseAction

def action_name

def action_name
  return name if name.present?
  self.class.to_s.demodulize.underscore.humanize(keep_id_suffix: true)
end

def add_message(body, type = :info)

def add_message(body, type = :info)
  response[:messages] << {
    type: type,
    body: body
  }
end

def curent_user

def curent_user
  Avo::Current.user
end

def download(path, filename)

def download(path, filename)
  response[:type] = :download
  response[:path] = path
  response[:filename] = filename
  self
end

def error(text)

def error(text)
  add_message text, :error
  self
end

def fields

Blank method
def fields
end

def form_data_attributes

def form_data_attributes
  # We can't respond with a file download from Turbo se we disable it on the form
  if may_download_file
    {turbo: turbo || false, remote: false, action_target: :form}
  else
    {turbo: turbo, turbo_frame: :_top, action_target: :form}.compact
  end
end

def get_attributes_for_action

def get_attributes_for_action
  get_fields.map do |field|
    value = field.value || Avo::ExecutionContext.new(
      target: field.default,
      record: self.class.record,
      resource: self.class.resource,
      view: view
    ).handle
    [field.id, value]
  end.to_h
end

def get_message

def get_message
  Avo::ExecutionContext.new(target: self.class.message, record: self.class.record, resource: self.class.resource).handle
end

def handle_action(**args)

def handle_action(**args)
  records, fields, current_user, resource = args.values_at(:records, :fields, :current_user, :resource)
  # Fetching the field definitions and not the actual fields (get_fields) because they will break if the user uses a `visible` block and adds a condition using the `params` variable. The params are different in the show method and the handle method.
  action_fields = get_field_definitions.map { |field| [field.id, field] }.to_h
  # For some fields, like belongs_to, the id and database_id differ (user vs user_id).
  # That's why we need to fetch the database_id for when we process the action.
  action_fields_by_database_id = action_fields.map do |id, value|
    [value.database_id.to_sym, value]
  end.to_h
  if fields.present?
    processed_fields = fields.to_unsafe_h.map do |name, value|
      field = action_fields_by_database_id[name.to_sym]
      next if field.blank?
      [name, field.resolve_attribute(value)]
    end
    processed_fields = processed_fields.reject(&:blank?).to_h
  else
    processed_fields = {}
  end
  args = {
    fields: processed_fields.with_indifferent_access,
    current_user: current_user,
    resource: resource
  }
  args[:records] = records
  handle(**args)
  self
end

def hydrate_fields

We're overriding this method to hydrate with the proper resource attribute.
def hydrate_fields
  fields.map do |field|
    field.hydrate(record: @record, view: @view, resource: resource)
  end
  self
end

def inform(text)

def inform(text)
  add_message text, :info
  self
end

def initialize(record: nil, resource: nil, user: nil, view: nil, arguments: {})

def initialize(record: nil, resource: nil, user: nil, view: nil, arguments: {})
  self.class.record = record
  self.class.resource = resource
  self.class.user = user
  self.class.view = view
  @arguments = arguments
  self.class.message ||= I18n.t("avo.are_you_sure_you_want_to_run_this_option")
  self.class.confirm_button_label ||= I18n.t("avo.run")
  self.class.cancel_button_label ||= I18n.t("avo.cancel")
  self.items_holder = Avo::Resources::Items::Holder.new
  fields
  @response ||= {}
  @response[:messages] = []
end

def keep_modal_open

def keep_modal_open
  response[:keep_modal_open] = true
  self
end

def param_id

def param_id
  self.class.to_s
end

def redirect_to(path = nil, allow_other_host: nil, status: nil, &block)

def redirect_to(path = nil, allow_other_host: nil, status: nil, &block)
  response[:type] = :redirect
  response[:allow_other_host] = allow_other_host
  response[:status] = status
  response[:path] = if block.present?
    block
  else
    path
  end
  self
end

def reload

def reload
  response[:type] = :reload
  self
end

def silent

Add a placeholder silent message from when a user wants to do a redirect action or something similar
def silent
  add_message nil, :silent
  self
end

def submit_button_data_attributes

We can't respond with a file download from Turbo se we disable close the modal manually after a while (it's a hack, we know)
def submit_button_data_attributes
  if may_download_file
    {action: "click->modal#delayedClose"}
  else
    {}
  end
end

def succeed(text)

def succeed(text)
  add_message text, :success
  self
end

def visible_in_view(parent_resource: nil)

def visible_in_view(parent_resource: nil)
  if visible.blank?
    # Hide on the :new view by default
    return false if view == :new
    # Show on all other views
    return true
  end
  # Run the visible block if available
  Avo::ExecutionContext.new(
    target: visible,
    params: params,
    parent_resource: parent_resource,
    resource: self.class.resource,
    view: self.class.view,
    arguments: arguments
  ).handle
end

def warn(text)

def warn(text)
  add_message text, :warning
  self
end