class Loa::Relatorios::ProgramaDeTrabalho

	def self.dados orcamento_id, unidade_orcamentaria = nil
		dados = ActiveRecord::Base.connection.execute( sql(orcamento_id, unidade_orcamentaria) ).to_a

		sumario = {}
		sumario['codigo'] = 'Total'
		sumario['nome'] = ''
		sumario['projeto'] = 0
		sumario['atividade'] = 0
		sumario['especiais'] = 0
		sumario['total'] = 0

		sumario[:estilo] = { negrito: true }

		dados.each do |dado|
			if dado['codigo'].size == 2
				sumario['projeto'] += dado['projeto'].to_f
				sumario['atividade'] += dado['atividade'].to_f
				sumario['especiais'] += dado['especiais'].to_f
				sumario['total'] += dado['total'].to_f
			end
		end

		dados.push(sumario)
		dados = formatarDados(dados)
		return dados
	end

	private

	def self.formatarDados(tabela)
		tabela.each.map do |dados|
			dados['projeto'] = dados['projeto'].to_s
			dados['atividade'] = dados['atividade'].to_s
			dados['especiais'] = dados['especiais'].to_s
			dados['total'] = dados['total'].to_s

			if dados['codigo'].count('.') == 5
				dados[:estilo] = { tabulacao: { posicoes: [1], quantidade: 2 * dados['codigo'].count('.') } }
			elsif dados['codigo'].count('.') > 0
				dados[:estilo] = { tabulacao: { posicoes: [1], quantidade: 2 * dados['codigo'].count('.') }, negrito: true }
			else
				dados[:estilo] = { negrito: true }
			end
		end

		return tabela
	end
	def self.sql(orcamento_id, unidade_orcamentaria = nil)
		if unidade_orcamentaria.nil? || unidade_orcamentaria.empty?
			query = "programa.orcamento_id = #{orcamento_id}"
		else
			query = "programa.orcamento_id = #{orcamento_id} and unidade_orcamentaria.id = #{unidade_orcamentaria}"
		end
		%Q(
		WITH cte_acoes AS (
			SELECT orgao.codigo as orgao_codigo
			     , orgao.nome as orgao_nome
			     , orgao.codigo|| '.' || lpad(unidade_orcamentaria.codigo, 2, '0') as unidade_orcamentaria_codigo
			     , unidade_orcamentaria.nome as unidade_orcamentaria_nome
			     , orgao.codigo|| '.' || lpad(unidade_orcamentaria.codigo, 2, '0') || '.' || funcao.codigo as funcao_codigo
			     , funcao.nome as funcao_nome
			     , orgao.codigo|| '.' || lpad(unidade_orcamentaria.codigo, 2, '0') || '.' || funcao.codigo || '.' || subfuncao.codigo as subfuncao_codigo
			     , subfuncao.nome as subfuncao_nome
			     , orgao.codigo|| '.' || lpad(unidade_orcamentaria.codigo, 2, '0') || '.' || funcao.codigo || '.' || subfuncao.codigo || '.' || programa.codigo as programa_codigo
			     , programa.nome as programa_nome
			     , acao.nome as nome
			     , orgao.codigo|| '.' || lpad(unidade_orcamentaria.codigo, 2, '0') || '.' || funcao.codigo || '.' || subfuncao.codigo || '.' || programa.codigo || '.' || natureza_da_acao.codigo || acao.codigo as codigo
			     , CASE WHEN natureza_da_acao.descricao = 'Projeto' THEN sum(orcamento_despesa.valor) END AS projeto
			     , CASE WHEN natureza_da_acao.descricao = 'Atividade' THEN sum(orcamento_despesa.valor) END AS atividade
			     , CASE WHEN natureza_da_acao.descricao = 'Operações Especiais' THEN sum(orcamento_despesa.valor) WHEN natureza_da_acao.descricao = 'Reserva de Contingência' THEN sum(orcamento_despesa.valor) END AS especiais
			 FROM loa_programas_de_governo programa
			 JOIN loa_acoes acao ON acao.programa_de_governo_id = programa.id
			 JOIN base_naturezas_das_acoes natureza_da_acao ON natureza_da_acao.id = acao.natureza_da_acao_id
			 JOIN loa_subacoes subacao ON acao.id = subacao.acao_id
			 JOIN base_funcoes funcao ON subacao.funcao_id = funcao.id
			 JOIN base_subfuncoes subfuncao ON subacao.subfuncao_id = subfuncao.id
			 JOIN loa_unidades_orcamentarias unidade_orcamentaria ON unidade_orcamentaria.id = subacao.unidade_orcamentaria_id
			 JOIN loa_orgaos orgao ON orgao.id = unidade_orcamentaria.orgao_id
			 JOIN loa_elementos_de_despesa_por_subacao elemento_subacao ON elemento_subacao.subacao_id = subacao.id
			 JOIN loa_orcamentos_da_despesa orcamento_despesa ON elemento_subacao.id = orcamento_despesa.elemento_de_despesa_por_subacao_id
			 WHERE #{query}
			 GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,natureza_da_acao.descricao
		 ), cte_orgaos AS (
			SELECT orgao_codigo as codigo
				, orgao_nome as nome
				 , sum(projeto) as projeto
				 , sum(atividade) as atividade
				 , sum(especiais) as especiais
			  FROM cte_acoes
			 GROUP BY 1,2
		 ), cte_unidades_orcamentarias AS (
			SELECT unidade_orcamentaria_codigo as codigo
				 , unidade_orcamentaria_nome as nome
				 , sum(projeto) as projeto
				 , sum(atividade) as atividade
				 , sum(especiais) as especiais
			  FROM cte_acoes
			 GROUP BY 1,2
		 ), cte_funcoes AS (
			SELECT funcao_codigo as codigo
				 , funcao_nome as nome
				 , sum(projeto) as projeto
				 , sum(atividade) as atividade
				 , sum(especiais)  as especiais
			  FROM cte_acoes
			 GROUP BY 1,2
		 ), cte_subfuncoes AS (
			SELECT subfuncao_codigo as codigo
				 , subfuncao_nome as nome
				 , sum(projeto) as projeto
				 , sum(atividade) as atividade
				 , sum(especiais) as especiais
			  FROM cte_acoes
			 GROUP BY 1,2
		 ), cte_programas AS (
			SELECT programa_codigo as codigo
				 , programa_nome as nome
				 , sum(projeto) as projeto
				 , sum(atividade) as atividade
				 , sum(especiais) as especiais
			  FROM cte_acoes
			 GROUP BY 1,2
		 )
		  SELECT orgao.codigo
			  , orgao.nome
			  , orgao.projeto
			  , orgao.atividade
			  , orgao.especiais
			  , COALESCE(orgao.projeto,0) + COALESCE(orgao.atividade,0) + COALESCE(orgao.especiais,0) AS total
		  FROM cte_orgaos orgao
		  UNION ALL
		  SELECT unidade_orcamentaria.codigo
			  , unidade_orcamentaria.nome
			  , unidade_orcamentaria.projeto
			  , unidade_orcamentaria.atividade
			  , unidade_orcamentaria.especiais
			  , COALESCE(unidade_orcamentaria.projeto,0) + COALESCE(unidade_orcamentaria.atividade,0) + COALESCE(unidade_orcamentaria.especiais,0) AS total
		  FROM cte_unidades_orcamentarias unidade_orcamentaria
		  UNION ALL
		 SELECT funcao.codigo
			  , funcao.nome
			  , funcao.projeto
			  , funcao.atividade
			  , funcao.especiais
			  , COALESCE(funcao.projeto,0) + COALESCE(funcao.atividade,0) + COALESCE(funcao.especiais,0) AS total
		  FROM cte_funcoes funcao
		  UNION ALL
		 SELECT subfuncao.codigo
			  , subfuncao.nome
			  , subfuncao.projeto
			  , subfuncao.atividade
			  , subfuncao.especiais
			  , COALESCE(subfuncao.projeto,0) + COALESCE(subfuncao.atividade,0) + COALESCE(subfuncao.especiais,0) AS total
		  FROM cte_subfuncoes subfuncao
		  UNION ALL
		 SELECT programa.codigo
			  , programa.nome
			  , programa.projeto
			  , programa.atividade
			  , programa.especiais
			  , COALESCE(programa.projeto,0) + COALESCE(programa.atividade,0) + COALESCE(programa.especiais,0) AS total
		  FROM cte_programas programa
		  UNION ALL
		 SELECT acao.codigo
			  , acao.nome
			  , acao.projeto
			  , acao.atividade
			  , acao.especiais
			  , COALESCE(acao.projeto,0) + COALESCE(acao.atividade,0) + COALESCE(acao.especiais,0)
		   FROM cte_acoes acao
		  ORDER BY 1;
		)
	end
end
