module BaseController
  module Devise
    extend ActiveSupport::Concern

    included do
      # This is a 'closed' application, be sure that visitors are logged in.
      before_action :require_login

      # Save Datetime of the last request.
      # This is usefull to know which users are currently logged.
      before_action :save_last_request_at

      # Configure Devise strong parameters when needed
      before_action :configure_permitted_parameters, if: :devise_controller?

      # Make controller method available in views
      helper_method :current_site_user
    end


    # This method is a more explicit shortcut for Devise #authenticate_user! method.
    # See https://github.com/plataformatec/devise for more infos.
    def require_login
      authenticate_user!
    end


    # This method is called in the Admin section of the application.
    # First we need to check if the visitor is logged.
    # If not, Devise will authenticate the user and will redirect him
    # to the desired page in the Admin section.
    # At that time this method will be triggered a second time and then
    # we will check if the visitor has the rights to access to the Admin section.
    def require_admin
      return unless require_login
      render_403 unless policy(:admin_zone).show?
    end


    # Define our own method to retrieve the current user in session.
    # The #current_user method is a Devise method to get the current user in session.
    # If the visitor is logged, Devise returns an instance of the User model,
    # else it returns nil. This is not very handy in views where we always have to
    # check to if the current_user is nil or not.
    #
    # To bypass this, use #current_site_user when you need to access to the current user.
    # This method will return an instance of the User model if the visitor is logged or
    # an instance of AnonymousUser if the visitor is not logged (instead of returning nil).
    # Thus you can do this :
    #
    #     current_site_user.logged? => true if current_site_user is an instance of User
    #     current_site_user.logged? => false if current_site_user is an instance of AnonymousUser
    #
    def current_site_user
      current_user || anonymous_user
    end


    # Return an instance of AnonymousUser
    def anonymous_user
      User.anonymous
    end


    # Override Pundit method to return our own crafted user,
    # otherwise Pundit uses #current_user method
    def pundit_user
      current_site_user
    end


    # Save Datetime of the last request.
    # This is usefull to know which users are currently logged.
    def save_last_request_at
      if current_site_user.logged?
        last_request_at = user_session['last_request_at']

        if last_request_at.is_a? Integer
          last_request_at = Time.at(last_request_at).utc
        elsif last_request_at.is_a? String
          last_request_at = Time.parse(last_request_at)
        end

        current_site_user.update_attribute(:last_request_at, last_request_at)
      end
    end


    protected


      def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:login, keys: [:email, :password, :remember_me])
        devise_parameter_sanitizer.permit(:account_update, keys: [:current_password, :password, :password_confirmation])
        # devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :password, :password_confirmation])
      end

  end
end
