class GestaoDeEstoque::ItemDoProgramaPorAlmoxarifadoETransferencia < ApplicationRecord
  has_paper_trail

  attr_accessor :quantidade_disponivel_attribute

  belongs_to :programa_por_almoxarifado_e_transferencia, class_name: "ProgramaPorAlmoxarifadoETransferencia"
  belongs_to :item, class_name: "Base::Item"
  belongs_to :estoque, class_name: "GestaoDeEstoque::Estoque"
  belongs_to :item_da_transferencia, class_name: "GestaoDeEstoque::ItemDaTransferencia"

  validates_presence_of :estoque_id, :quantidade

  validate :valida_quantidade

  before_create :atribui_quantidade_solicitada
  before_save :atribui_item_id
  before_save :cria_ou_atualiza_item_da_transferencia
  after_create :atribui_item_da_transferencia_id
  after_destroy :exclui_item_da_transferencia, if: Proc.new {Rails.env.test? == false}

  def atribui_quantidade_solicitada
    self.quantidade_solicitada = self.quantidade.to_d
  end

  def atribui_item_id
    self.item_id = self.estoque.item_id if self.estoque_id.present?
  end

  def atribui_item_da_transferencia_id
    item_da_trans = GestaoDeEstoque::ItemDaTransferencia.find_by(
      transferencia_id: self.programa_por_almoxarifado_e_transferencia.transferencia.id,
      estoque_id: self.estoque.id, item_id: self.item.id,
      programa_por_escola_id: self.programa_por_almoxarifado_e_transferencia.programa_por_escola.id)

    self.update_column(:item_da_transferencia_id, item_da_trans.id)
  end

  def cria_ou_atualiza_item_da_transferencia
    itens = self.programa_por_almoxarifado_e_transferencia.transferencia.itens_da_transferencia
      .where(programa_por_escola: self.programa_por_almoxarifado_e_transferencia.programa_por_escola.id, item_id: self.item.id, estoque_id: self.estoque.id)

    if itens.present?
      item_da_trans = GestaoDeEstoque::ItemDaTransferencia.find_by(
        transferencia_id: self.programa_por_almoxarifado_e_transferencia.transferencia.id,
        estoque_id: self.estoque.id, item_id: self.item.id,
        programa_por_escola_id: self.programa_por_almoxarifado_e_transferencia.programa_por_escola.id)
      quant_total = (item_da_trans.quantidade - self.quantidade_was + self.quantidade)
      calcula_quantidade_e_total(quant_total, item_da_trans)
    else
      item_da_trans = GestaoDeEstoque::ItemDaTransferencia.create!(
        transferencia_id: self.programa_por_almoxarifado_e_transferencia.transferencia.id ,
        estoque_id: self.estoque.id,
        item_id: self.item.id,
        programa_por_escola_id: self.programa_por_almoxarifado_e_transferencia.programa_por_escola.id,
        quantidade: self.quantidade,
        quantidade_disponivel: self.estoque.quantidade_total_saldo,
        valor_unitario: self.estoque.calcular_valor_medio_por_data_final(self.programa_por_almoxarifado_e_transferencia.transferencia.data_de_transferencia),
        total: (self.quantidade * self.estoque.calcular_valor_medio_por_data_final(self.programa_por_almoxarifado_e_transferencia.transferencia.data_de_transferencia))
      )
    end
  end

  def exclui_item_da_transferencia
    itens = self.programa_por_almoxarifado_e_transferencia.transferencia.itens_da_transferencia
    if itens.pluck(:estoque_id).include?(self.estoque.id) && itens.pluck(:item_id).include?(self.item.id)
      item_da_trans = GestaoDeEstoque::ItemDaTransferencia.find_by(
        transferencia_id: self.programa_por_almoxarifado_e_transferencia.transferencia.id,
        estoque_id: self.estoque.id, item_id: self.item.id)
      quant_total = (item_da_trans.quantidade - self.quantidade_was)
      if quant_total <= 0
        item_da_trans.destroy
      else
        calcula_quantidade_e_total(quant_total, item_da_trans)
      end
    end
  end

  def calcula_quantidade_e_total(quant, item_da_trans)
    total_geral = (quant * self.estoque.calcular_valor_medio_por_data_final(self.programa_por_almoxarifado_e_transferencia.transferencia.data_de_transferencia))
    item_da_trans.update_columns(quantidade: quant, total: total_geral)
  end

  def valida_quantidade
    transferencia = self.programa_por_almoxarifado_e_transferencia.transferencia
    quantidade = GestaoDeEstoque::ItemDoProgramaPorAlmoxarifadoETransferencia.joins(:programa_por_almoxarifado_e_transferencia)
      .where('transferencia_id = ? and estoque_id = ?', transferencia.id, self.estoque.id).pluck(:quantidade).sum

    saldo_do_estoque = (self.estoque.quantidade_total_por_data(transferencia.data_de_transferencia.to_date) - quantidade)
    if self.quantidade.to_f > saldo_do_estoque
      errors.add(:quantidade, "Quantidade maior que a do estoque") if transferencia.present?
    end
  end

end
