class Contabilidade::LancamentoExtraorcamentarioDespesa < ApplicationRecord
	has_paper_trail

	attr_default :ordem_para_grid_razao, 2
	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_da_despesa, if: Proc.new {self.modulo_type == "Contabilidade::DespesaExtraOrcamentaria"}

	after_save :atualizar_saldo_inicial_dos_exercicios_posteriores
	after_destroy :atualizar_saldo_inicial_dos_exercicios_posteriores

	def valor_nao_passar_da_despesa
		valor_total_lancamentos = Contabilidade::LancamentoExtraorcamentarioDespesa.where(modulo_type: "Contabilidade::DespesaExtraOrcamentaria", modulo_id: self.modulo.id).sum(:valor)
		errors.add(:valor, "O valor não pode ser maior que o valor da despesa ") if (self.valor.to_d + valor_total_lancamentos.to_d) > modulo.valor_total.to_d
	end

	def referente_a
		case self.modulo_type
		when "Contabilidade::DespesaExtraOrcamentaria"
			"Lançamento da Despesa Extra \##{self.modulo.try(:numero_de_caixa)}"
		when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
			"Estorno da Despesa Extra \##{self.modulo.despesa_extra_orcamentaria.try(:numero_de_caixa)}"
		when "Contabilidade::AnulacaoDaContaExtra"
			"Cancelamento de conta \##{self.modulo.conta_extra_orcamentaria.try(:codigo_completo_e_descricao)}"
		else
			""
		end
	end

	def numero_despesa
		case self.modulo_type
		when "Contabilidade::DespesaExtraOrcamentaria"
			"DP - #{self.modulo.try(:numero_de_caixa)}"
		when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
			"DP - #{self.modulo.try(:numero_de_caixa)}"
		else
			""
		end	
	end

	def historico_despesa
		case self.modulo_type
		when "Contabilidade::DespesaExtraOrcamentaria"
			"#{self.modulo.try(:historico)}"
		when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
			"#{self.modulo.try(:historico)}"
		else
			""
		end	
	end

	def unidade_orcamentaria
		case self.modulo_type
		when "Contabilidade::TalaoDeReceita"
			self.modulo.unidade_orcamentaria.try(:sigla)
		when "Contabilidade::AnulacaoDoTalaoDeReceita"
			self.modulo.talao_de_receita.unidade_orcamentaria
		else
			""
		end
	end
	
	
	def unidade_orcamentaria
		case self.modulo_type
		when "Contabilidade::DespesaExtraOrcamentaria"
			self.modulo.unidade_orcamentaria
		when "Contabilidade::EstornoDeDespesaExtraOrcamentaria"
			self.modulo.despesa_extra_orcamentaria.unidade_orcamentaria
		else
			""
		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
					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
