class Loa::OrdenadorDeDespesa < ApplicationRecord
	has_paper_trail
	include SimConcern

	belongs_to :agente_publico, class_name: 'Base::AgentePublicoMunicipal', foreign_key: "agente_publico_id"
	belongs_to :unidade_orcamentaria, class_name: 'Loa::UnidadeOrcamentaria'
	belongs_to :arquivo, class_name: 'Tcm::Arquivo', required: false

	has_one :orgao, through: :unidade_orcamentaria
	has_one :orcamento, through: :orgao

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

	validates_presence_of :unidade_orcamentaria_id, :agente_publico_id, :tipo_de_cargo, :data_inicio_da_gestao, :numero_da_portaria, :data_da_portaria, :ingresso_sistema_publico_municipal, :tipo_relacao_servico_publico
	
	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_ordenador_ativo

	include Enums

	def adiciona_fim_da_gestao_ao_antecessor
		ordenador_ant_sem_fim_de_vig = Loa::OrdenadorDeDespesa.where('unidade_orcamentaria_id = ? AND data_fim_de_gestao IS NULL AND ID <> ?', self.unidade_orcamentaria_id, self.id).last
		ordenador_ant_sem_fim_de_vig.update_column(:data_fim_de_gestao, self.data_inicio_da_gestao.to_date - 1.day) if ordenador_ant_sem_fim_de_vig.present?
	end

	def remove_fim_da_gestao_ao_novo_ordenador_ativo
		novo_ordenador_atual = Loa::OrdenadorDeDespesa.find_by('unidade_orcamentaria_id = ? AND ((data_inicio_da_gestao <=  ? AND data_fim_de_gestao >= ?) OR (data_inicio_da_gestao <=  ? AND data_fim_de_gestao IS NULL))', self.unidade_orcamentaria_id, Date.today, Date.today, Date.today)
		novo_ordenador_atual.update_column(:data_fim_de_gestao, nil) if novo_ordenador_atual.present?
	end

	def nome_e_cpf
		agente_publico.cpf_e_nome
	end

	#Ajustar quando o mes bloqueio for corrigido
	def existe_algum_lote_gerado?
		data = self.data_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 valida_se_possui_balancete_gerado
		errors.add(:data_inicio_da_gestao, "Balancete de verificações do mês já foi gerado") if balancete_pcasp_gerado?(self.data_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: data_inicio_da_gestao.year).id, mes_de_referencia: data_inicio_da_gestao.month) rescue nil
		errors.add(:data_inicio_da_gestao, "Balancete de verificações do mês já foi gerado") if balancete.present?
	end

	def to_sim(exercicio_e_mes_de_geracao, data_referencia)
		# Variáveis necessárias para gerar o SIM
		begin
			exercicio_do_orcamento = unidade_orcamentaria.orgao.orcamento.exercicio.to_s
			data_de_inclusao_uo = unidade_orcamentaria.created_at.to_date
			incio_gestao = data_inicio_da_gestao.year == data_referencia.year ? data_inicio_da_gestao : data_referencia.beginning_of_year
			data_unid = unidade_orcamentaria.data_de_inclusao.year == data_referencia.year ? unidade_orcamentaria.data_de_inclusao : data_referencia.beginning_of_year
	
			texto = ""
			texto << "109".sim_preenche(3) + ","
			texto << Configuracao.first.codigo_do_municipio_no_tcm.sim_preenche(3) + ","
			texto << exercicio_do_orcamento + '00' + ","
			texto << unidade_orcamentaria.unidade_gestora.codigo.to_s.rjust(2, '0') + ","
			texto << unidade_orcamentaria.orgao.codigo.sim_limite(2) + ","
			texto << unidade_orcamentaria.codigo.codigo_uo_to_sim + ","
			texto << data_unid.sim_data + ","
			texto << agente_publico.cpf.sim_limite(11) + ","
			texto << self.read_attribute_before_type_cast(:ingresso_sistema_publico_municipal).to_s.sim_preenche(1) + ","
			texto << self.read_attribute_before_type_cast(:tipo_relacao_servico_publico).to_s.sim_preenche(1) + ","
			texto << self.numero_da_portaria.to_s.sim_limite(10) + ","
	
			texto << incio_gestao.sim_data + ","
			texto << exercicio_e_mes_de_geracao.to_s + ","
			texto << agente_publico.nome.sim_limite(40) + ","
			# texto << (data_fim_de_gestao ? data_fim_de_gestao.try(:sim_data) : '0') + ","v
			texto << '0' + ","
			texto << self.read_attribute_before_type_cast(:tipo_de_cargo).digitos(2)
	
	
			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
