# app/models/perfil_acesso.rb
#
# O conjunto de permissões que o ADM monta na tela e atribui a um usuário.
# O catálogo do que PODE ser marcado é código (Permissao::TODAS); aqui fica só a
# escolha do ADM.
class PerfilAcesso < ApplicationRecord
  # Nome da tabela fixado: o Inflector pt-BR resolveria `perfil_acesso` como
  # "perfil_acessos" (mesma pegadinha de ConsolidacaoMotorista e das tabelas de
  # notificação). A tabela real é `perfis_acesso`.
  self.table_name = 'perfis_acesso'

  has_many :users, foreign_key: :perfil_acesso_id, dependent: :nullify, inverse_of: :perfil_acesso

  validates :nome, presence: true
  validates :nome, uniqueness: { case_sensitive: false }

  before_validation :normalizar_permissoes

  scope :ativos,     -> { where(ativo: true) }
  scope :ordenados,  -> { order(Arel.sql('LOWER(nome)')) }
  scope :de_sistema, -> { where(sistema: true) }

  # Chaves que ainda existem no catálogo. Uma permissão removida do código não
  # pode travar um perfil salvo meses atrás — ela simplesmente deixa de valer.
  def permissoes_validas
    Permissao.filtrar(permissoes)
  end

  def pode?(chave)
    permissoes_validas.include?(chave.to_s)
  end

  # Perfil de sistema é editável e desativável, mas não apagável (apagar deixaria
  # usuários órfãos e a tela sem ponto de partida). Perfil em uso também não sai:
  # o usuário cairia no fallback do papel sem ninguém perceber.
  def apagavel?
    !sistema? && users.none?
  end

  # Este perfil ainda consegue reabrir a porta do sistema? É o que a trava do
  # último administrador pergunta antes de deixar salvar.
  def administra_acesso?
    ativo? && pode?('admin.perfis') && pode?('admin.usuarios_gerenciar')
  end

  def total_permissoes
    permissoes_validas.size
  end

  # Um perfil que não enxerga nada existe (é uma forma de suspender acesso sem
  # desativar a conta), mas a tela precisa avisar.
  def vazio?
    permissoes_validas.empty?
  end

  private

  def normalizar_permissoes
    self.nome = nome.to_s.strip
    self.permissoes = Permissao.filtrar(permissoes)
  end
end
