module ZuoraConnect::Controllers::Helpers

def authenticate_connect_app_request

def authenticate_connect_app_request
  Thread.current[:appinstance] = nil
  if params[:app_instance_ids].present? && !params[:app_instance_id].present?
    begin
      app_instance_ids = JSON.parse(Base64.urlsafe_decode64(params[:app_instance_ids]))
      if app_instance_ids.length == 1
        verify_with_navbar
        instances = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(session[params[:app_instance_ids]]["url"]).query)["app_instance_ids"][0]))
        if instances.include?(app_instance_ids[0])
          @appinstance = ZuoraConnect::AppInstance.find(app_instance_ids[0])
          @appinstance.new_session(session: {})
          @appinstance.cache_app_instance
          session["appInstance"] = app_instance_ids[0]
        else
          Rails.logger.fatal("Launch Error: Param Instance didnt match session data")
          render "zuora_connect/static/invalid_launch_request"
          return
        end
      else
        select_instance
        return
      end
    rescue => ex
      Rails.logger.fatal("Launch Error: #{ex.message}")
      render "zuora_connect/static/invalid_launch_request"
      return
    end
    
  elsif params[:app_instance_ids].present? && params[:app_instance_id].present?
    begin
      instances = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(session[params[:app_instance_ids]]["url"]).query)["app_instance_ids"][0]))
      if instances.include?(params[:app_instance_id].to_i)
        @appinstance = ZuoraConnect::AppInstance.find(params[:app_instance_id].to_i)
        @appinstance.new_session(session: {})
        @appinstance.cache_app_instance
        session["appInstance"] = params[:app_instance_id].to_i
      else
        render "zuora_connect/static/invalid_launch_request"
        return
      end
    rescue => ex
      Rails.logger.fatal("Launch Error: #{ex.message}")
      render "zuora_connect/static/invalid_launch_request"
      return
    end
  end
  start_time = Time.now
  if ZuoraConnect.configuration.mode == "Production"
    if request["data"] && /^([A-Za-z0-9+\/\-\_]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/.match(request["data"].to_s)
      setup_instance_via_data
    else
      setup_instance_via_session
    end
  else
    setup_instance_via_dev_mode
  end
  #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis 
  #so data lookup provides a model method that can be overriden per app.
  if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
    if @appinstance.new_session_for_ui_requests(:params => params)
      @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
    end
  end
  if session["#{@appinstance.id}::user::email"].present? 
    ElasticAPM.set_user(session["#{@appinstance.id}::user::email"])  if defined?(ElasticAPM) 
    PaperTrail.whodunnit =  session["#{@appinstance.id}::user::email"] if defined?(PaperTrail)
  end
  begin
    I18n.locale = session["#{@appinstance.id}::user::locale"] ?  session["#{@appinstance.id}::user::locale"] : @appinstance.locale
  rescue I18n::InvalidLocale => ex
    Rails.logger.error("Invalid Locale: #{ex.message}")
  end
  Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
  Rails.logger.debug("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
end