class Patrimonio::ItemDaRequisicaoPatrimonial < ApplicationRecord
  has_paper_trail

  attr_accessor :quantidade_disponivel_attribute

  belongs_to :requisicao_patrimonial, class_name: 'Patrimonio::RequisicaoPatrimonial'
  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_da_requisicao, class_name: 'Patrimonio::BemPatrimonialDaRequisicao', inverse_of: :item_da_requisicao_patrimonial, dependent: :destroy

  accepts_nested_attributes_for :bens_patrimoniais_da_requisicao, allow_destroy: true

  validates_presence_of :requisicao_patrimonial_id
  validate :valida_unicidade_de_bem_patrimonial

  after_save :definir_unidade_gestora
  after_save :define_bem_por_lote, if: Proc.new { self.requisicao_patrimonial.por_lote? }
  after_save :remover_este_item_se_quantidade_igual_a_zero, if: Proc.new {Rails.env.test? == false}

  def definir_unidade_gestora
    if self.centro_de_custo.present?
      self.update_columns( 
        unidade_gestora_id: self.requisicao_patrimonial.dados_dos_destinos_das_requisicoes.where(centro_de_custo: self.centro_de_custo).last.unidade_gestora.id
      )
    end
  end

  def define_bem_por_lote
    quantidade = self.quantidade_solicitada.to_i
    bens_patrimoniais_escolhidos = Patrimonio::BemPatrimonial.joins(:localizacao_atual).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.requisicao_patrimonial.unidade_gestora.id, 
      self.requisicao_patrimonial.centro_de_custo.id).limit(quantidade).order('numero_do_tombamento ASC')

    begin
      bens_patrimoniais_escolhidos.each do |bem|
        bem_patrimonial_da_requisicao = Patrimonio::BemPatrimonialDaRequisicao.create!(
          item_da_requisicao_patrimonial_id: self.id,
          bem_id: bem.id
        )
      end
    rescue Exception => e
      raise e
    end

  end
  
  def atualiza_localizacao
    if self.requisicao_patrimonial.por_lote? || self.requisicao_patrimonial.por_lote_e_tombamento?
      bens_patrimoniais_escolhidos = Patrimonio::BemPatrimonial.where('patrimonio_bens_patrimoniais.id in (?)', self.bens_patrimoniais_da_requisicao.pluck(:bem_id)).order('numero_do_tombamento ASC')

      begin
        bens_patrimoniais_escolhidos.each do |bem|
          bem.update_columns(
            unidade_gestora_id: self.unidade_gestora.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.requisicao_patrimonial.data_da_requisicao
          )

          ulti_respon = Patrimonio::ResponsavelDoBemPatrimonial.find_by(bem_patrimonial_id: bem.id)
          if ulti_respon.nil?
            bem.gera_responsaveis_faltantes
          else
            ulti_respon.update_columns(
              data_fim: nova_localizacao.data_de_inicio_na_localizacao
            )
          end

          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
			nova_localizacao = Patrimonio::LocalizacaoDoBem.create!(
        bem_patrimonial_id: self.bem_patrimonial.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.requisicao_patrimonial.data_da_requisicao
      )
      
      ulti_respon = Patrimonio::ResponsavelDoBemPatrimonial.find_by(bem_patrimonial_id: self.bem_patrimonial.id)
      if ulti_respon.nil?
        self.bem_patrimonial.gera_responsaveis_faltantes
      else
        ulti_respon.update_columns(
          data_fim: nova_localizacao.data_de_inicio_na_localizacao
        )
      end
      
      novo_responsavel = Patrimonio::ResponsavelDoBemPatrimonial.create!(
        bem_patrimonial_id: self.bem_patrimonial.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
      )
      
      self.bem_patrimonial.definir_nova_localizacao_atual
		rescue Exception => e
			raise e
		end
	end

  def valida_unicidade_de_bem_patrimonial

    unless self.requisicao_patrimonial.por_lote?
      bens_existentes = self.requisicao_patrimonial.itens_da_requisicao_patrimonial.map{|bem| [bem.centro_de_custo_id, bem.bem_patrimonial_id]}.uniq
    else
      bens_existentes = self.requisicao_patrimonial.itens_da_requisicao_patrimonial.map{|bem| [bem.centro_de_custo_id, bem.item_id]}.uniq
    end
    existe_duplicata = bens_existentes.size != self.requisicao_patrimonial.itens_da_requisicao_patrimonial.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
