require 'active_support/concern'

module Tcm::EmpenhoConcern extend ActiveSupport::Concern
	# NE_____.DCD
	# ARQUIVO 601

	def pesquisa_empenhos
		status_a_utilizar = [Contabilidade::Empenho.status[:confirmado], Contabilidade::Empenho.status[:anulado]]
		Contabilidade::Empenho.joins(orcamento_da_despesa:[elemento_de_despesa_por_subacao: [subacao: [unidade_orcamentaria: :tipo_de_unidade_administrativa]]])
			.where('base_tipos_de_unidades_administrativas.poder_associado = ?', self.lote.poder_associado)
			.where('contabilidade_empenhos.arquivo_id is null or contabilidade_empenhos.arquivo_id = ?', self.id)
			.where('data_do_empenho >= ? AND data_do_empenho <= ? AND status IN (?) AND restos_a_pagar <> true', self.lote.data_referencia, self.lote.data_referencia.end_of_month, status_a_utilizar)
	end

	def gerar_empenhos
		# pesquisar objetos
		objetos = self.pesquisa_empenhos
		classe_do_objeto = 'Contabilidade::Empenho'
		tipo_de_poder = Tcm::Linha.tipos_de_poder[self.lote.tipo_de_poder]

		# limpar arquivo
		ActiveRecord::Base.connection.execute("DELETE FROM tcm_linhas WHERE modulo_type = '#{classe_do_objeto}' and tipo_de_poder = #{tipo_de_poder} and arquivo_referencia = '#{self.nome}'")

		self.carrega_dependencias_para_empenhos

		linhas = []
		conteudo = ""
		objetos.each do |objeto|
			linha = self.empenho_to_sim(objeto)
			conteudo << linha
			conteudo << "\r\n"
			linhas << Tcm::Linha.new(modulo_id: objeto.id, modulo_type: objeto.class.name, arquivo_referencia: self.nome , conteudo: linha, tipo_de_poder: tipo_de_poder)
			objeto.update_column(:arquivo_id, self.id)
		end
		self.update_columns(conteudo: conteudo, classe: classe_do_objeto)
		Tcm::Linha.import linhas
	end

	def carrega_dependencias_para_empenhos
		@configuracao = Configuracao.first
		@orcamentos = Orcamento.all.map(&:attributes).map(&:symbolize_keys)
	end

	def empenho_to_sim(empenho)
		# Variáveis necessárias para gerar o SIM
		exercicio_do_orcamento =  @orcamentos.select { |i| i[:id] == empenho.orcamento_id }.first[:exercicio].to_s
		orgao = empenho.unidade_orcamentaria.orgao
		cod_elemento = empenho.sub_elemento_de_despesa.elemento_de_despesa.codigo.to_s[4..5]
		elementos_de_folha = ['31900100', '31900300', '31900400', '31901100', '31901600']

		documento_pessoa_sim =
		if empenho.pessoa.tipo_pessoa_to_sim == "6"
			'"66666666666"'
		elsif empenho.pessoa.tipo_pessoa_to_sim == "7"
			'"77777777777"'
		else
			empenho.pessoa.cpf_ou_cnpj_sem_pontos.to_s.sim_limite(25)
		end

		empenho.valida_complementacao_da_fonte_de_recurso
		empenho.valida_gestor_da_unidade

		begin
			texto = ""
			texto << "601".sim_preenche(3) + "," #1
			texto << @configuracao.codigo_do_municipio_no_tcm.sim_preenche(3) + "," #2
			texto << exercicio_do_orcamento + '00' + "," #3
			texto << orgao.codigo.sim_preenche(2) + "," #4
			texto << empenho.unidade_orcamentaria.codigo.codigo_uo_to_sim + "," #5
			texto << empenho.data_do_empenho.sim_data + "," #6
			texto << empenho.numero_do_empenho.sim_limite(8) + "," #7
			texto << (self.try(:lote).present? ? self.lote.exercicio_e_mes_de_geracao : self.exercicio_e_mes_de_geracao).to_s + "," #8
			texto << empenho.subacao.funcao.codigo.sim_limite(2) + "," #9
			texto << empenho.subacao.subfuncao.codigo.sim_limite(3) + "," #10
			texto << empenho.orcamento_da_despesa.acao.programa_de_governo.codigo.sim_limite(4) + "," #11
			texto << empenho.orcamento_da_despesa.acao.natureza_da_acao.codigo.sim_limite(1) + "," #12
			texto << empenho.orcamento_da_despesa.acao.codigo.sim_limite(3) + "," #13
			texto << empenho.orcamento_da_despesa.subacao.codigo.sim_preenche(4) + "," #14
			texto << empenho.sub_elemento_de_despesa.elemento_de_despesa.codigo.sim_preenche(8) + ","
			texto << empenho.fonte_de_recursos.codigo_completo.sim_limite(1) + "," #16
			texto << empenho.fonte_de_recursos.codigo_completo[1..9].sim_limite(9) + "," #17
			texto << '""' + "," #18
			texto << empenho.modalidade_para_o_sim.sim_limite(1) + "," #19
			texto << empenho.historico.sim_descricao.sim_limite(510) + "," #20

			# orcamento_da_despesa_id = self.orcamento_da_despesa.id
			# lancamento_do_orcamento_da_despesa = Contabilidade::LancamentoDoOrcamentoDaDespesa.where(orcamento_da_despesa_id: orcamento_da_despesa_id, modulo_type: "Contabilidade::Empenho", modulo_id: self.id)

			#texto << lancamento_do_orcamento_da_despesa.saldo_ate_o_lancamento.to_f.to_s.sim_valor + "," #21
			texto << empenho.saldo_da_dotacao_antes_do_empenho.to_f.to_s.sim_valor + "," #21
			texto << empenho.definir_valor_do_empenho.to_d.to_s.sim_valor + "," #22
			texto << empenho.saldo_da_dotacao_apos_o_empenho.to_f.to_s.sim_valor + "," #23
			#texto << lancamento_do_orcamento_da_despesa.saldo_antes_do_lancamento.to_f.to_s.sim_valor + "," #23

			if empenho.contrato.present? && !empenho.contrato.parceria?
				if empenho.contrato.unidade_orcamentaria.unidade_gestora.data_encerramento.present? && empenho.contrato.data_do_contrato <= empenho.contrato.unidade_orcamentaria.unidade_gestora.data_encerramento
					gestor_da_unidade = empenho.contrato.unidade_orcamentaria.unidade_gestora.gestor_no_periodo(empenho.contrato.data_do_contrato)
				else
					if empenho.aditivo.present?
						gestor_da_unidade = empenho.aditivo.contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.gestor_no_periodo(empenho.aditivo.data_do_aditivo)
					else
						gestor_da_unidade = empenho.contrato.unidade_orcamentaria_do_exercicio.unidade_gestora.gestor_no_periodo(empenho.contrato.data_do_contrato)
					end
				end

				texto << gestor_da_unidade.cpf.sim_preenche(11) + "," #24

				if empenho.aditivo.present?
					texto << (empenho.contrato.numero + empenho.aditivo.numero.digitos(2)).sim_limite(15) + "," #25
					texto << empenho.aditivo.data_do_aditivo.sim_data + "," #26
				else
					texto << empenho.contrato.numero.to_s.sim_limite(15) + "," #25
					texto << empenho.contrato.data_do_contrato.sim_data + "," #26
				end

				if empenho.projeto.present? && empenho.projeto.data_de_autuacao.present?
					if empenho.projeto.dispensa_de_licitacao? && !empenho.projeto.envia_pro_sim?
						texto << '""' + "," #27
						utiliza_inciso_24 = (empenho.projeto.legislacao.try(:eh_artigo_24_inciso_i?) || empenho.projeto.legislacao.try(:eh_artigo_24_inciso_ii?)) && @configuracao.try(:mandar_dispensa_art_24_i_e_ii_ao_sim) == false
						utiliza_inciso_75 = (empenho.projeto.legislacao.try(:eh_artigo_75_inciso_i?) || empenho.projeto.legislacao.try(:eh_artigo_75_inciso_ii?)) && @configuracao.try(:mandar_dispensa_art_75_i_e_ii_ao_sim) == false

						if utiliza_inciso_24 || utiliza_inciso_75
							texto << '0' + "," #28
						else
							texto << empenho.projeto.data_de_autuacao.sim_data + "," #28
						end
						texto << '"F",' #29
					else
						texto << empenho.projeto.numero_do_processo.to_s.sim_limite(15) + "," #27
						texto << empenho.projeto.data_de_autuacao.sim_data + "," #28
						texto << empenho.projeto.sigla_da_modalidade_do_processo.to_s.sim_preenche(1) + "," #29
					end
				else
					texto << '""' + "," #27
					texto << '0' + "," #28
					texto << '"S"' + "," #29
				end
			else
				texto << '""' + "," #24
				texto << '""' + "," #25
				texto << '0' + "," #26
				texto << '""' + "," #27
				texto << '0' + "," #28
				texto << '"S"' + "," #29
			end

			if empenho.empenho_de_folha? && elementos_de_folha.include?(empenho.sub_elemento_de_despesa.elemento_de_despesa.codigo)
				texto << empenho.pessoa.tipo_pessoa_to_sim.sim_limite(1) + "," #30
				texto << documento_pessoa_sim + "," #31
			else
				texto << '"1"' + ","#30
				if empenho.unidade_orcamentaria.tipo_de_unidade_administrativa.poder_associado == "legislativo"
					texto << empenho.unidade_orcamentaria.unidade_gestora.cnpj.sim_limite(14) + "," #31
				else
					texto << @configuracao.try(:cnpj_da_prefeitura).to_s.delete("./-").sim_limite(14) + "," #31
				end
			end

			texto << empenho.pessoa.nome.to_s.sim_limite(60) + "," #32
			texto << empenho.pessoa.endereco_completo.to_s.sim_limite(255) + "," #33
			texto << (empenho.pessoa.telefone ? empenho.pessoa.telefone.to_s.sim_preenche(11) : '00000000000') + "," #34
			texto << empenho.pessoa.cep.to_s.sim_limite(8) + "," #35
			texto << empenho.pessoa.cidade.try(:nome).to_s.sim_limite(30) + "," #36
			texto << empenho.pessoa.cidade.try(:estado).try(:codigo_uf).to_s.sim_limite(2) + "," #37

			if empenho.obra.present?
				texto << empenho.obra.data_de_inicio.sim_data + "," #38
				texto << empenho.obra.tipo_para_o_sim.to_s.sim_preenche(1) + "," #39
				texto << empenho.obra.codigo.to_s.sim_preenche(4) + "," #40
			else
				texto << '0' + "," #38
				texto << '""' + "," #39
				texto << '""' + "," #40
			end

			#ordenador da despesa
			ordenador_da_despesa_do_empenho = empenho.unidade_orcamentaria.ordenador_de_despesa_na_data(empenho.data_do_empenho)
			texto << ordenador_da_despesa_do_empenho.agente_publico.pessoa.cpf.sim_limite(11) + "," #41

			if empenho.contrato.present? && empenho.contrato.parceria?
				texto << empenho.contrato.data_do_contrato.sim_data + "," #42
				texto << empenho.contrato.numero.to_s.sim_limite(15) + "," #43
				texto << empenho.contrato.sim_tipo_de_contrato.sim_limite(2) + "," #44
			else
				texto << "0" + "," #42
				texto << '""' + "," #43
				texto << '""' + "," #44
			end

			#a partir de 2022 não é mais obrigatorio a fonte de recurso e o codigo será pego da fonte stn
			# if self.complementacao_da_fonte_de_recurso.nil?
			# 	texto << self.fonte_de_recursos.fonte_stn.detalhamento_sintetico.to_s.sim_preenche(4) #45
			# else
			# 	texto << self.read_attribute_before_type_cast(:complementacao_da_fonte_de_recurso).to_s.sim_preenche(4) #45
			# end
			texto << '"0000"' + ","#45
			texto << (empenho.sub_elemento_de_despesa.sub_elemento_origem_tce.present? ? empenho.sub_elemento_de_despesa.sub_elemento_origem_tce.codigo : empenho.sub_elemento_de_despesa.codigo).sim_preenche(2) #46

			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(empenho, empenho.numero_do_empenho, atributo_falho, coluna)
			else
				raise e
			end
		end
	end

end
