require 'active_support/concern'

module SeedNaturezasDaReceitaIniciais extend ActiveSupport::Concern
	def cria_naturezas_da_receita_iniciais(copiar_do_orcamento_anterior = true)
		unless Rails.env.test?
			id_fiscal = self.tipos_de_orcamento.find_by(codigo: 'F').id
			id_social = self.tipos_de_orcamento.find_by(codigo: 'S').id

			orcamento_anterior = Orcamento.find_by(exercicio: self.exercicio - 1)
			receitas_stn = self.receitas_stn.index_by(&:codigo)

			
			if copiar_do_orcamento_anterior == false
				if self.exercicio.to_i >= 2022
					array = ActiveSupport::JSON.decode(File.read("db/data_seeds/base/naturezas_da_receita/2022b.json"))
					
					puts "Importando naturezas da receita..."
					array.each {|natureza|
						atributos = natureza
						# tipo de orcamento no arquivo -> fiscal = 39 e social = 40
						atributos["tipo_de_orcamento_id"] = natureza["tipo_de_orcamento_id"] == "40" ? id_social : id_fiscal

						codigo_stn = natureza["codigo"][0..7]
						receita_stn = receitas_stn[codigo_stn]
						if receita_stn.present?
							atributos["receita_stn_id"] = receita_stn.id
						end					
						atributos["padrao"] = true
						atributos["codigo"] = natureza["codigo"].rjust(16, '0')
						atributos["modulo_id"] = self.id
						atributos["modulo_type"] = "Orcamento"
						receita = self.naturezas_da_receita.build(atributos.except("id"))
						receita.save(validate: false)
					}
				else
					array = ActiveSupport::JSON.decode(File.read("db/data_seeds/base/naturezas_da_receita/2018.json"))

					array.each {|natureza|
						natureza["tipo_de_orcamento_id"] = natureza["tipo_de_orcamento_id"] == "social" ? id_social : id_fiscal

						natureza_ja_importada = self.naturezas_da_receita.find_by(codigo: natureza["codigo"])
						if natureza_ja_importada
							natureza_ja_importada.update(natureza.slice("sigla", "tipo_de_orcamento", "tipo_de_receita", "legislacao_da_receita", "historico_padrao"))
						else
							# a pedido da consultoria, as naturezas da receita devem ser iguais ao do exercicio anterior, caso tenha exercicio anterior
							if orcamento_anterior.nil? || (orcamento_anterior.present? && orcamento_anterior.naturezas_da_receita.find_by(codigo: natureza["codigo"]).present?)

								atributos = natureza
								codigo_stn = natureza["codigo"][2..9]
								receita_stn = receitas_stn[codigo_stn]
								atributos["modulo_id"] = self.id
								atributos["modulo_type"] = "Orcamento"
								atributos["tipo_de_deducao_id"] = self.tipos_de_deducao.find_by(codigo: '00').id
								if natureza["codigo"][0] == '9'
									receita = self.naturezas_da_receita.build(natureza.except("tipo_de_deducao", "Fonte", "percentual", "criar_receita_intra"))
									receita.save
								else
									if receita_stn
										if natureza["codigo"][-6..-1].to_i > 0 #opcional, cria direto do hash
											receita = self.naturezas_da_receita.build(natureza.except("tipo_de_deducao", "Fonte", "percentual", "criar_receita_intra"))
											receita.save! unless receita.nivel_pai && receita.nivel_pai.valor_previsto?
										else
											tipo_de_deducao = natureza["tipo_de_deducao"]
											atributos["receita_stn_id"] = receita_stn.id
											atributos["padrao"] = true
											receita_stn.gerar_natureza_da_receita(atributos.except("tipo_de_deducao", "Fonte",
												"percentual", "codigo", "descricao", "criar_receita_intra", "sigla"), true, tipo_de_deducao)

										end
									end
								end
							end
						end
					}

				end
			end

			if orcamento_anterior.present? && copiar_do_orcamento_anterior == true
			# COPIA A PARTIR DO ORÇAMENTO ANTERIOR
				orcamento_anterior.naturezas_da_receita.each do |natureza_da_receita_anterior|
					if self.naturezas_da_receita.find_by(codigo: natureza_da_receita_anterior.codigo).nil?
						natureza_da_receita_anterior.dup.tap do |nova_receita|
							nova_receita.modulo = self
							nova_receita.tipo_de_orcamento_id = self.tipos_de_orcamento.find_by(codigo: natureza_da_receita_anterior.tipo_de_orcamento.try(:codigo)).id
							nova_receita.receita_stn = receitas_stn[natureza_da_receita_anterior.receita_stn.try(:codigo)]
							nova_receita.forma_de_adicao = :original
							nova_receita.valor_previsto = 0
							nova_receita.save(validate: false)
						end
					end
				end
			end

		end
	end

	def importa_valores_das_receitas_do_orcamento_anterior
		begin
			orcamento_anterior = Orcamento.find_by_exercicio(self.exercicio - 1)
			fontes_de_recursos = self.fontes_de_recursos.index_by(&:codigo_completo)

			puts "Importando valores das receitas do exercício anterior..."
			self.naturezas_da_receita.each do |natureza_da_receita|

				# atualiza receita_stn_id
				receita_stn = self.receitas_stn.find_by(codigo: natureza_da_receita.codigo[2..9])
				natureza_da_receita.update_column(:receita_stn_id, receita_stn.id) if receita_stn.present? && natureza_da_receita.receita_stn_id.nil?

				natureza_da_receita_do_exercicio_anterior = orcamento_anterior.naturezas_da_receita.find_by(codigo: natureza_da_receita.codigo)

				if natureza_da_receita_do_exercicio_anterior.present?

					natureza_da_receita_do_exercicio_anterior.unidades_orcamentarias_por_natureza_da_receita.each do |unidade_orcamentaria_por_natureza_da_receita_do_exercicio_anterior|
						unidade_orcamentaria_do_exercicio_anterior = unidade_orcamentaria_por_natureza_da_receita_do_exercicio_anterior.unidade_orcamentaria

						unidade_orcamentaria = self.unidades_orcamentarias.joins(:orgao)
							.where("loa_orgaos.codigo = ? and loa_unidades_orcamentarias.codigo = ?", unidade_orcamentaria_do_exercicio_anterior.orgao.codigo, unidade_orcamentaria_do_exercicio_anterior.codigo).first

						unidade_orcamentaria_por_natureza_da_receita = natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.first_or_create(
							unidade_orcamentaria: unidade_orcamentaria,
							status_do_orcamento: :aberto,
							forma_de_adicao: :original
						)

						if unidade_orcamentaria_por_natureza_da_receita.persisted?

							unidade_orcamentaria_por_natureza_da_receita_do_exercicio_anterior.orcamentos_da_receita.each do |orcamento_da_receita_do_exercicio_anterior|
								fonte = fontes_de_recursos[orcamento_da_receita_do_exercicio_anterior.fonte_de_recursos.codigo_completo]

								orcamento_da_receita = unidade_orcamentaria_por_natureza_da_receita.orcamentos_da_receita.find_by(
									fonte_de_recursos: fonte,
									valor: 0,
									valor_arrecadado: 0,
									status_do_orcamento: :aberto,
									arquivo_id: nil,
									valor_atual: 0,
									forma_de_adicao: :original
								)

								unless orcamento_da_receita.present?
									orcamento_da_receita = unidade_orcamentaria_por_natureza_da_receita.orcamentos_da_receita.new(
										fonte_de_recursos: fonte,
										valor: 0,
										valor_arrecadado: 0,
										status_do_orcamento: :aberto,
										arquivo_id: nil,
										valor_atual: 0,
										forma_de_adicao: :original
									)
									orcamento_da_receita.save(validate: false)
								end

							end
						end
					end

				end
			end
		rescue => exception
			puts exception.record
			raise ActiveRecord::Rollback
		end
	end
end
