class Patrimonio::ItemDaTransferencia < ApplicationRecord
  has_paper_trail
  
  attr_accessor :quantidade_disponivel_attribute

  belongs_to :transferencia, class_name: 'Patrimonio::Transferencia'
  belongs_to :item, class_name: "Base::Item"
  belongs_to :unidade_gestora, class_name: 'Loa::UnidadeGestora'
  belongs_to :centro_de_custo, class_name: 'Controladoria::CentroDeCusto'

  belongs_to :bem_patrimonial, class_name: 'Patrimonio::BemPatrimonial'
  has_many :bens_patrimoniais, class_name: 'Patrimonio::BemPatrimonial'

  validates_presence_of :centro_de_custo_id
  validate :valida_quantidade
  validate :valida_unicidade_de_bem_patrimonial
  after_save :definir_unidade_gestora
  after_save :remover_este_item_se_quantidade_igual_a_zero, if: Proc.new {Rails.env.test? == false}

	def saldo_atual_do_item
    item.quantidade_de_bens_com_mesmo_item_e_mesma_unidade_gestora_e_centro_de_custo(self.transferencia.unidade_gestora_origem.id, self.transferencia.centro_de_custo_origem.id).to_f rescue 0.0
  end

  def definir_unidade_gestora
    if self.centro_de_custo.present?
      self.update_columns( 
        unidade_gestora_id: self.transferencia.dados_dos_destinos_das_transferencias.where(centro_de_custo_destino: self.centro_de_custo).last.unidade_gestora_destino.id
      )
    end
  end

  def atualiza_localizacao
    if self.transferencia.por_lote?
      quantidade = self.quantidade_solicitada.to_i
      bens_patrimoniais_escolhidos = Patrimonio::BemPatrimonial.joins(:localizacoes_dos_bens).where('patrimonio_bens_patrimoniais.status = 1 
        and patrimonio_bens_patrimoniais.item_id = ? and patrimonio_bens_patrimoniais.unidade_gestora_id = ? and patrimonio_localizacoes_dos_bens.centro_de_custo_id = ?', 
          self.item_id, self.transferencia.unidade_gestora_origem.id, self.transferencia.centro_de_custo_origem.id).limit(quantidade).order('numero_do_tombamento ASC')

      begin
        bens_patrimoniais_escolhidos.each do |bem| 
          bem.update_columns(
            unidade_gestora_id: self.unidade_gestora.id,
            item_da_transferencia_id: self.id
          )

          nova_localizacao = Patrimonio::LocalizacaoDoBem.create!(
            bem_patrimonial_id: bem.id,
            centro_de_custo_id: self.centro_de_custo.id,
            agente_publico_municipal: self.centro_de_custo.responsavel_do_centro_de_custos.agente_publico_municipal,
            status: 2,
            data_de_inicio_na_localizacao: self.transferencia.data_da_transferencia
          )

          ulti_respon = Patrimonio::ResponsavelDoBemPatrimonial.find_by(bem_patrimonial_id: bem.id).update_columns(
            data_fim: nova_localizacao.data_de_inicio_na_localizacao
          )

          novo_responsavel = Patrimonio::ResponsavelDoBemPatrimonial.create!(
            bem_patrimonial_id: bem.id,
            pessoa_id: self.centro_de_custo.responsavel_do_centro_de_custos.agente_publico_municipal.pessoa.id,
            data_inicio: nova_localizacao.data_de_inicio_na_localizacao,
            tipo_de_responsavel: self.centro_de_custo.responsavel_do_centro_de_custos.centro_de_custo_id == self.centro_de_custo_id ? 1 : 2
          )
          bem.definir_nova_localizacao_atual
        end
      rescue Exception => e
        raise e
      end
      
    else
      begin
        if self.centro_de_custo.unidade_gestora.present?
          unidade_gestora = self.centro_de_custo.unidade_gestora
        else
          unidade_gestora = self.centro_de_custo.centro_de_custos_mae_principal.unidade_gestora
        end
  
        self.bem_patrimonial.update_columns(
          unidade_gestora_id: unidade_gestora.id
        )
        
        self.adiciona_movimentacao
      rescue Exception => e
        raise e
      end
    end
	end

  def adiciona_movimentacao
    begin
      responsavel = self.centro_de_custo.responsavel_do_centro_de_custos || self.centro_de_custo.centro_de_custos_mae_principal.responsavel_atual_patrimonial
      agente_publico = responsavel.agente_publico_municipal
  
      Patrimonio::LocalizacaoDoBem.transaction do
        nova_localizacao = Patrimonio::LocalizacaoDoBem.create!(
          bem_patrimonial_id: self.bem_patrimonial.id,
          centro_de_custo_id: self.centro_de_custo.id,
          agente_publico_municipal: agente_publico,
          status: 2,
          data_de_inicio_na_localizacao: self.transferencia.data_da_transferencia
        )
  
        Patrimonio::ResponsavelDoBemPatrimonial
          .where(bem_patrimonial_id: self.bem_patrimonial.id)
          .update_all(data_fim: nova_localizacao.data_de_inicio_na_localizacao)
  
        Patrimonio::ResponsavelDoBemPatrimonial.create!(
          bem_patrimonial_id: self.bem_patrimonial.id,
          pessoa_id: agente_publico.pessoa.id,
          data_inicio: nova_localizacao.data_de_inicio_na_localizacao,
          tipo_de_responsavel: responsavel.centro_de_custo_id == self.centro_de_custo_id ? 1 : 2
        )
  
        self.bem_patrimonial.definir_nova_localizacao_atual
      end
    rescue Exception => e
      raise e
    end
  end

  def valida_quantidade
    if self.quantidade_solicitada.to_f > self.saldo_atual_do_item
      errors.add(:quantidade_solicitada, "Quantidade maior que a disponível.") if transferencia.present?
    end
  end

  def valida_unicidade_de_bem_patrimonial

    unless self.transferencia.por_lote?
      bens_existentes = self.transferencia.itens_da_transferencia.map{|bem| [bem.centro_de_custo_id, bem.bem_patrimonial_id]}.uniq
    else
      bens_existentes = self.transferencia.itens_da_transferencia.map{|bem| [bem.centro_de_custo_id, bem.item_id]}.uniq
    end
    
    existe_duplicata = bens_existentes.size != self.transferencia.itens_da_transferencia.size
    errors.add(:base, "Bem patrimonial já foi incluído ou existem bens patrimoniais duplicados.") if existe_duplicata
  end

  def remover_este_item_se_quantidade_igual_a_zero
		self.delete if (self.item.nil? && self.bem_patrimonial.nil?) || (self.quantidade_solicitada.to_f < 0 && (self.item.present? || self.bem_patrimonial.present?))
	end

end
