class Licitacao::ItemDaAta < ApplicationRecord
	has_paper_trail

	belongs_to :item_do_lote, class_name: 'Licitacao::ItemDoLote', required: true
	belongs_to :ata_de_registro_de_precos, class_name: "Licitacao::AtaDeRegistroDePrecos", foreign_key: :ata_de_registro_de_preco_id, required: true

	delegate :item, :item_do_pedido, :preco_unitario, :quantidade_contratada, to: :item_do_lote

	delegate :unidades_orcamentarias, :valor_contratado_sem_aditivos, :itens_do_aditivo_da_ata, to: :ata_de_registro_de_precos
	has_one :lote, through: :item_do_lote
	has_one :ganhador, through: :lote

	validates_uniqueness_of :item_do_lote_id, scope: :ata_de_registro_de_preco_id, if: Proc.new{ self.persisted? }

	scope :dos_lotes_ativos, -> { joins(item_do_lote: :lote).merge(Licitacao::ItemDoLote.ativos).merge(Licitacao::Lote.ativo) }

	def pode_ser_deletado?
		ata_de_registro_de_precos.itens_dos_contratos.find_by(item_do_lote_id: self.item_do_lote_id).blank?
	end

	def valor_por_unidade_da_ata_sem_aditivo
		return preco_unitario if  (item_do_pedido.por_preco? && !item_do_pedido.por_valor_previsto?)

		unidades_orcamentarias.inject(0) do |valor, unidade_orcamentaria|
			valor + item_do_pedido.valor_previsto_por_unidade_orcamentaria(unidade_orcamentaria.id) if item_do_lote.lote.ativo?
		end
	end

	def valor_por_unidade_da_ata
		reajustes_acrescimo = itens_do_aditivo_da_ata.joins(:aditivo_da_ata).where(item_do_lote: item_do_lote).where(licitacao_aditivos_da_ata: { status: 1, modalidade: Licitacao::AditivoDaAta.modalidades["reajuste_de_valor_acrescimo"] })
		reajustes_decrescimo = itens_do_aditivo_da_ata.joins(:aditivo_da_ata).where(item_do_lote: item_do_lote).where(licitacao_aditivos_da_ata: { status: 1,modalidade: Licitacao::AditivoDaAta.modalidades["reajuste_de_valor_decrescimo"] })

		if reajustes_acrescimo.any? || reajustes_decrescimo.any?
			if item_do_pedido.por_valor_previsto?
				unidades_orcamentarias.inject(0) do |valor, unidade_orcamentaria|
					(valor + item_do_pedido.valor_previsto_por_unidade_orcamentaria(unidade_orcamentaria.id)) + reajustes_acrescimo.sum(:valor_adicionado) - reajustes_decrescimo.sum(:valor_adicionado) if item_do_lote.lote.ativo?
				end
			else
				(preco_unitario + reajustes_acrescimo.sum(:valor_adicionado) - reajustes_decrescimo.sum(:valor_adicionado)).to_f
			end
		else
			return preco_unitario if  (item_do_pedido.por_preco? && !item_do_pedido.por_valor_previsto?)

			unidades_orcamentarias.inject(0) do |valor, unidade_orcamentaria|
				valor + item_do_pedido.valor_previsto_por_unidade_orcamentaria(unidade_orcamentaria.id) if item_do_lote.lote.ativo?
			end
		end
	end

	def valor_de_cada_unidade_por_desconto(unidade_orcamentaria_id)
		item_do_pedido.valor_previsto_por_unidade_orcamentaria(unidade_orcamentaria_id) if item_do_lote.lote.ativo?
	end

	def quantidade_por_unidade_da_ata
		ata_de_registro_de_precos.unidades_orcamentarias.inject(0) do |quantidade, unidade_orcamentaria|
			quantidade + item_do_pedido.quantidade_por_unidade_orcamentaria(unidade_orcamentaria.id) if item_do_lote.lote.ativo?
		end
	end

	def valor_a_contratar_por_unidade(unidade_orcamentaria_id)
		saldo = item_do_lote.saldo_por_unidade(unidade_orcamentaria_id)
		if self.ata_de_registro_de_precos.contratos_com_discriminacao_de_itens?
			saldo * valor_por_unidade_da_ata
		elsif self.ata_de_registro_de_precos.por_valor_previsto?
			valor_a_total_por_unidade(unidade_orcamentaria_id) - valor_contratado_por_unidade(unidade_orcamentaria_id)
		else
			valor_a_total_por_unidade(unidade_orcamentaria_id) - valor_contratado.round(2)
		end
	end

	def valor_contratado
		ata_de_registro_de_precos.itens_dos_contratos.where(item_do_lote_id: item_do_lote.id).inject(0) do |valor, item_do_contrato|
				valor + item_do_contrato.valor_total if item_do_lote.lote.ativo?
		end
	end

	def valor_contratado_por_unidade(unidade_orcamentaria_id)
		contratos_da_unidade = self.ata_de_registro_de_precos.contratos.joins(:unidade_orcamentaria_por_pedido).where("licitacao_unidades_orcamentarias_por_pedido.unidade_orcamentaria_id = ?", unidade_orcamentaria_id).sum(&:valor)
	end

	def valor_a_total_por_unidade(unidade_orcamentaria_id)
		if self.ata_de_registro_de_precos.por_valor_previsto?
			pedido_id = item_do_pedido.pedido.id
			unidade_por_pedido = Licitacao::UnidadeOrcamentariaPorPedido.find_by(unidade_orcamentaria_id: unidade_orcamentaria_id, pedido_id: pedido_id)
			valor = unidade_por_pedido.valor_previsto_de_itens
		else
			quantidade = item_do_pedido.quantidade_por_unidade_orcamentaria_sem_periodicidade(unidade_orcamentaria_id)
			quantidade * valor_por_unidade_da_ata
		end
	end

	def saldo
		(quantidade_por_unidade_da_ata.to_f - quantidade_contratada.to_f).round(2)
	end

	def saldo_em_porcentagem
		return 0 if quantidade_por_unidade_da_ata <= 0

		(saldo / quantidade_por_unidade_da_ata) * 100
	end

	def valor_total_por_unidade_sem_aditivos
		return valor_por_unidade_da_ata_sem_aditivo.to_f.round(2) if item_do_lote.item_do_pedido.por_valor_previsto? || !ata_de_registro_de_precos.contratos_com_discriminacao_de_itens?

		(quantidade_por_unidade_da_ata.to_f * valor_por_unidade_da_ata_sem_aditivo.to_f).round(2)
	end

	def valor_total_por_unidade
		return valor_por_unidade_da_ata.to_f.round(2) if ( item_do_pedido.por_desconto? || item_do_pedido.por_valor_previsto? ) || !ata_de_registro_de_precos.contratos_com_discriminacao_de_itens?

		(quantidade_por_unidade_da_ata.to_f * valor_por_unidade_da_ata.to_f).round(2)
	end

	def valor_a_contratar
		if !ata_de_registro_de_precos.contratos_com_discriminacao_de_itens?
			valor_por_unidade_da_ata - valor_contratado.round(2)
		elsif item_do_pedido.por_valor_previsto?
			(valor_por_unidade_da_ata - valor_contratado_sem_aditivos).round(2)
		else
			(saldo * valor_por_unidade_da_ata).round(2)
		end
	end

	def valor_a_contratar_em_porcentagem
		return 0 if valor_total_por_unidade <= 0

		(valor_a_contratar / valor_total_por_unidade) * 100
	end
end
