class Tableless::ValidadorDeSim
	include ActiveModel::Model
	include EnumIsh::Base

	attr_accessor :arquivo, :texto_do_arquivo, :criticas

	def arquivo_valido?
		return false if arquivo_a_validar.nil?
		
		@linhas_validas = []
		@linhas_de_cpf_invalidas = []

		linhas = CSV.parse(texto_do_arquivo, :headers => false)
		linhas.each_with_index do |linha, index|
			campos = linha
			campo_valido = send(arquivo_a_validar.to_sym, campos, index)[0]

			if campo_valido == false && codigo_do_arquivo == "AP"
				@linhas_de_cpf_invalidas.push([index: index , mensagem: send(arquivo_a_validar.to_sym, campos, index)[1]])
			end
			if campo_valido
				@linhas_validas.push([index: index , mensagem: send(arquivo_a_validar.to_sym, campos, index)[1]])
			end
		end

		@linhas_validas.present? && linhas.size == @linhas_validas.size && @linhas_validas.flatten.any? { |item| item[:mensagem] != nil } == false
	end

	def arquivo_a_validar
		case codigo_do_arquivo
		when "FP"
			metodo = 'validar_campos_FP'
		when "AP"
			metodo = 'validar_campos_AP'
		end
	end

	def exercicio_e_mes_de_geracao
		nome_do_arquivo = arquivo.original_filename[2..7]
	end

	def codigo_do_arquivo
		arquivo.original_filename.try(:first, 2)
	end

	def retorna_arquivo_a_ser_comparado
		case codigo_do_arquivo
		when "FP"
			nome_do_arquivo_a_ser_comparado = "LQ" + exercicio_e_mes_de_geracao + ".DCD"
			Tcm::Arquivo.joins(:lote).find_by('tcm_arquivos.nome like ? AND tcm_lotes.situacao in (?)', nome_do_arquivo_a_ser_comparado, ["1", "9"])
		when "AP"
			nome_do_arquivo_a_ser_comparado = "DA" + exercicio_e_mes_de_geracao + ".OUT"
			Tcm::Arquivo.joins(:lote).find_by('tcm_arquivos.nome like ? AND tcm_lotes.situacao in (?)', nome_do_arquivo_a_ser_comparado, ["1", "9"])
		end
	end

	def conteudo_arquivo_a_ser_comparado
		return '' if arquivo.nil?

		retorna_arquivo_a_ser_comparado.present? ? retorna_arquivo_a_ser_comparado.conteudo : 'Não há arquivo a ser comparado'
	end

	def nome_do_arquivo_a_ser_comparado
		return '' if arquivo.nil?

		retorna_arquivo_a_ser_comparado.present? ? retorna_arquivo_a_ser_comparado.nome : 'Não há arquivo a ser comparado'
	end

	def lote_do_arquivo_a_ser_comparado
		return '' if arquivo.nil? && retorna_arquivo_a_ser_comparado.nil?

		retorna_arquivo_a_ser_comparado.lote_id rescue nil
	end

	def nome_do_arquivo
		return '' if arquivo.nil?

		arquivo.original_filename
	end

	def linhas_lq
		linhas = CSV.parse(retorna_arquivo_a_ser_comparado.conteudo, :headers => false) rescue nil
		return linhas
	end

	def linhas_da
		linhas = CSV.parse(retorna_arquivo_a_ser_comparado.conteudo, :headers => false) rescue nil
		return linhas
	end

	def validar_campos_FP campos_fp, linha
		return [false, nil] if campos_fp.size != 18 || linhas_lq.nil?

		pares_de_campo = [[3,3], [4, 4] ,[5, 13], [6, 14], [7, 15]]
		compara_linhas(campos_fp, linhas_lq, pares_de_campo)
	end

	def validar_campos_AP campos_ap, linha
		return [false, nil] if campos_ap.size != 40 || linhas_da.nil?

		pares_de_campo = [[3, 3], [4, 4], [5, 5]]
		compara_linhas(campos_ap, linhas_da, pares_de_campo)
	end

	def compara_linhas(campos_origem, linhas, pares_de_campo)
		total_agrupado_por_unidade = 0
		linhas_equivalentes = 0
		empenhos = ""
		alerta = nil

		linhas.each do |linha_interna|

			campos_internos = linha_interna
			campos_validos = 0
			pares_de_campo.each do |pares_de_campo|
				index_fp = pares_de_campo[0]
				index_lq = pares_de_campo[1]
				campos_validos += campos_origem[index_fp] == campos_internos[index_lq] ? 1 : 0
			end

			if campos_validos == pares_de_campo.size
				linhas_equivalentes += 1

				if codigo_do_arquivo == "FP"
					total_agrupado_por_unidade += campos_internos[16].to_s.to_d 
					empenhos << campos_internos[6] + ","
				end
			end
		end
	
		linha_valida = linhas_equivalentes > 0 ? true : false

		if codigo_do_arquivo == "FP" && total_agrupado_por_unidade.to_d != campos_origem[9].to_s.to_d
			empenhos = empenhos.chop if empenhos.last == ","
			alerta = "NO ÓRGÃO E UNIDADE ORÇAMENTÁRIA #{campos_origem[3]}#{campos_origem[4]} NO ARQUIVO DE LIQUIDAÇÃO É DEMONSTRADO UM VALOR DE #{total_agrupado_por_unidade.real_contabil} PARA FOLHA #{campos_origem[6]}, E NO ARQUIVO FP O VALOR ENCONTRADO PARA MESMA SITUAÇÃO É #{campos_origem[9].real_contabil} COM UMA DIFERENÇA DE #{(campos_origem[9].to_s.to_d - total_agrupado_por_unidade.to_d).real_contabil }."
		elsif codigo_do_arquivo == "AP" && linha_valida == false
			alerta = "NO ÓRGÃO E UNIDADE ORÇAMENTÁRIA #{campos_origem[3]}#{campos_origem[4]} NO ARQUIVO DE DIÁRIAS NÃO FOI ENCONTRADO O SEGUINTE CPF:#{campos_origem[5]}."
		end

		return [linha_valida, alerta]
	end

	def texto_do_arquivo_validado
		texto = ""
		self.criticas = ""
		texto_do_arquivo.to_s.split("\r\n").each_with_index do |linha, index|

			linha_valida = @linhas_validas.find { |e| e[0][:index] == index } rescue nil
			linha_de_cpf_invalida = @linhas_de_cpf_invalidas.find { |e| e[0][:index] == index } rescue nil
			coloracao = 
				if linha_valida.nil?
					'text-danger'
				elsif linha_valida.present? && linha_valida[0][:mensagem].present?
					'text-warning'
				else
					'text-success'
				end

			texto << "<p class=#{coloracao}>"
			texto << "#{linha} "
			texto << "\n#{linha_valida[0][:mensagem]}" if linha_valida.present? && linha_valida[0][:mensagem].present?
			texto << "\n#{linha_de_cpf_invalida[0][:mensagem]}" if linha_de_cpf_invalida.present? && linha_de_cpf_invalida[0][:mensagem].present?
			texto << "</p>"
			self.criticas << "#{linha_valida[0][:mensagem]}," if linha_valida.present? && linha_valida[0][:mensagem].present?
			self.criticas << "#{linha_de_cpf_invalida[0][:mensagem]}," if linha_de_cpf_invalida.present? && linha_de_cpf_invalida[0][:mensagem].present?
		end
		self.criticas = self.criticas.chop if self.criticas.last == ","
		texto.html_safe
	end
end