class ApplicationController < ActionController::Base
  include Oath::ControllerHelpers # Methods for authentication
  include Pundit # Methods for authorization
  include RememberMe::Controller

  before_action :disable_browser_page_caching
  before_action :set_locale
  before_action :require_login

  before_action :set_raven_context
  after_action :verify_authorized, except: :index
  after_action :verify_policy_scoped, only: :index

  include SetCurrentRequestDetails
  before_action :redirect_accountless

  private

  def require_login
    if !masquerading? && remembered_user = remember("user")
      sign_in(remembered_user)
    end
    super
  end

  def redirect_accountless
    if Current.user && Current.account.nil?
      redirect_to accountless_user_path
    end
  end

  def signed_in_as_admin?
    signed_in? && current_user.admin?
  end
  helper_method :signed_in_as_admin?

  # Ensure that all url helpers include the current locale
  def default_url_options
    super.merge(locale: I18n.locale) # Use merge to avoid clobbering any options set during config
  end

  # Set the locale for the current request
  def set_locale
    I18n.locale = params[:locale] || request.env["rack.locale"] || I18n.default_locale
  end

  # Run authorization against Current.user which will ensure it works in async jobs and channels as well
  # All authorization depends on the Current.account as users will have a different role for each
  def pundit_user
    UserContext.new(Current.user, Current.account)
  end

  # Set the context for Sentry exception handling service
  def set_raven_context
    account_id = (session[:active_account] || try(:current_user).try(:accounts).try(:first))
    Raven.user_context(id: current_user.id, account_id: account_id) if signed_in?
    Raven.extra_context(params: params.to_unsafe_h, url: request.url)
  end

  def disable_browser_page_caching
    response.headers["Cache-Control"] = "no-cache, no-store"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "0"
  end

  def masquerading?
    session[:admin_id].present?
  end
  helper_method :masquerading?
end
