module Contabilidade::TalaoDaReceitaHelper
  EXCECOES = {
    '11%' => ['111250%', '1114511%', '1114512%', '111253%', '111303%'],
    '13%' => ['132101%', '132102%', '132103%', '132104%', '132105%', '132999%'],
    '17%' => ['1711511%', '1711512%', '172150%', '172151%', '171152%', '172152%', '175150%', '1715%']
  }

  CAMPOS_DESTACADOS = [
  	:'Impostos, Taxas e Contribuições de Melhoria',
  	:'Receita Patrimonial',
  	:'Transferências Correntes',
  	:'Contribuições',
  	:'Dedução de Receita para Formação do FUNDEB',
  	:'Receita Agropecuária',
  	:'Receita de Serviços',
  	:'Receita Industrial',
  	:'Contrib. do Servidor para o Plano de Previdência',
  	:'Compensação Financ. entre Regimes Previdência',
  	:'Outras Receitas Correntes',
  	:'( - ) Transferências obrigatórias da União relativas às emendas individuais (art. 166-A, § 1º, da CF) (IV)',
  	:'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DE ENDIVIDAMENTO (V) = (III - IV)',
  	:'( - ) Transferências obrigatórias da União relativas às emendas de bancada (art. 166, § 16, da CF) (VI)',
  	:'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DA DESPESA COM PESSOAL (IX) = (V - VI - VII - VIII)',
  	:"RECEITA CORRENTE LÍQUIDA (III) = (I - II)"
  ]

  @total_valor_receita_ajustada = []
  @total_calc_limite_ajustado = []

  @total_calc_limites_de_endividamento = 0
  @total_calc_limites_da_despesa_pessoal = 0

	def buscar_sum_por_codigo(codigos, comeco_mes, fim_mes, unidade_orcamentaria, co = false)
    return busca_com_soma(codigos, comeco_mes, fim_mes, unidade_orcamentaria) unless co

    busca_soma_por_fonte_de_recursos(codigos, comeco_mes, fim_mes, unidade_orcamentaria)
  end

  def lista_nr
  	{ 	
  		'RECEITA CORRENTES (I)': ['111250%', '1114511%', '1114512%', '111253%', '111303%', '12%', '132101%', '132102%', '132103%', '132104%', '132105%', '132999%', '13%', '132101%', '132102%', '132103%', '132104%', '132105%', '132999%', '13%', '14%', '15%', '16%', '1711511%', '1711512%', '172150%', '172151%', '171152%', '172152%', '175150%', '1715%', '17%', '19%'], 
			'Impostos, Taxas e Contribuições de Melhoria': ['111250%', '1114511%', '1114512%', '111253%', '111303%'], 
			'IPTU': '111250%',  
			'ISS': ['1114511%', '1114512%'],
			'ITBI': '111253%', 
			'IRRF': '111303%', 
			'Outros Impostos, Taxas e Contribuições de Melhoria': '11%',
			'Contribuições': '12%', 'Receita Patrimonial': ['132101%', '132102%', '132103%', '132104%', '132105%', '132999%', '13%'], 
			'Rendimentos de Aplicação Financeira': ['132101%', '132102%', '132103%', '132104%', '132105%', '132999%'], 
			'Outras Receitas Patrimoniais': '13%',  
			'Receita Agropecuária': '14%', 
			'Receita Industrial': '15%', 
			'Receita de Serviços': '16%', 
			'Transferências Correntes': ['1711511%', '1711512%', '172150%', '172151%', '171152%', '172152%', '175150%', '1715%'], 
			'Cota-Parte do FPM': ['1711511%', '1711512%'], 
			'Cota-Parte do ICMS': '172150%', 
			'Cota-Parte do IPVA': '172151%', 
			'Cota-Parte do ITR': '171152%', 
			'Transferências da LC 61/1989': '172152%', 
			'Transferências do FUNDEB': ['175150%', '1715%'], 
			'Outras Transferências Correntes': '17%', 
			'Outras Receitas Correntes': '19%', 
			'DEDUÇÕES (II)': ['121501%', '121502%', '121503%', '121550%', '121551%', '199903%'],
			'Contrib. do Servidor para o Plano de Previdência': ['121501%', '121502%', '121503%', '121550%', '121551%', '95%'],
			'Compensação Financ. entre Regimes Previdência': '199903%', 
			'Dedução de Receita para Formação do FUNDEB': '95%', 
			'RECEITA CORRENTE LÍQUIDA (III) = (I - II)': nil,
			'( - ) Transferências obrigatórias da União relativas às emendas individuais (art. 166-A, § 1º, da CF) (IV)': { co: '3120', fr: nil, nr: '171%' },
			'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DE ENDIVIDAMENTO (V) = (III - IV)': nil,
			'( - ) Transferências obrigatórias da União relativas às emendas de bancada (art. 166, § 16, da CF) (VI)': { co: '3120', fr: '604', nr: '171%' },
			'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DA DESPESA COM PESSOAL (IX) = (V - VI - VII - VIII)': nil
		}
  end

  def calc_receita_corrente(receita_corrente, deducoes)
		@total_valor_receita_ajustada = receita_corrente.zip(deducoes).map { |receita, deducao| receita - deducao }
  end

  def calc_receita_corrente_ajustada(codigo)
  	@total_calc_limite_ajustado = @total_valor_receita_ajustada.zip(codigo).map { |corrente_liquida, transferencia_obrigatoria| corrente_liquida - transferencia_obrigatoria  }
  end

  def calc_limite_da_despesa_com_pessoal(uniao_relativas_as_emendas, uniao_relativas_a_remuneracao, outras_deducoes)
  	total_calc_uniao_relativa = @total_calc_limite_ajustado.zip(uniao_relativas_as_emendas).map { |limite_ajustado, uniao_relativas_as_emendas| limite_ajustado - uniao_relativas_as_emendas }
  	
  	# comentado caso outras deduções e a união relativas a remuneração entrem no relatorio para fazer o calculo
  	#total_calc_uniao_relativa = total_calc_uniao_relativa.zip(uniao_relativas_a_remuneracao).map { |limite_ajustado, uniao_relativas_a_remuneracao| limite_ajustado - uniao_relativas_a_remuneracao }

  	#total_calc_uniao_relativa.zip(outras_deducoes).map { |limite_ajustado, transferencia_obrigatoria| limite_ajustado - transferencia_obrigatoria }
  end

  def soma_previsao_atualizada(comeco_mes, fim_mes, index, unidade_orcamentaria)
    codigos = lista_nr[index]
    codigo_com_index = codigos.is_a?(Hash) ? codigos[:nr] : codigos

  	query = Loa::OrcamentoDaReceita.joins('
  		JOIN contabilidade_complementos_por_fonte_do_talao_de_receita on contabilidade_complementos_por_fonte_do_talao_de_receita.orcamento_da_receita_id = loa_orcamentos_da_receita.id
  		JOIN contabilidade_taloes_de_receita on contabilidade_taloes_de_receita.id = contabilidade_complementos_por_fonte_do_talao_de_receita.talao_de_receita_id 
  		JOIN base_naturezas_da_receita on base_naturezas_da_receita.id = contabilidade_taloes_de_receita.natureza_da_receita_id JOIN base_receitas_stn on base_receitas_stn.id = base_naturezas_da_receita.receita_stn_id'
  	).where('contabilidade_taloes_de_receita.data_do_talao BETWEEN ? AND ? 
					  				AND base_receitas_stn.codigo LIKE ANY (ARRAY[?])', comeco_mes, fim_mes, codigo_com_index)

  	if codigos.is_a?(Hash)
  		query = query.where('AND base_fontes_stn.detalhamento_sintetico = ?', codigos[:co])
  		query = query.where.not('AND base_fontes_stn.codigo_principal = ?', codigos[:fr]) if codigos[:fr]
  	end

	 	query = query.where('contabilidade_taloes_de_receita.unidade_orcamentaria_id = ?', unidade_orcamentaria) if unidade_orcamentaria.present?
		total = query.sum(:valor) rescue 0.0
  end

  def soma_receitas_e_deducoes(comeco_mes, fim_mes, unidade_orcamentaria)
  	receita_corrente = :"RECEITA CORRENTES (I)"
  	deducao = :"DEDUÇÕES (II)"
  	
  	total_receitas = soma_previsao_atualizada(comeco_mes, fim_mes, receita_corrente, unidade_orcamentaria)
  	total_deducoes = soma_previsao_atualizada(comeco_mes, fim_mes, deducao, unidade_orcamentaria)

    @total_calc_limites_de_endividamento = total_receitas - total_deducoes
  end

  def soma_previsao_receita_corrente_liquida(comeco_mes, fim_mes, unidade_orcamentaria)
  	uniao_relativa_as_emendas_individuais = :'( - ) Transferências obrigatórias da União relativas às emendas individuais (art. 166-A, § 1º, da CF) (IV)'

  	total_uniao_relativa_as_emendas_individuais = soma_previsao_atualizada(comeco_mes, fim_mes, uniao_relativa_as_emendas_individuais, unidade_orcamentaria)

  	@total_calc_limites_da_despesa_pessoal = @total_calc_limites_de_endividamento - total_uniao_relativa_as_emendas_individuais
  end

  def soma_previsao_limite_da_despesa_com_pessoal(comeco_mes, fim_mes, unidade_orcamentaria)
  	emendas_de_bancada = :'( - ) Transferências obrigatórias da União relativas às emendas de bancada (art. 166, § 16, da CF) (VI)'

  	total_uniao_relativa_as_emendas_individuais = soma_previsao_atualizada(comeco_mes, fim_mes, emendas_de_bancada, unidade_orcamentaria)

  	@total_calc_limites_da_despesa_pessoal - total_uniao_relativa_as_emendas_individuais
  end

  def campo_destacado? campo
  	CAMPOS_DESTACADOS.include?(campo)
  end

  def campos_estilizados key
  	campos = {
  		:'RECEITA CORRENTES (I)' => { class: nil, style: "font-weight: bold;" },
      :'Impostos, Taxas e Contribuições de Melhoria' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Receita Patrimonial' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Transferências Correntes' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'DEDUÇÕES (II)' => { class: nil, style: "font-weight: bold;" },
      :'Contribuições' => { class: "rgf_destaque", style: "padding-left: 10px;"},
      :'Dedução de Receita para Formação do FUNDEB' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Receita Agropecuária' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Receita Industrial' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Receita de Serviços' => { class: "rgf_destaque", style: "padding-left: 10px;"},
      :'Contrib. do Servidor para o Plano de Previdência' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Compensação Financ. entre Regimes Previdência' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'Outras Receitas Correntes' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'RECEITA CORRENTE LÍQUIDA (III) = (I - II)' => { class: "rgf_destaque", style: "font-weight: bold;" },
      :'( - ) Transferências obrigatórias da União relativas às emendas individuais (art. 166-A, § 1º, da CF) (IV)' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DE ENDIVIDAMENTO (V) = (III - IV)' => { class: "rgf_destaque", style: "font-weight: bold;" },
      :'( - ) Transferências obrigatórias da União relativas às emendas de bancada (art. 166, § 16, da CF) (VI)' => { class: "rgf_destaque", style: "padding-left: 10px;" },
      :'RECEITA CORRENTE LÍQUIDA AJUSTADA PARA CÁLCULO DOS LIMITES DA DESPESA COM PESSOAL (IX) = (V - VI - VII - VIII)' => { class: "rgf_destaque", style: "padding-left: 10px; font-weight: bold;" }
  	}

  	return campos[key] if campos.include?(key)

  	nil
  end

  private

  def busca_soma_por_fonte_de_recursos(codigos, comeco_mes, fim_mes, unidade_orcamentaria)
  	query = Contabilidade::ComplementoPorFonteDoTalaoDeReceita
  				  .joins(
					    contabilidade_taloes_de_receita: {
					      natureza_da_receita: :receita_stn
					    },
					    orcamento_da_receita: {
					      fonte_de_recursos: :fonte_stn
					    }
					  ).where('contabilidade_taloes_de_receita.data_do_talao BETWEEN ? AND ? 
					  				AND base_receitas_stn.codigo LIKE ANY (ARRAY[?])
					  				AND base_fontes_stn.detalhamento_sintetico = ?', comeco_mes, fim_mes, codigos[:nr], codigos[:co])

		query = query.where.not('AND base_fontes_stn.codigo_principal = ?', codigos[:fr]) if codigos[:fr]
		query = query.where('contabilidade_taloes_de_receita.unidade_orcamentaria_id = ?', unidade_orcamentaria) if unidade_orcamentaria.present?

		query.sum(:valor) rescue 0.0
  end

  def busca_com_soma(codigos, comeco_mes, fim_mes, unidade_orcamentaria)
  	query = Contabilidade::TalaoDeReceita
     	.joins(
	    	natureza_da_receita: :receita_stn,
   	 		complementos_por_fonte_do_talao_de_receita: { orcamento_da_receita: { fonte_de_recursos: :fonte_stn } }
		  )
      .where(
        'contabilidade_taloes_de_receita.data_do_talao BETWEEN ? AND ? 
        AND base_receitas_stn.codigo LIKE ANY (ARRAY[?])',
        comeco_mes,
        fim_mes,
        codigos
      )

   	query = query.where('NOT (base_receitas_stn.codigo LIKE ANY (ARRAY[?]))', EXCECOES[codigos]) if excecoes_presentes?(codigos)
   	query = query.where('contabilidade_taloes_de_receita.unidade_orcamentaria_id = ?', unidade_orcamentaria) if unidade_orcamentaria.present?

   	query.sum(:valor) rescue 0.0
  end

  def excecoes_presentes?(codigo)
    EXCECOES.keys.include?(codigo)
  end

  def calcular_receita_corrente(lista_nr, data, data_final, unidade_orcamentaria)
 	 	keys_to_sum = [
	    'Impostos, Taxas e Contribuições de Melhoria',
	    'Receita Patrimonial',
	    'Receita Agropecuária',
	    'Receita Industrial',
	    'Receita de Serviços',
	    'Transferências Correntes',
	    'Outras Transferências Correntes'
	  ]

	  total = 0
	  keys_to_sum.each do |key|
	    total += buscar_sum_por_codigo(lista_nr[key], data, data_final, unidade_orcamentaria) if lista_nr[key]
	  end
	  total
	end
end
