class Projecao::ReceitaDoCalculoDeProjecao < ApplicationRecord
	has_paper_trail

	belongs_to :calculo_de_projecao, class_name: 'Projecao::CalculoDeProjecao', required: true
	belongs_to :receita, class_name: 'Projecao::Receita'

	has_one :calculo_por_exercicio, dependent: :destroy

	validates_presence_of :calculo_de_projecao_id, :receita_id

	validates_uniqueness_of :receita_id, scope: :calculo_de_projecao_id

	after_create :cria_calculo_por_exercicio_de_projecao

	validate :receita_tem_valor_base_definido

	def atualiza_total_do_calculo_por_exercicio
		total_do_calculo_de_exercicio_base = calculo_exercicio_base( self.calculo_de_projecao.exercicio_base, self.receita_id).total.to_f
		total_atualizado = total_do_calculo_de_projecao( total_do_calculo_de_exercicio_base, percentual_dos_indices )
		self.calculo_por_exercicio.update( total: total_atualizado )
	end

	def valor_calculado_da_receita
		return self.calculo_por_exercicio.present? ? self.calculo_por_exercicio.total.to_f : 0.00
	end

	def valor_base_da_receita
		return calculo_exercicio_base( self.calculo_de_projecao.exercicio_base, self.receita_id ).present? ? calculo_exercicio_base( self.calculo_de_projecao.exercicio_base, self.receita_id).total.to_f : 0.00
	end

	def exercicio
		return try(:calculo_por_exercicio).try(:exercicio)
	end

	private
	def cria_calculo_por_exercicio_de_projecao
		if calculo_exercicio_base( self.calculo_de_projecao.exercicio_base, self.receita_id).present? && self.calculo_de_projecao.indices_do_calculo_de_projecao.present?
			total_do_calculo_de_exercicio_base = calculo_exercicio_base( self.calculo_de_projecao.exercicio_base, self.receita_id).total.to_f
			total = total_do_calculo_de_projecao( total_do_calculo_de_exercicio_base, percentual_dos_indices )
			Projecao::CalculoPorExercicio.create!( exercicio: self.calculo_de_projecao.exercicio_destino, tipo: 'projetado', receita_do_calculo_de_projecao_id: self.id, total: total )
		end
	end

	def total_do_calculo_de_projecao total_do_calculo_de_exercicio_base, percentual_dos_indices
		return (((total_do_calculo_de_exercicio_base * percentual_dos_indices) / 100 ) + total_do_calculo_de_exercicio_base).to_f
	end

	def calculo_exercicio_base exercicio, receita_id
		if exercicio == exercicio_corrente
			return Projecao::CalculoPorExercicio.revisado.find_by( exercicio: exercicio, receita_id: receita_id )
		elsif exercicios_base.include?(exercicio) || (exercicios_destino.first == exercicio && projecao_pertence_a_orcamento?)
			return Projecao::CalculoPorExercicio.find_by( exercicio: exercicio, receita_id: receita_id )
		elsif exercicios_destino.include?(exercicio)
			receita_do_calculo_de_projecao = self.receita.receitas_dos_calculos_de_projecao.find{|rc| rc.exercicio.eql?(exercicio)}
			if receita_do_calculo_de_projecao
				return Projecao::CalculoPorExercicio.find_by( exercicio: exercicio, receita_do_calculo_de_projecao_id: receita_do_calculo_de_projecao.id )
			else
				return nil
			end
		end
	end

	def percentual_dos_indices
		return self.calculo_de_projecao.percentual_dos_indices
	end

	def exercicios_base
		return self.calculo_de_projecao.projecao_de_receita.exercicios_base
	end

	def exercicio_corrente
		return self.calculo_de_projecao.projecao_de_receita.exercicio_corrente
	end

	def exercicios_destino
		return self.calculo_de_projecao.projecao_de_receita.exercicios_destino
	end

	def projecao_pertence_a_orcamento?
		self.calculo_de_projecao.projecao_de_receita.pertence_a_orcamento?
	end

	def receita_tem_valor_base_definido
		unless self.calculo_de_projecao && self.receita_id && calculo_exercicio_base(self.calculo_de_projecao.exercicio_base, self.receita_id)
			errors.add(:receita_id, "não está projetada para o ano base dessa projeção.")
		end
	end
end
