class Contabilidade::LancamentoExtraorcamentarioReceita < ApplicationRecord
	has_paper_trail

	attr_default :ordem_para_grid_razao, 1
	attr_accessor :ordem_para_grid_razao

	belongs_to :conta_extra_orcamentaria, class_name: 'Contabilidade::ContaExtraOrcamentaria', required: true
	belongs_to :modulo, polymorphic: true, required: true

	validates_presence_of :conta_extra_orcamentaria_id, :data_do_lancamento, :valor, :modulo_id, :modulo_type
	validates_numericality_of :valor

	validates :modulo_id, immutable: true
	validates :modulo_type, immutable: true

	validates :data_do_lancamento, date: true

	validate :valor_nao_passar_do_talao, if: Proc.new { self.modulo_type == "Contabilidade::TalaoDeReceita" && self.modulo&.orcamentario? }

	after_save :atualizar_saldo_inicial_dos_exercicios_posteriores
	after_destroy :atualizar_saldo_inicial_dos_exercicios_posteriores

	def valor_nao_passar_do_talao
		valor_total_lancamentos = Contabilidade::LancamentoExtraorcamentarioReceita.where(modulo_type: "Contabilidade::TalaoDeReceita", modulo_id: self.modulo.id).sum(:valor).to_d
		errors.add(:valor, "O valor não pode ser maior que o valor do talão ") if (self.valor.to_d + valor_total_lancamentos) > modulo.saldo
	end

	def unidade_orcamentaria
		case self.modulo_type
		when "Contabilidade::TalaoDeReceita"
			self.modulo.unidade_orcamentaria
		when "Contabilidade::AnulacaoDoTalaoDeReceita"
			self.modulo.talao_de_receita.unidade_orcamentaria
		else
			""
		end
	end

	def referente_a
		case self.modulo_type
		when "Contabilidade::TalaoDeReceita"
			"Lançamento do Talão de Receita \##{self.modulo.try(:numero_do_talao)}"
		when "Contabilidade::AnulacaoDoTalaoDeReceita"
			"Anulação #{self.modulo.try(:tipo_de_anulacao).try(:humanize)} do Talão de Receita \##{self.modulo.try(:talao_de_receita).try(:numero_do_talao)}"
		else
			""
		end
	end

	def numero_talao
		case self.modulo_type
		when "Contabilidade::TalaoDeReceita"
			" TL - #{self.modulo.try(:numero_do_talao)}"
		when "Contabilidade::AnulacaoDoTalaoDeReceita"
			" ATL -#{self.modulo.try(:tipo_de_anulacao).try(:humanize)} do Talão de Receita \##{self.modulo.try(:talao_de_receita).try(:numero_do_talao)} "
		end
	end
	
	def historico_talao
		case self.modulo_type
		when "Contabilidade::TalaoDeReceita"
			if (self.modulo.pagamento.present?)
				"#{self.modulo.try(:pagamento).try(:historico) + unidade_orcamentaria.try(:sigla)}"
			else
				"#{self.modulo.try(:historico)}"
			end	
		when "Contabilidade::AnulacaoDoTalaoDeReceita"
			"#{self.modulo.try(:talao_de_receita).try(:numero_do_talao)}"
		end	
	end
	

	def atualizar_saldo_inicial_dos_exercicios_posteriores
		# atualiza o saldo_inicial do próximo exercicio quando houver alteração de movimentação no exercicio anterior
		maior_exercicio = Orcamento.order("exercicio").last&.exercicio
		proximo_orcamento_exercicio = contexto_atual.exercicio.to_i + 1

		if maior_exercicio.to_i > 0 && maior_exercicio.to_i > contexto_atual.exercicio # só executar se existir novos orçamentos
			for i in proximo_orcamento_exercicio..maior_exercicio
				# orcamento a ser atualizado
				proximo_orcamento = Orcamento.find_by(exercicio: i)
				# orcamento com movimentacação realizada
				orcamento = Orcamento.find_by(exercicio: proximo_orcamento_exercicio - 1)
				# pesquisa movimentacao inicial

				# dados do exercicio atual
				unidade_orcamentaria_do_exercicio = orcamento.unidades_orcamentarias.where("loa_unidades_orcamentarias.codigo = ? and loa_orgaos.codigo = ?", self.unidade_orcamentaria&.codigo, self.unidade_orcamentaria&.orgao&.codigo).first
				conta_extra_orcamentaria_do_exercicio = orcamento.contas_extra_orcamentarias.where(codigo: self.conta_extra_orcamentaria&.codigo).first
				conta_extra_por_unidade_orcamentaria_do_exercicio = conta_extra_orcamentaria_do_exercicio.contas_extra_por_unidades_orcamentarias.where(unidade_orcamentaria_id: unidade_orcamentaria_do_exercicio.id).first rescue nil
				
				# dados do exercicio a ser atualizado (posterior)
				unidade_orcamentaria_do_proximo_exercicio = proximo_orcamento.unidades_orcamentarias.where("loa_unidades_orcamentarias.codigo = ? and loa_orgaos.codigo = ?", self.unidade_orcamentaria&.codigo, self.unidade_orcamentaria&.orgao&.codigo).first
				conta_extra_orcamentaria_do_proximo_exercicio = proximo_orcamento.contas_extra_orcamentarias.where(codigo: self.conta_extra_orcamentaria&.codigo).first
				if unidade_orcamentaria_do_proximo_exercicio.present? && conta_extra_orcamentaria_do_proximo_exercicio.present?
					# atualiza saldo inicial
					conta_extra_por_unidade_orcamentaria_do_proximo_exercicio = conta_extra_orcamentaria_do_proximo_exercicio.contas_extra_por_unidades_orcamentarias.where(unidade_orcamentaria_id: unidade_orcamentaria_do_proximo_exercicio.id).first
					if conta_extra_por_unidade_orcamentaria_do_proximo_exercicio.present?
						conta_extra_por_unidade_orcamentaria_do_proximo_exercicio.update_column(:saldo, conta_extra_por_unidade_orcamentaria_do_exercicio.saldo_por_unidade&.to_d) if conta_extra_por_unidade_orcamentaria_do_exercicio.present?
					end
				end
			end
		end
	end
end
