class GestaoDeEstoque::ItemDoConsumo < ApplicationRecord
  has_paper_trail

	include GeradorDeEventosContabeis

  attr_accessor :enviando_ao_almoxarifado_pelo_patrimonio_attribute
  attr_accessor :quantidade_disponivel_attribute

  belongs_to :consumo, class_name: "GestaoDeEstoque::Consumo"
  belongs_to :estoque, class_name: "GestaoDeEstoque::Estoque"
  belongs_to :item, class_name: "Base::Item"

  has_many :itens_do_consumo_por_escola_e_programas, class_name: "GestaoDeEstoque::ItensDoConsumoPorEscolaEPrograma"
  has_many :setores, class_name: "GestaoDeEstoque::Setor"
  accepts_nested_attributes_for :setores, allow_destroy: true

  validates_presence_of :consumo_id, :estoque_id, :quantidade_consumida
	validates_numericality_of :quantidade_consumida, greater_than: 0
	# validates_uniqueness_of :estoque_id, scope: :consumo_id, message: 'Deve ser único'

  validate :valida_quantidade, if: Proc.new{ self.quantidade_consumida.to_d != self.quantidade_consumida_was.to_d }
  validate :valida_quantidade_em_data_do_consumo, if: Proc.new{ self.quantidade_consumida.to_d != self.quantidade_consumida_was.to_d }

  before_save :atribui_item_id

	enum status_de_reconhecimento:{
		aguardando_reconhecimento: 1,
		reconhecido: 2
	}

	def saldo_atual_do_item
    estoque.quantidade_total_saldo.to_f rescue 0.0
  end
	def saldo_do_item_na_data
    estoque.quantidade_anterior_total(self.consumo.data_de_consumo).to_f rescue 0.0
  end

  def atribui_item_id
    if self.estoque_id.present?
			self.item_id = self.estoque.item_id
			self.unidade_de_medida_id = self.estoque.unidade_de_medida_id
			self.valor_unitario = self.estoque.calcular_valor_medio_por_data_final(self.consumo.data_de_consumo)
			if self.quantidade_consumida.to_i > 0 && self.valor_unitario.to_f > 0
				self.total = (self.valor_unitario * self.quantidade_consumida).to_f
			end
		end
  end

  def adiciona_ou_atualiza_saldo_no_estoque
		begin
			if self.estoque_id.present?
				self.estoque.update_columns(
					saldo_da_ordem_de_compra: saldo_do_estoque
				)
				self.adiciona_movimentacao_no_estoque
			else
				estoque = GestaoDeEstoque::Estoque.new(
					item_id: self.item_id,
					unidade_de_medida_id: self.try(:item).try(:unidade_de_medida).id,
					saldo_da_ordem_de_compra: saldo_do_estoque,
					unidade_orcamentaria_id: self.consumo.unidade_orcamentaria_id,
					almoxarifado_id: self.consumo.almoxarifado_id,
					tipo_de_material: self.estoque.tipo_de_material,
					sub_elemento_de_despesa_id: self.estoque.sub_elemento_de_despesa_id
				)
				self.estoque_id = estoque.id if estoque.save
				self.adiciona_movimentacao_no_estoque
			end
		rescue Exception => e
			raise e
		end
	end

	def adiciona_movimentacao_no_estoque
		begin

			if self.estoque.present? && self.estoque.persisted?
				GestaoDeEstoque::MovimentacaoDoEstoque.create!(
					estoque_id: self.estoque.id,
					quantidade_saida: self.quantidade_consumida.to_f,
					origem_id: self.consumo.id,
					origem_type: self.consumo.class.name,
					orcamento_id: self.consumo.orcamento_id,
					unidade_orcamentaria_id: consumo.unidade_orcamentaria_id,
					almoxarifado_id: consumo.almoxarifado_id,
          valor_unitario: self.valor_unitario,
					valor_total: self.total
				)
				self.desconta_saldo_do_sub_estoque
			end
		rescue Exception => e
			raise e
		end
	end

  def saldo_do_estoque
		total = estoque.quantidade_total_saldo.to_f rescue 0.0
		(total - retorna_quantidade_ou_quantidade_de_conversao.to_f).to_f
	end

  def retorna_quantidade_ou_quantidade_de_conversao
		self.quantidade_consumida
	end

  def desconta_saldo_do_sub_estoque
    quantidade = self.quantidade_consumida

    while(quantidade > 0)
      sub_estoque_menor_validade = self.estoque.sub_estoques_por_validade.where("quantidade > 0 ").order("validade ASC").first rescue nil
      break if sub_estoque_menor_validade.nil?
      if quantidade >= sub_estoque_menor_validade.quantidade
        quantidade = quantidade - sub_estoque_menor_validade.quantidade
        sub_estoque_menor_validade.update_attribute(:quantidade, 0)
      else
        sub_estoque_menor_validade.update_attribute(:quantidade, sub_estoque_menor_validade.quantidade - quantidade)
        break
      end
    end
  end
  
  def consumo_mensal
		qtd_dias = Date.today.end_of_month.day
		total = (self.quantidade_consumida.to_f / qtd_dias).round(2) rescue 0
  end

  def valida_quantidade
    if self.quantidade_consumida.to_f > self.saldo_atual_do_item
      errors.add(:quantidade_consumida, "Quantidade maior que a do estoque.") if consumo.present?
    end
  end

  def valida_quantidade_em_data_do_consumo
    if self.quantidade_consumida.to_f > self.saldo_do_item_na_data
      errors.add(:quantidade_consumida, "Quantidade maior que a do estoque no período.") if consumo.present?
    end
  end

end
