module Base
	class ReceitasStnController < ApplicationController
		include ControllerConcern
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!
		before_action :disponibiliza_dependencias

		def index
			@q = orcamento_atual.receitas_stn.where(analitica: true).order(:codigo).search(params[:q])
			@receitas_stn = @q.result(distinct: false).paginate(page: params[:page], per_page: 20)
		end

		def selecionar_receita_para_importar
			return if bloqueia_usuario_com_base_em 'importar_receita_stn'
			@natureza_da_receita = Base::NaturezaDaReceita.new
		end

		# usado no modal
		def pesquisa
			@q = orcamento_atual.receitas_stn.search(params[:q])
			render layout: false
		end

		# usado no modal
		def resultado
			params[:q][:codigo_cont] = params[:q][:codigo_cont].gsub('.', '') if params[:q][:codigo_cont].present?
			@q = orcamento_atual.receitas_stn.where(analitica: true).order(:codigo).search(params[:q])
			@receitas_stn = @q.result(distinct: false).paginate(page: params[:page], per_page: 7)
			render layout: false
		end

		def importar_receita_stn
			if configuracoes_receita_params[:id].present?
				receita_analitica_stn = contexto_atual.receitas_stn.find(configuracoes_receita_params[:id])
				codigos_das_receitas_a_serem_adicionadas = receita_analitica_stn.codigos_da_hierarquia.uniq

				ActiveRecord::Base.transaction do
					begin
						codigos_das_receitas_a_serem_adicionadas.each do |codigo|
							receita_stn = contexto_atual.receitas_stn.find_by(codigo: codigo)
							if receita_stn
								receita_stn.codigo = '00' + receita_stn.codigo + '0000'
								if !receita_stn.codigo[0..2].eql?("009")
									receita_stn.codigo += '00'
								end
								resultado_criacao = criar_novas_receitas(receita_stn)
								unless resultado_criacao[0]
									raise ActiveRecord::Rollback, resultado_criacao[1]
								end
							end
						end

						receita_analitica_stn.niveis_opcionais_stn.each do |nivel_opcional|
							receita_stn = {
								codigo: '00' + receita_analitica_stn.codigo + nivel_opcional.codigo,
								descricao: nivel_opcional.descricao,
								sigla: nivel_opcional.sigla,
								id: receita_analitica_stn.id
							}

							criar_novas_receitas(receita_stn)
						end
					rescue Exception => e
						@natureza_da_receita.receita_stn_id = configuracoes_receita_params[:id]
						flash[:alert] = e.message
						render :selecionar_receita_para_importar
						return false
					end
				end

				if @natureza_da_receita.try(:valid?)
					if manter_form_apos_cadastro?
						redirect_to base_selecionar_receitas_stn_path, notice: 'Natureza da receita importada com sucesso.'
					else
						redirect_to base_naturezas_da_receita_path(modulo: contexto_atual.class.to_s.downcase, exercicio: contexto_atual.exercicio), notice: 'Natureza da receita criada com sucesso.'
					end
				else
					render :selecionar_receita_para_importar
				end
			else
				redirect_to base_selecionar_receitas_stn_path, alert: 'Selecione uma receita.'
			end
		end

		private

		def criar_novas_receitas receita_stn
			configuracoes_receita = configuracoes_receita_params
			replicar_parametros = replicacao_de_receita_params
			mensagem = ""

			atributos_natureza_da_receita = {
				id: nil,
				novo_tipo: true,
				codigo: receita_stn[:codigo],
				descricao: receita_stn[:descricao],
				sigla: receita_stn[:sigla],
				padrao: true,
				tipo_de_deducao_id: orcamento_atual.tipos_de_deducao.find_by(codigo:'00').id,
				receita_stn_id: receita_stn[:id],
				codigo_referencia: receita_stn[:codigo],
				de_convenio: receita_stn[:de_convenio]
			}

			receita = configuracoes_receita.merge(atributos_natureza_da_receita)

			@natureza_da_receita = orcamento_atual.naturezas_da_receita.new(receita)

			# marca natureza como revisada caso o orçamento já esteja encerrado
			@natureza_da_receita.forma_de_adicao = :revisado if orcamento_atual.aprovado?

			if !orcamento_atual.naturezas_da_receita.find_by(codigo: @natureza_da_receita.codigo).present?
				unless @natureza_da_receita.save
					if @natureza_da_receita.errors[:codigo].include?('já está em uso')
						mensagem << "Receita principal já havia sido importada. "
						return false, mensagem
					else
						mensagem << "Não foi possível criar a receita principal."
						return false, mensagem
					end
				end
				
				if replicar_parametros[:deducao].present? && replicar_parametros[:tipo_de_deducao_id].present?
					nova_receita = Marshal.load(Marshal.dump(receita))
					unless criar_receita_de_deducao(nova_receita, replicar_parametros[:tipo_de_deducao_id])
						mensagem << "Não foi possível criar a receita de dedução."
						return false, mensagem
					end
				end

				if replicar_parametros[:intra_orcamentaria].present?
					nova_receita = Marshal.load(Marshal.dump(receita))
					unless criar_receita_intraorcamentaria(nova_receita)
						mensagem << "Não foi possível criar a receita intra-orçamentária."
						return false, mensagem
					end
				end

				if replicar_parametros[:deducao_intra].present? && replicar_parametros[:tipo_de_deducao_intra_id].present?
					nova_receita = Marshal.load(Marshal.dump(receita))
					unless criar_receita_de_deducao_intra(nova_receita, replicar_parametros[:tipo_de_deducao_intra_id])
						mensagem << "Não foi possível criar a receita intra-orçamentária."
						return false, mensagem
					end
				end

				return true, mensagem
			end
			return true, mensagem
		end

		def disponibiliza_dependencias
			@receitas_stn = contexto_atual.receitas_stn.where(analitica: true).order(:codigo)
			@sub_contas = contexto_atual.sub_contas_pcasp.divida_ativa
			@tipos_de_orcamento = orcamento_atual.tipos_de_orcamento
			@tipos_de_deducao = orcamento_atual.tipos_de_deducao.where.not(codigo: '00').order("codigo ASC")
			@contas_extras_orcamentarias = contexto_atual.contas_extra_orcamentarias
		end

		def criar_receita_de_deducao receita, tipo_de_deducao_id
			tipo_de_deducao = orcamento_atual.tipos_de_deducao.find(tipo_de_deducao_id)
			receita[:id] = nil
			receita[:codigo][0..1] = tipo_de_deducao.codigo
			receita[:tipo_de_deducao_id] = tipo_de_deducao.id

			receita.merge!(parametros_nil_receita_intra_deducao)

			nova_receita = orcamento_atual.naturezas_da_receita.new(receita)

			if nova_receita.save || receita[:codigo][9] == '0'
				return true
			else
				@natureza_da_receita.errors[:tipo_de_deducao_id] = 'já está em uso'
				return false
			end
		end

		def criar_receita_intraorcamentaria receita
			receita[:id] = nil
			receita[:tipo_de_deducao_id] = Loa::TipoDeDeducao.find_by(codigo: '00').id
			receita[:codigo][0..1] = '00'
			receita[:codigo][2] = Base::NaturezaDaReceita.codigo_da_nova_receita_intra_orcamentaria(receita[:codigo])
			receita.merge!(parametros_nil_receita_intra_deducao)

			nova_receita = orcamento_atual.naturezas_da_receita.new(receita)
			if nova_receita.save || receita[:codigo][9] == '0'
				return true
			else
				@natureza_da_receita.errors[:tipo_intra_orcamentaria] = 'já está em uso'
				return false
			end
		end

		def criar_receita_de_deducao_intra receita, tipo_de_deducao_id
			tipo_de_deducao = orcamento_atual.tipos_de_deducao.find(tipo_de_deducao_id)
			receita[:id] = nil
			receita[:codigo][0..1] = tipo_de_deducao.codigo
			receita[:codigo][2] = Base::NaturezaDaReceita.codigo_da_nova_receita_intra_orcamentaria(receita[:codigo])
			receita[:tipo_de_deducao_id] = tipo_de_deducao.id
			receita.merge!(parametros_nil_receita_intra_deducao)

			nova_receita = orcamento_atual.naturezas_da_receita.new(receita)
			if nova_receita.save || receita[:codigo][9] == '0'
				return true
			else
				@natureza_da_receita.errors[:tipo_de_deducao_intra_id] = 'já está em uso'
				return false
			end
		end

		def parametros_nil_receita_intra_deducao
			{
				de_convenio: false,
				percentual_de_aplicacao_na_educacao:nil,
				percentual_de_aplicacao_na_saude:nil,
				pedir_cadastro_de_convenio:false,
				percentual_para_legislativo:nil,
				evento_contabil_obrigatorio: false,
				historico_padrao: nil
			}
		end

		def configuracoes_receita_params
			params.require(:base_natureza_da_receita).permit(
				:id,
				:tipo_de_receita,
				:tipo_de_orcamento_id,
				:de_convenio,
				:percentual_de_aplicacao_na_educacao,
				:percentual_de_aplicacao_na_saude,
				:pedir_cadastro_de_convenio,
				:percentual_para_legislativo,
				:evento_contabil_obrigatorio,
				:legislacao_da_receita,
				:historico_padrao,
				:conta_extra_orcamentaria_id,
				:sub_conta_pcasp_id
			)
		end

		def replicacao_de_receita_params
			params.permit(
				:tipo_de_deducao_id,
				:deducao,
				:intra_orcamentaria,
				:deducao_intra,
				:tipo_de_deducao_intra_id
			)
		end
	end

end
