class Avo::ActionsController

def action_class

def action_class
  Avo::BaseAction.descendants.find do |action|
    action.to_s == params[:action_id]
  end
end

def action_params

def action_params
  params.permit(:authenticity_token, :resource_name, :action_id, :button, fields: {})
end

def decrypted_arguments

def decrypted_arguments
  arguments = params[:arguments] || params.dig(:fields, :arguments)
  return if arguments.blank?
  Avo::Services::EncryptionService.decrypt(
    message: Base64.decode64(arguments),
    purpose: :action_arguments
  )
end

def decrypted_query

def decrypted_query
  Avo::Services::EncryptionService.decrypt(
    message: @selected_query,
    purpose: :select_all
  )
end

def flash_messages(messages)

def flash_messages(messages)
  messages.each do |message|
    flash[message[:type]] = message[:body]
  end
end

def get_messages(response)

def get_messages(response)
  default_message = {
    type: :info,
    body: I18n.t("avo.action_ran_successfully")
  }
  return [default_message] if response[:messages].blank?
  response[:messages].select do |message|
    # Remove the silent placeholder messages
    message[:type] != :silent
  end
end

def handle

def handle
  resource_ids = action_params[:fields][:avo_resource_ids].split(",")
  @selected_query = action_params[:fields][:avo_selected_query]
  fields = action_params[:fields].except(:avo_resource_ids, :avo_selected_query)
  args = {
    fields: fields,
    current_user: _current_user,
    resource: resource
  }
  args[:records] = if @selected_query.present?
    @resource.model_class.find_by_sql decrypted_query
  else
    @resource.find_record resource_ids, params: params
  end
  performed_action = @action.handle_action(**args)
  respond performed_action.response
end

def keep_modal_open(messages)

def keep_modal_open(messages)
  flash_messages messages
  respond_to do |format|
    format.turbo_stream do
      render "keep_modal_open"
    end
  end
end

def respond(response)

def respond(response)
  messages = get_messages response
  return keep_modal_open(messages) if response[:keep_modal_open]
  response[:type] ||= :reload
  if response[:type] == :download
    return send_data response[:path], filename: response[:filename]
  end
  respond_to do |format|
    format.html do
      # Flash the messages collected from the action
      flash_messages messages
      if response[:type] == :redirect
        redirect_to Avo::ExecutionContext.new(target: response[:path]).handle,
          **{allow_other_host: response[:allow_other_host], status: response[:status]}.compact
      elsif response[:type] == :reload
        redirect_back fallback_location: resources_path(resource: @resource)
      end
    end
  end
end

def set_action

def set_action
  @action = action_class.new(
    record: @record,
    resource: @resource,
    user: _current_user,
    view: :new, # force the action view to in order to render new-related fields (hidden field)
    arguments: decrypted_arguments || {}
  )
end

def show

def show
  # Se the view to :new so the default value gets prefilled
  @view = :new
  @resource.hydrate(record: @record, view: @view, user: _current_user, params: params)
  @record = ActionModel.new @action.get_attributes_for_action
end