class Loa::Relatorios::QuadroDeDetalhamentoDaDespesa

	def self.dados_do_relatorio loa_atual, unidade_orcamentaria_id = 0

		dados_do_relatorio = []

		referencia_natureza_da_acao = {
			'0' => 'O',
			'1' => 'P',
			'2' => 'A',
			'9' => 'R'
		}

		if unidade_orcamentaria_id.to_i > 0
			unidades_orcamentarias = loa_atual.unidades_orcamentarias.where(id: unidade_orcamentaria_id)
		else
			unidades_orcamentarias = loa_atual.unidades_orcamentarias
		end

		total_geral = 0

		unidades_orcamentarias.includes(:orgao).order("loa_orgaos.codigo, loa_unidades_orcamentarias.codigo ").each do |unidade|
			programas_por_unidade_orcamentaria =  unidade.programas_de_governo
			fontes_totais = Array.new

			dados_dos_programas = []
			total_geral = 0
			programas_por_unidade_orcamentaria.order(:codigo).each { |programa|
				total_geral += programa.valor_total_fixado_da_despesa_por_unidade(unidade).to_f
					dados_dos_programas << {
						especificacao: programa.codigo_e_nome,
						natureza:'',
						fr: '',
						iduso: '',
						detalhado: '',
						total: programa.valor_total_fixado_da_despesa_por_unidade(unidade)
					}.delete_if {|key, value| key == :iduso && !loa_atual.trabalhar_com_iduso}

					programa.subacoes.where(unidade_orcamentaria_id: unidade.id).sort_by {|subacao| subacao.acao.codigo_completo }.each { |subacao|
						fontes = Array.new
						orcamentos = Array.new
						acao = subacao.acao

						subacao.metas_fisicas.each { |meta_fisica|
							if meta_fisica.present?
								dados_dos_programas << {
											especificacao: meta_fisica.produto_da_meta_fisica,
											natureza: '',
											fr: '',
											iduso: '',
											detalhado: '',
											total: meta_fisica.total_realizado_da_meta_fisica,
											fontes: fontes,
											orcamentos: orcamentos,
											estilo: { tabulacao: {posicoes:[2], quantidade: 45}}
										}.delete_if {|key, value| key == :iduso && !loa_atual.trabalhar_com_iduso}
							end
						}

						subacao.elementos_de_despesa_por_subacao.each { |despesa|
							despesa.orcamentos_da_despesa.each { |orcamento|
								if fontes_totais.any? {|f| f[:codigo] == orcamento.fonte_de_recursos.codigo_completo}
									fontes_totais.select {|f| f[:codigo] == orcamento.fonte_de_recursos.codigo_completo }.first[:valor] += orcamento.valor.to_f
								else
									fontes_totais << {
										codigo: orcamento.fonte_de_recursos.codigo_completo,
										codigo_e_descricao: 'Total fontes',
										valor: orcamento.valor.to_f
									}
								end

								if fontes.any? {|f| f[:codigo] == orcamento.fonte_de_recursos.codigo_completo}
									fontes.select {|f| f[:codigo] == orcamento.fonte_de_recursos.codigo_completo }.first[:valor] += orcamento.valor.to_f
								else
									fontes << {
										especificacao: despesa.elemento_de_despesa.descricao,
										codigo: orcamento.fonte_de_recursos.codigo_completo,
										codigo_e_descricao: orcamento.fonte_de_recursos.codigo_e_descricao,
										valor: orcamento.valor.to_f,
										estilo: { tabulacao: { posicoes: [0], quantidade: 2 }}
									}
								end
								orcamentos << {
									especificacao: despesa.elemento_de_despesa.descricao,
									natureza: despesa.elemento_de_despesa.codigo_formatado,
									fr: orcamento.fonte_de_recursos.codigo_completo,
									iduso: orcamento.read_attribute('iduso'),
									detalhado: orcamento.valor,
									total: despesa.valor_total,
									estilo: { tabulacao: { posicoes: [1], quantidade: 2 }}
								}.delete_if {|key, value| key == :iduso && !loa_atual.trabalhar_com_iduso}
							}
						}
						dados_dos_programas << {
									especificacao: acao.codigo_e_nome,
									natureza: '',
									fr: '',
									iduso: '',
									detalhado: '',
									total: subacao.fixacao_da_despesa,
									fontes: fontes,
									orcamentos: orcamentos,
									estilo: { tabulacao: { posicoes: [1], quantidade: 2 }}
								}.delete_if {|key, value| key == :iduso && !loa_atual.trabalhar_com_iduso}
					}

				dados_dos_programas.last.try(:delete, :adicionar_linha)
			}

			dados_do_relatorio << {
				orgao: unidade.orgao.codigo_e_nome,
				nome: unidade.codigo_completo_e_nome,
				programas: dados_dos_programas,
				fontes_totais: fontes_totais,
				total_geral: total_geral.to_f
			} if dados_dos_programas.any?
		end

		dados_do_relatorio << {
			label: "TOTAL GERAL",
			soma_total: total_geral
		}

		return dados_do_relatorio
	end
end
