require 'httparty'

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

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

				dados_orcamentos_da_receita = importar_dados_orcamentos_da_receita( codigo_do_municipio, exercicio )
				criar_orcamentos_da_receita( dados_orcamentos_da_receita, orcamento )
			end

			def criar_orcamentos_da_receita dados_orcamentos_da_receita, orcamento
				progress_bar = ImportacaoTcm::Loa.barra_de_progresso( titulo: 'RECEITAS', total: dados_orcamentos_da_receita.size ) unless Rails.env == "test"

				if orcamento.exercicio <= 2014
					grupo_da_fonte_de_recurso = orcamento.grupos_das_fontes_de_recursos.new(modulo_id: orcamento.id, modulo_type: orcamento.class.name, codigo: "0", descricao: "IMPORTADO DO TCM 0")
					grupo_da_fonte_de_recurso.save(validate: false)
				end

				dados_orcamentos_da_receita.each do |receita|

					# Buscando a(s) Unidade(s) Orçamentária(s)
					orgao = ::Loa::Orgao.find_by( orcamento_id: orcamento.id, codigo: receita['codigo_orgao'] )
					unidade_orcamentaria = ::Loa::UnidadeOrcamentaria.find_by( orgao_id: orgao.id, codigo: receita['codigo_unidade'].strip )

					# Buscando e/ou cadastrando a(s) Natureza(s) da Receita
					natureza_da_receita = ::Base::NaturezaDaReceita.find_by( modulo_id: orcamento.id, modulo_type: orcamento.class.name, codigo: codigo_receita(receita['codigo_rubrica'], orcamento.exercicio) )
					if natureza_da_receita.blank?
						natureza_da_receita = criar_natureza_da_receita( orcamento, receita )
					end

					# Cadastrando o(s) Orçamento(s) da Receita
					if orcamento.exercicio > 2018
						fonte_de_recursos = orcamento.fontes_de_recursos.find {|fonte_de_recurso| fonte_de_recurso.codigo_completo[1..9] == despesa['codigo_fonte'].strip }
					else
						fonte_de_recursos = orcamento.fontes_de_recursos.find_by( codigo: despesa['codigo_fonte'].strip )
					end
					if fonte_de_recursos.nil?
						grupo_da_fonte_de_recurso = ::Base::GrupoDaFonteDeRecursos.find_by(modulo_id: orcamento.id, modulo_type: orcamento.class.name, codigo: receita['tipo_fonte'].strip)
						fonte_de_recursos = orcamento.fontes_de_recursos.create(
							codigo: receita['codigo_fonte'].strip,
							descricao: "IMPORTADO DO TCM #{receita['codigo_fonte'].strip}",
							grupo_da_fonte_de_recursos_id: grupo_da_fonte_de_recurso.try(:id)
						)
					end

					unidade_orcamentaria_por_natureza_da_receita = ::Loa::UnidadeOrcamentariaPorNaturezaDaReceita.find_by( unidade_orcamentaria_id: unidade_orcamentaria.id, natureza_da_receita_id: natureza_da_receita.id )
					if unidade_orcamentaria_por_natureza_da_receita.blank?
						unidade_orcamentaria_por_natureza_da_receita = criar_unidade_orcamentaria_por_natureza_da_receita( unidade_orcamentaria, natureza_da_receita )
					end

						criar_orcamento_da_receita( unidade_orcamentaria_por_natureza_da_receita, receita['valor_previsto'].to_f, fonte_de_recursos )

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

			def importar_dados_orcamentos_da_receita codigo_do_municipio, exercicio
				response = HTTParty.get("#{@@host}/orcamento_receita.xml?codigo_municipio=#{codigo_do_municipio}&exercicio_orcamento=#{exercicio}00")
				begin
					Hash.from_xml(response.body.encode(Encoding::UTF_8))['rsp']['orcamento_receita']
				rescue
					puts "Página não encontrada, tentando novamente..."
					sleep 5
					importar_dados_orcamentos_da_receita codigo_do_municipio, exercicio
				end
			end
		end

		def self.criar_natureza_da_receita orcamento, dados_da_natureza
			novo_tipo = orcamento.exercicio > 2017
			if novo_tipo
				natureza = codigo_receita(dados_da_natureza['codigo_rubrica'], orcamento.exercicio)
				tipo_de_deducao = orcamento.tipos_de_deducao.find_by_codigo!(natureza[0..1])
				::Base::NaturezaDaReceita.create!(
					modulo_id: orcamento.id, modulo_type: orcamento.class.name, codigo: natureza,
					categoria_economica: natureza[0..2],
					origem: natureza[3],
					especie: natureza[4],
					rubrica: natureza[5],
					alinea: natureza[6..7],
					subalinea: natureza[8],
					detalhamento_optativo: natureza[9],
					nivel_opcional_1: natureza[10..11],
					nivel_opcional_2: natureza[12..13],
					nivel_opcional_3: natureza[14..15],
					descricao: dados_da_natureza['descricao_rubrica'],
					tipo_de_orcamento_id: orcamento.tipos_de_orcamento.first.id,
					padrao: false,
					tipo_de_receita: "primaria",
					novo_tipo: novo_tipo,
					tipo_de_deducao_id: tipo_de_deducao.id
				)
			else
				::Base::NaturezaDaReceita.create!(
					modulo_id: orcamento.id, modulo_type: orcamento.class.name, codigo: dados_da_natureza['codigo_rubrica'][0..9],
					categoria_economica: dados_da_natureza['codigo_rubrica'][0],
					origem: dados_da_natureza['codigo_rubrica'][1],
					especie: dados_da_natureza['codigo_rubrica'][2],
					rubrica: dados_da_natureza['codigo_rubrica'][3],
					alinea: dados_da_natureza['codigo_rubrica'][4..5],
					subalinea: dados_da_natureza['codigo_rubrica'][6..7],
					detalhamento_optativo: dados_da_natureza['codigo_rubrica'][8..9],
					descricao: dados_da_natureza['descricao_rubrica'],
					tipo_de_orcamento_id: orcamento.tipos_de_orcamento.first.id,
					padrao: false,
					tipo_de_receita: "primaria",
					novo_tipo: novo_tipo
				)
			end
		end

		def self.criar_unidade_orcamentaria_por_natureza_da_receita unidade_orcamentaria, natureza_da_receita
			::Loa::UnidadeOrcamentariaPorNaturezaDaReceita.create!(
				unidade_orcamentaria_id: unidade_orcamentaria.id,
				natureza_da_receita_id: natureza_da_receita.id,
				skip_fontes_obrigatorias: true
			)
		end

		def self.criar_orcamento_da_receita unidade_orcamentaria_por_natureza_da_receita, valor, fonte_de_recursos
			orcamento_da_receita = ::Loa::OrcamentoDaReceita.find_by(
				unidade_orcamentaria_por_natureza_da_receita_id: unidade_orcamentaria_por_natureza_da_receita.id,
				fonte_de_recursos_id: fonte_de_recursos.id
			)

			if orcamento_da_receita.present?
				inclui_valor_previsto_na_natureza_da_receita( orcamento_da_receita.unidade_orcamentaria_por_natureza_da_receita.natureza_da_receita, valor )
				inclui_valor( orcamento_da_receita, valor )

			else
				orcamento_da_receita = ::Loa::OrcamentoDaReceita.new(
					unidade_orcamentaria_por_natureza_da_receita_id: unidade_orcamentaria_por_natureza_da_receita.id,
					fonte_de_recursos_id: fonte_de_recursos.id,
					valor: valor
				)

				inclui_valor_previsto_na_natureza_da_receita( orcamento_da_receita.unidade_orcamentaria_por_natureza_da_receita.natureza_da_receita, valor )
				orcamento_da_receita.save!(validate: false)
			end
		end

		def self.inclui_valor orcamento_da_receita, valor
			orcamento_da_receita.valor += valor
			orcamento_da_receita.save!(validate: false)
		end

		def self.inclui_valor_previsto_na_natureza_da_receita natureza_da_receita, valor
			natureza_da_receita.valor_previsto += valor
			# natureza_da_receita.skip_validacao = true
			natureza_da_receita.save!(validate: false)
		end

		def self.codigo_receita codigo, exercicio
			if exercicio > 2017
				natureza = codigo[0..13]
				if natureza[0] == '9'
					natureza << '00'
				else
					natureza.prepend('00')
				end
			else
				codigo[0..9]
			end
		end

		private_class_method :criar_natureza_da_receita
		private_class_method :criar_orcamento_da_receita
		private_class_method :inclui_valor
		private_class_method :inclui_valor_previsto_na_natureza_da_receita

	end
end
