class Loa::Gestor < ApplicationRecord
	has_paper_trail
	include SimConcern

	belongs_to :unidade_gestora
	belongs_to :agente_publico_municipal, class_name: "Base::AgentePublicoMunicipal"
	belongs_to :arquivo, class_name: 'Tcm::Arquivo', required: false
	delegate :cpf_e_nome, to: :agente_publico_municipal, allow_nil: true
	delegate :cpf, to: :agente_publico_municipal
	delegate :nome, to: :agente_publico_municipal

	attr_default :ingresso_sistema_publico_municipal, :ingresso_por_cargo_politico_administrativo
	attr_default :tipo_relacao_servico_publico, :cargo_politico_administrativo

	validates_presence_of :unidade_gestora_id, :agente_publico_municipal_id, :tipo_de_cargo, :inicio_da_gestao, :numero_da_portaria, :data_da_portaria, :ingresso_sistema_publico_municipal, :tipo_relacao_servico_publico

	validate :valida_gestor
	validate :coincidencia_de_periodos_de_gestao
	validate :valida_se_possui_balancete_gerado
	validate :valida_se_data_inicio_e_menor_que_ultimo_balancete, if: Proc.new {Configuracao.last.try(:utiliza_evento_contabil?)}
	after_save :adiciona_fim_da_gestao_ao_antecessor

	after_destroy :remove_fim_da_gestao_ao_novo_gestor_ativo

	include Enums

	scope :exceto, ->(gestor) { where.not(id: gestor) }

	def adiciona_fim_da_gestao_ao_antecessor
		gestor_ant_sem_fim_de_vig = Loa::Gestor.where('unidade_gestora_id = ? AND fim_da_gestao IS NULL AND ID <> ?', self.unidade_gestora_id, self.id).last
		gestor_ant_sem_fim_de_vig.update_column(:fim_da_gestao, self.inicio_da_gestao.to_date - 1.day) if gestor_ant_sem_fim_de_vig.present?
	end

	def remove_fim_da_gestao_ao_novo_gestor_ativo
		novo_gestor_atual = Loa::Gestor.where('unidade_gestora_id = ? AND fim_da_gestao IS NOT NULL AND ID <> ?', self.unidade_gestora_id, self.id).last
		novo_gestor_atual.update_column(:fim_da_gestao, nil) if novo_gestor_atual.present? && self.gestor_ativo?
	end

	def valida_se_possui_balancete_gerado
		errors.add(:inicio_da_gestao, "Balancete de verificações do mês já foi gerado") if balancete_pcasp_gerado?(self.inicio_da_gestao)
	end

	def valida_se_data_inicio_e_menor_que_ultimo_balancete
		balancete = Contabilidade::BalanceteDeVerificacao.find_by(orcamento_id: Orcamento.find_by(exercicio: inicio_da_gestao.year).id, mes_de_referencia: inicio_da_gestao.month) rescue nil
		errors.add(:inicio_da_gestao, "Balancete de verificações do mês já foi gerado") if balancete.present?
	end

	def valida_gestor
    gestor_existente = self.try(:unidade_gestora).try(:existe_gestor_periodo?,self.inicio_da_gestao, self.fim_da_gestao)

    if gestor_existente.present?
      errors.add(:agente_publico_municipal_id, "Essa unidade gestora já possui um gestor ativo") if gestor_existente.id != self.id
    end
  end

	def gestor_ativo?
		self.inicio_da_gestao <= Date.today && ((self.fim_da_gestao.present? && self.fim_da_gestao >= Date.today) || self.fim_da_gestao == nil)
	end

	def coincidencia_de_periodos_de_gestao
		unless fim_da_gestao.blank?
			coincidencia = unidade_gestora.gestores.exceto(self).where('(inicio_da_gestao <= ? and fim_da_gestao >= ?) or (inicio_da_gestao <= ? and fim_da_gestao >= ?) or (inicio_da_gestao < ? and fim_da_gestao is null)', self.inicio_da_gestao, self.inicio_da_gestao, self.fim_da_gestao, self.fim_da_gestao, self.fim_da_gestao).any?
			errors.add(:base, "Esse período coincide com o de outro gestor") if coincidencia
		end
	end

	#Ajustar quando o mes bloqueio for corrigido
	def existe_algum_lote_gerado?
		data = self.inicio_da_gestao
		if data.year <= 2018
			return true
		else
			orcamento_id = Orcamento.find_by(exercicio: data.year)
			lote_sim = Tcm::Lote.find_by( orcamento_id: orcamento_id, mes_de_referencia: data.month, 
				situacao: [Tcm::Lote.situacoes[:gerado], Tcm::Lote.situacoes[:finalizado]] )
				
			return lote_sim.present?
		end
	end

	def enviado_ao_sim?
		arquivo_id.present? && arquivo_id > 0 && arquivo.lote.lote_processado_ou_enviado?
	end

	def to_sim(data_referencia,unidade_id)
		# MARCAR PARA TESTAR
		# Variáveis necessárias para gerar o SIM
		begin
			exercicio_do_orcamento = data_referencia[0..3]
			tipo_de_cargo = (self.read_attribute_before_type_cast(:tipo_de_cargo) == 59 || self.read_attribute_before_type_cast(:tipo_de_cargo) == 99) ? '' : self.read_attribute_before_type_cast(:tipo_de_cargo).to_s.sim_preenche(2)
			unidade_orcamentaria = unidade_gestora.unidades_orcamentarias.find(unidade_id)
			
			inicio_gestao = inicio_da_gestao.year == exercicio_do_orcamento.to_i ? inicio_da_gestao : Date.new(exercicio_do_orcamento.to_i, 1, 1)

			texto = ""
			texto << "101".sim_preenche(3) + "," #1
			texto << Configuracao.first.codigo_do_municipio_no_tcm.sim_preenche(3) + "," #2
			texto << exercicio_do_orcamento + '00' + "," #3
			texto << unidade_gestora.codigo.to_s.rjust(2, '0') + "," #4
			texto << unidade_orcamentaria.orgao.codigo.sim_limite(2) + "," #5
			texto << unidade_orcamentaria.codigo.codigo_uo_to_sim + ","  #6
			texto << cpf.sim_limite(11) + "," #7
			texto << self.read_attribute_before_type_cast(:ingresso_sistema_publico_municipal).to_s.sim_preenche(1) + "," #8
			texto << self.read_attribute_before_type_cast(:tipo_relacao_servico_publico).to_s.sim_preenche(1) + "," #9
			texto << self.numero_da_portaria.to_s.sim_limite(10) + "," #10
			texto << inicio_gestao.sim_data + "," #11
			texto << data_referencia.to_s + "," #12
			texto << nome.sim_limite(40) + "," #13
			texto << (fim_da_gestao ? fim_da_gestao.to_date.sim_data : '0') + "," #14
			texto << tipo_de_cargo + "," #15
			texto <<  "1"	#16

			return texto
		rescue => e
			if e.class.to_s == "NoMethodError"
				atributo_falho = e.message.split(" ")[2]
				coluna = CSV.parse(texto, :headers => false).last.count
				raise e.mensagem_traduzida(self, "", atributo_falho, coluna)
			else
				raise e
			end
		end
	end

end
