require 'httparty'

module ImportacaoTcm
	class ContabilidadeLiquidacoes
		@@host = 'https://api.tce.ce.gov.br/index.php/sim/1_0'

		class << self
			def importar codigo_do_municipio, exercicio
				contabilidade = Orcamento.find_by(exercicio: exercicio)
				if contabilidade.nil?
					ImportacaoTcm::Loa.importar(codigo_do_municipio, exercicio)
					contabilidade = Orcamento.find_by(exercicio: exercicio)
				end

				::Loa::Orgao.where(orcamento_id: contabilidade.id).order(:codigo).pluck(:id, :codigo).map do |orgao_id, codigo_do_orgao|
					liquidacoes = Array.new
					# puts "CARREGANDO LIQUIDAÇÕES DO ÓRGÃO #{codigo_do_orgao}..."
					::Loa::UnidadeOrcamentaria.where(orgao_id: orgao_id, importar_dependencias: true).order(:codigo).pluck(:codigo).map do |codigo_da_unidade_orcamentaria|
						dados_liquidacoes = importar_dados_liquidacoes( codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria )
						liquidacoes.concat(dados_liquidacoes) unless dados_liquidacoes.nil?
					end
					criar_liquidacoes( liquidacoes, contabilidade, codigo_do_orgao ) if liquidacoes.size > 0
				end

				::Loa::Orgao.where(orcamento_id: contabilidade.id).order(:codigo).pluck(:id, :codigo).map do |orgao_id, codigo_do_orgao|
					notas_fiscais = Array.new
					# puts "CARREGANDO NOTAS FISCAIS DO ÓRGÃO #{codigo_do_orgao}..."
					::Loa::UnidadeOrcamentaria.where(orgao_id: orgao_id, importar_dependencias: true).order(:codigo).pluck(:codigo).map do |codigo_da_unidade_orcamentaria|
						dados_notas_fiscais = importar_dados_notas_fiscais( codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria )
						notas_fiscais.concat(dados_notas_fiscais) unless dados_notas_fiscais.nil?
					end
					atualiza_liquidacoes( notas_fiscais, contabilidade, codigo_do_orgao ) if notas_fiscais.size > 0
				end
			end

			def criar_liquidacoes dados_liquidacoes, contabilidade, codigo_do_orgao
				progress_bar = ImportacaoTcm::Loa.barra_de_progresso( titulo: "LIQUIDAÇÕES DO ÓRGÃO #{codigo_do_orgao}", total: dados_liquidacoes.size ) unless Rails.env == "test"
				dados_liquidacoes.each do |liquidacao|

					empenho = Contabilidade::Empenho.find_by(numero_do_empenho: liquidacao['numero_empenho'], orcamento_id: contabilidade.id)

					if empenho
						liquidacao = Contabilidade::Liquidacao.new(
							empenho_id: empenho.id,
							data_da_liquidacao: liquidacao['data_liquidacao'],
							valor: liquidacao['valor_liquidado']
						)
						liquidacao.save(validate: false)
					end

					progress_bar.increment unless Rails.env == "test"
				end
			end

			def atualiza_liquidacoes dados_notas_fiscais, contabilidade, codigo_do_orgao
				progress_bar = ImportacaoTcm::Loa.barra_de_progresso( titulo: "NOTAS FISCAIS DO ÓRGÃO #{codigo_do_orgao}", total: dados_notas_fiscais.size ) unless Rails.env == "test"

				dados_notas_fiscais.each do |nota_fiscal|

					liquidacoes = Contabilidade::Empenho.find_by(numero_do_empenho: nota_fiscal['numero_empenho']).liquidacoes
					if liquidacoes
						liquidacoes.each do |liquidacao|
							if liquidacao.data_da_liquidacao == nota_fiscal['data_liquidacao'].to_date && liquidacao.nota_fiscal_numero.blank?

								liquidacao.nota_fiscal_numero = nota_fiscal['numero_nota_fiscal']
								liquidacao.nota_fiscal_tipo_id = nota_fiscal['tipo_nota_fiscal']
								liquidacao.nota_fiscal_serie = nota_fiscal['numero_serie'][0..4].strip
								liquidacao.nota_fiscal_tipo_de_emissao = nota_fiscal['tipo_emissao'].to_i
								liquidacao.nota_fiscal_data_de_emissao = nota_fiscal['data_emissao']
								liquidacao.nota_fiscal_tipo_de_desconto = 2
								liquidacao.nota_fiscal_valor_de_desconto = nota_fiscal['valor_desconto'].to_f.round(2)
								liquidacao.nota_fiscal_data_limite_de_expedicao = nota_fiscal['data_limite']
								liquidacao.nota_fiscal_numero_protocolo_de_autorizacao = nota_fiscal['numero_protocolo_autenticacao']
								liquidacao.nota_fiscal_serie_do_selo = nota_fiscal['numero_serie_selo_transito'].strip
								liquidacao.nota_fiscal_numero_do_selo = nota_fiscal['numero_selo_transito'].strip
								liquidacao.nota_fiscal_numeros_de_formularios = nota_fiscal['numero_formulario']
								liquidacao.nota_fiscal_aliquota_do_iss = nota_fiscal['valor_aliquota_iss']
								liquidacao.nota_fiscal_aliquota_do_iss_valor = nota_fiscal['valor_base_calculo_iss'].to_f.round(2)

								liquidacao.save(validate: false)
							end
						end
					end

					progress_bar.increment unless Rails.env == "test"
				end
			end


			def importar_dados_liquidacoes codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria
				begin
					response = HTTParty.get("#{@@host}/liquidacoes.xml?codigo_municipio=#{codigo_do_municipio}&exercicio_orcamento=#{exercicio}00&codigo_orgao=#{codigo_do_orgao}&codigo_unidade=#{codigo_da_unidade_orcamentaria}")
					dados_liquidacoes = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['liquidacoes']
					if dados_liquidacoes.is_a?(Array)
						return dados_liquidacoes
					else
						if dados_liquidacoes.nil?
							return nil
						else
							return dados_liquidacoes
						end
					end
				rescue
					puts "Página não encontrada, tentando novamente..."
					sleep 5
					importar_dados_liquidacoes codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria
					return nil
				end
			end

			def importar_dados_notas_fiscais codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria
				begin
					response = HTTParty.get("#{@@host}/notas_fiscais.xml?codigo_municipio=#{codigo_do_municipio}&exercicio_orcamento=#{exercicio}00&codigo_orgao=#{codigo_do_orgao}&codigo_unidade=#{codigo_da_unidade_orcamentaria}")
					dados_notas_fiscais = Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['notas_fiscais']

					if dados_notas_fiscais.is_a?(Array)
						return dados_notas_fiscais
					else
						if dados_notas_fiscais.nil?
							return nil
						else
							return dados_notas_fiscais = [ dados_notas_fiscais ]
						end
					end
				rescue
					puts "Página não encontrada, tentando novamente..."
					sleep 5
					importar_dados_notas_fiscais codigo_do_municipio, exercicio, codigo_do_orgao, codigo_da_unidade_orcamentaria
					return nil
				end

				return dados_notas_fiscais
			end
		end
	end
end
