class Loa::Relatorios::DemonstrativoConsolidadoDoOrcamentoDespesa

	def self.dados orcamento
		dados = ActiveRecord::Base.connection.execute( sql_despesa(orcamento.id) ).to_a

		dados = sumario(dados)
		dados = ajustar_valores_percentuais(dados)
		dados = formatarDados(dados)
		return dados
	end

	private

	def self.ajustar_valores_percentuais(dados)

		dados.map do |dado|
			dado['percentual_ordinario'] = dados.last['ordinario'].to_f > 0 ? dado['ordinario'].to_f / dados.last['ordinario'] * 100 : 0
			dado['percentual_vinculado'] = dados.last['vinculado'].to_f > 0 ? dado['vinculado'].to_f / dados.last['vinculado'] * 100  : 0
			dado['percentual_total'] = dados.last['total'].to_f > 0 ? dado['total'].to_f / dados.last['total'] * 100  : 0
		end
		return dados
	end

	def self.formatarDados(tabela)
		tabela.map do |dados|
			if dados['codigo'].size == 1
				dados[:estilo] = {negrito: true}
			elsif dados['codigo'].size == 2
				dados[:estilo] = {tabulacao: 12}
			elsif dados['codigo'].size == 3
				dados[:estilo] = {tabulacao: 24}
			end


			dados['ordinario'] = dados['ordinario'].to_s
			dados['percentual_ordinario'] = dados['percentual_ordinario'].to_s
			dados['vinculado'] = dados['vinculado'].to_s
			dados['percentual_vinculado'] = dados['percentual_vinculado'].to_s
			dados['total'] = dados['total'].to_s
			dados['percentual_total'] = dados['percentual_total'].to_s

			dados.delete('codigo')
		end

		return tabela
	end

	def self.sumario(dados)
		sumario = {}
		sumario['codigo'] = ''
		sumario['descricao'] = 'Total'
		sumario['ordinario'] = 0
		sumario['percentual_ordinario'] = 100.0
		sumario['vinculado'] = 0
		sumario['percentual_vinculado'] = 100.0
		sumario['total'] = 0
		sumario['percentual_total'] = 100.0
		sumario[:estilo] = { negrito: true }

		dados.each do |dado|
			if dado['codigo'].size == 1
				sumario['vinculado'] += dado['vinculado'].to_f
				sumario['ordinario'] += dado['ordinario'].to_f
				sumario['total'] += dado['total'].to_f
			end
		end

		dados.push(sumario)
		return dados
	end

	def self.sql_despesa(orcamento_id)
		%Q(
			WITH cte_tipo_fonte_classificacao_despesa_e_tipo_de_administracao AS (
			SELECT elemento_de_despesa.codigo AS elemento_de_despesa_codigo
					 , tipo_de_adm.descricao AS descricao
					 , CASE WHEN fonte.tipo_de_arrecadacao = '0' THEN orcamento_da_despesa.valor ELSE 0 END AS ordinario
					 , CASE WHEN fonte.tipo_de_arrecadacao = '1' THEN orcamento_da_despesa.valor ELSE 0 END AS vinculado
					 , orcamento_da_despesa.valor AS total
					 , grupo_despesa.descricao AS grupo_despesa_descricao
					 , categoria_economica.descricao AS categoria_economica_descricao
				FROM base_categorias_economicas categoria_economica
				JOIN base_grupos_de_natureza_da_despesa grupo_despesa ON (grupo_despesa.categoria_economica_id = categoria_economica.id)
				JOIN base_modalidades_de_aplicacao modalidade_de_aplicacao ON (modalidade_de_aplicacao.grupo_de_natureza_da_despesa_id = grupo_despesa.id)
				JOIN base_elementos_de_despesa elemento_de_despesa ON (elemento_de_despesa.modalidade_de_aplicacao_id = modalidade_de_aplicacao.id)
				JOIN loa_elementos_de_despesa_por_subacao subacao_por_elemento ON (subacao_por_elemento.elemento_de_despesa_id = elemento_de_despesa.id)
				JOIN loa_subacoes subacao ON (subacao_por_elemento.subacao_id = subacao.id)
				JOIN loa_unidades_orcamentarias unidade_orcamentaria ON (subacao.unidade_orcamentaria_id = unidade_orcamentaria.id)
				JOIN base_tipos_de_administracao tipo_de_adm ON (unidade_orcamentaria.tipo_de_administracao_id = tipo_de_adm.id)
				JOIN loa_orcamentos_da_despesa orcamento_da_despesa ON (orcamento_da_despesa.elemento_de_despesa_por_subacao_id = subacao_por_elemento.id)
				JOIN base_fontes_de_recursos fonte ON (orcamento_da_despesa.fonte_de_recursos_id = fonte.id)
				JOIN base_grupos_das_fontes_de_recursos grupo_fonte ON (grupo_fonte.id = fonte.grupo_da_fonte_de_recursos_id)
			 WHERE categoria_economica.modulo_id = #{orcamento_id}
				 AND categoria_economica.modulo_type = 'Orcamento'
			 ), cte_agrupa_tipo_fonte_classificacao_despesa AS (
			SELECT substring(elemento_de_despesa_codigo from 1 for 2) as codigo
					 , descricao
					 , grupo_despesa_descricao
					 , SUM(ordinario) as ordinario
					 , SUM(vinculado) as vinculado
					 , SUM(total) as total
				FROM cte_tipo_fonte_classificacao_despesa_e_tipo_de_administracao
			 GROUP BY 1,2,3
			 ORDER BY 1
			 ), cte_grupo_natureza_despesa AS (
			 SELECT substring(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.elemento_de_despesa_codigo from 1 for 2) AS codigo
						, tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.grupo_despesa_descricao as descricao
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.ordinario) as ordinario
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.vinculado) as vinculado
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.total) as total
				 FROM cte_tipo_fonte_classificacao_despesa_e_tipo_de_administracao tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao
				 GROUP BY 1,2
				 ORDER BY 1
			), cte_categoria_economica AS (
			 SELECT substring(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.elemento_de_despesa_codigo from 1 for 1) as codigo
						, tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.categoria_economica_descricao as descricao
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.ordinario) as ordinario
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.vinculado) as vinculado
						, sum(tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao.total) as total
				 FROM cte_tipo_fonte_classificacao_despesa_e_tipo_de_administracao tipo_fonte_e_classificacao_da_despesa_e_tipo_administracao
				 GROUP BY 1,2
				 ORDER BY 1
			) SELECT codigo, descricao, ordinario, '' AS percentual_ordinario,vinculado, '' AS percentual_vinculado,total, '' AS percentual_total FROM cte_categoria_economica
				UNION ALL
				SELECT codigo, descricao, ordinario, '' AS percentual_ordinario,vinculado, '' AS percentual_vinculado,total, '' AS percentual_total FROM cte_grupo_natureza_despesa
				UNION ALL
				SELECT RPAD(codigo, 3, '0'), descricao, ordinario, '' AS percentual_ordinario,vinculado, '' AS percentual_vinculado,total, '' AS percentual_total FROM cte_agrupa_tipo_fonte_classificacao_despesa
				ORDER BY 1,2
		)
	end
end
