class Acesso::Controle < ApplicationRecord
  belongs_to :modulo
  has_many :acoes
	has_many :permissoes

	attr_default :acesso_de_modulo, false

	after_create :gera_permissao_por_perfil
	after_destroy :apaga_permissoes_dos_perfis

	def gera_permissao_por_perfil
		Perfil.all.each do |perfil|
			permissao = self.permissoes.find_or_create_by(perfil: perfil)
		end
	end

	def apaga_permissoes_dos_perfis
		Acesso::Permissao.where(controle_id: self.id).delete_all
	end

	def gera_permissoes_crud acoes = {}
		acoes_extra = acoes[:acoes_extra] || []
		acoes_removidas = acoes[:except] || []
		acoes_incluidas = acoes[:only] || []
		exclui_crud = acoes[:exclui_crud]

		raise ArgumentError, 'hash de ações extra está inválido' unless acoes_extra.empty? || acoes_extra.map(&:keys).flatten.to_set == [:nome_da_acao, :nome_de_exibicao].to_set

		raise ArgumentError, 'não pode conter :except e :only na mesma chamada' if acoes_removidas.any? && acoes_incluidas.any?

		acoes_padrao = [
		{ nome_da_acao: "read", nome_de_exibicao: "Visualizar" },
		{ nome_da_acao: "update", nome_de_exibicao: "Editar" },
		{ nome_da_acao: "create", nome_de_exibicao: "Cadastrar" },
		{ nome_da_acao: "destroy", nome_de_exibicao: "Remover" }]

		acoes_crud = if exclui_crud
			[]
		elsif acoes_removidas.any?
			acoes_padrao.reject {|acao| acoes_removidas.include?(acao[:nome_da_acao])}
		elsif acoes_incluidas.any?
			acoes_padrao.select {|acao| acoes_incluidas.include?(acao[:nome_da_acao])}
		else
			acoes_padrao
		end


		(acoes_crud + acoes_extra).each do |acao|
			self.acoes.find_or_create_by!(acao)
		end

		self
	end
end
