module RequisicaoDeRelatorioConcern
	extend ActiveSupport::Concern

	def executar_relatorio_em_segundo_plano
		return if Rails.env.development?

		lista_de_controllers = ['contabilidade/relatorios_da_contabilidade', 'contabilidade/relatorios/balancetes_de_verificacoes', 'contabilidade/relatorios/lei_de_financas']
		
		if controller_path == 'contabilidade/relatorios_da_contabilidade' && 
			params[:tableless_relatorio_da_contabilidade].present? &&
			["saldo_inicial_das_contas_por_unidade", "saldo_das_contas_por_unidade", "saldo_de_restos_a_pagar"].include?(params[:tableless_relatorio_da_contabilidade][:relatorio])
			return
		end
	
		if lista_de_controllers.include?(controller_path) && action_name != 'selecionar_relatorio'
			if params[:processar].present? && params[:processar] == 'true'
				if params[:token].present?
					requisicao_de_relatorio = RequisicaoDeRelatorio.where(token: params[:token]).first
					if requisicao_de_relatorio.present?
						sign_in(requisicao_de_relatorio.usuario)
						session[:contexto_tipo] = params[:contexto_tipo] || "Contabilidade"
						session[:contexto_id] = params[:contexto_id]
						Thread.current[:contexto_atual] = Orcamento.find(params[:contexto_id])
					end
				end
			else
				if params.include?(:tableless_relatorio_da_contabilidade)
					extrair_parametros_de = :tableless_relatorio_da_contabilidade
				end
	
				if RequisicaoDeRelatorio.where(status: [:pendente, :em_processamento], usuario_id: current_usuario.id).exists?(url: request.url)
					redirect_to requisicoes_de_relatorios_path, alert: "Você já solicitou um relatório igual a este, aguarde o processamento."
				elsif RequisicaoDeRelatorio.where(status: [:pendente, :em_processamento], usuario_id: current_usuario.id).size >= 5
					redirect_to requisicoes_de_relatorios_path, alert: "O limite de processamento de relatórios por usuário é de 5. Aguarde a conclusão de pelo menos um dos outros relatórios em processamento para adicionar outro."
				else
					token = SecureRandom.hex(10)
					parametros = extrair_parametros_de.nil? ? params.permit!.to_h.to_json.gsub("\",\"", "\" , \"").gsub("\":\"", "\" : \"") : params[extrair_parametros_de].permit!.to_h.to_json.gsub("\",\"", "\" , \"").gsub("\":\"", "\" : \"")
					titulo_do_relatorio = find_param_value(params, :relatorio)
					RequisicaoDeRelatorio.create!(usuario_id: current_usuario.id, url: request.url, status: :pendente, titulo: titulo_do_relatorio, parametros: parametros, contexto_id: contexto_atual.id, contexto_tipo: session[:contexto_tipo], token: token)
					
					redirect_to requisicoes_de_relatorios_path 
				end
			end
		end
	end	

	def find_param_value(params, key)
		# Converte para hash caso seja ActionController::Parameters
		params = params.to_unsafe_h if params.is_a?(ActionController::Parameters)

		# Verifica cada chave do hash
		params.each do |k, v|
			# Retorna o valor se a chave for encontrada
			return v if k.to_s == key.to_s

			# Se o valor também for um hash, chama recursivamente
			if v.is_a?(Hash)
				found = find_param_value(v, key)
				return found if found
			end
		end
		nil
	end

end