class Contabilidade::SubacaoDaSolicitacao < ApplicationRecord
	has_paper_trail

	belongs_to :solicitacao_de_alteracao_orcamentaria, inverse_of: :subacoes_da_solicitacao
	belongs_to :subacao, class_name: 'Loa::Subacao'

	has_many :elementos_por_subacao_da_solicitacao, class_name: 'Contabilidade::ElementoPorSubacaoDaSolicitacao', dependent: :destroy
	has_many :elementos_de_despesa, through: :elementos_por_subacao_da_solicitacao

	delegate :acao_iniciativa, to: :subacao

	accepts_nested_attributes_for :elementos_por_subacao_da_solicitacao, reject_if: :all_blank, allow_destroy: true

	validates_presence_of :solicitacao_de_alteracao_orcamentaria_id, :subacao_id

	validates_associated :elementos_por_subacao_da_solicitacao

	validates :elementos_por_subacao_da_solicitacao, uniq_nested_attributes: {
		atributo: :elemento_de_despesa_id,
		mensagem: "Elemento de Despesa deve ser único dentro de uma Ação"
	}

	validate :valida_vinculo_com_elemento

	after_save :faz_os_vinculos_no_loa

	private
	def valida_vinculo_com_elemento
		if elementos_por_subacao_da_solicitacao.empty? || elementos_por_subacao_da_solicitacao.all?{ |elemento| elemento.marked_for_destruction? }
			errors.add(:subacao_id, "É preciso vincular no mínimo um Elemento de Despesa por Ação")
		end
	end

	def faz_os_vinculos_no_loa
		elementos_ja_vinculados_ids = subacao.elementos_de_despesa.pluck(:id)
		elementos_por_subacao_da_solicitacao.each do |elemento_por_subacao|
			elemento_de_despesa_id = elemento_por_subacao.elemento_de_despesa_id
			# Só faz o vínculo do elemento se ele não estiver vinculado
			if !elementos_ja_vinculados_ids.include?(elemento_de_despesa_id)
				subacao.elementos_de_despesa_por_subacao.create(
					elemento_de_despesa_id: elemento_de_despesa_id,
					de_credito_adicional: true,
					solicitacao_de_alteracao_orcamentaria_id: self.solicitacao_de_alteracao_orcamentaria_id
				)
			end
			# Faz os vínculos das fontes de cada elemento se ela não estiver vinculada
			elemento_de_despesa_por_subacao = subacao.elementos_de_despesa_por_subacao.find_by(elemento_de_despesa_id: elemento_de_despesa_id)
			fontes_ja_vinculadas_ids = elemento_de_despesa_por_subacao.orcamentos_da_despesa.pluck(:fonte_de_recursos_id)
			elemento_por_subacao.fontes_por_elemento_da_subacao_da_solicitacao.each do |fonte_por_elemento|
				if !fontes_ja_vinculadas_ids.include?(fonte_por_elemento.fonte_de_recursos_id)
					orcamento_a_vincular = elemento_de_despesa_por_subacao.orcamentos_da_despesa.new(
						fonte_de_recursos_id: fonte_por_elemento.fonte_de_recursos.id,
						iduso: fonte_por_elemento.iduso,
						valor: 0,
						valor_empenhado: nil,
						valor_orcado: nil,
						de_credito_adicional: true
					)
					orcamento_a_vincular.save(validate: false)
				end
			end
		end
	end
end
