class User < ApplicationRecord
  rolify
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable,
         :recoverable,
         :rememberable,
         :trackable
         # :validatable,
         # :confirmable,
         # :lockable

  scope :without_admin_role, -> { joins(:roles).where("roles.name != ?", "admin") }
  scope :by_institution, -> (institution_ids) { joins(:institutions).where(institutions: {id: institution_ids}) }
  scope :by_branch, -> (branch_ids) { joins(:branches).where(branches: {id: branch_ids}) }
  scope :by_administrative_area, -> (area) { where(administrative_area: area) }

  has_and_belongs_to_many :institutions
  has_and_belongs_to_many :branches

  has_many :expedients, :dependent => :restrict_with_error
  has_one :admin_setting

  validates :name, presence: true

  validates :email, presence: true
  validates :email,
            uniqueness: { case_sensitive: false },
            if: proc { |o| o.email.present? }

  validates :email,
            format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i },
            if: proc { |o| o.email.present? }

  validates :password,
            presence: true,
            confirmation: true,
            on: :create

  validates :password,
            presence: true,
            confirmation: true,
            if: proc { |o| o.password.present? },
            on: :update

  validates :administrative_area, presence: true, if: Proc.new { |u| u.has_role?(:administrative_unit) }

  before_save :ensure_authentication_token

  def one_institution?
    institutions.count == 1
  end

  def one_branch?
    institutions.count == 1
  end

  def uniq_institution
    return nil unless one_institution?
    institutions.try(:first)
  end

  def uniq_branch
    return nil unless one_branch?
    branches.try(:first)
  end

  def admin?
    has_role? :admin
  end

  def roles_name_s
    roles_name.map{|i| I18n.t(i, scope: 'activerecord.enum.user.role')}.to_sentence
  end

  def institutions_name
    institutions.pluck(:name).to_sentence
  end

  def branches_name
    branches.pluck(:name).to_sentence
  end

  def ensure_authentication_token
    if authentication_token.blank?
      self.authentication_token = generate_authentication_token
    end
  end

  private

  def generate_authentication_token
    loop do
      token = Devise.friendly_token
      break token unless User.where(authentication_token: token).first
    end
  end
end
