class Base::ElementosDeDespesaController < ApplicationController
	include LoaControllersConcern
	include ControllerConcern

	skip_before_action :verifica_se_sessao_eh_de_contabilidade, only: [:tipo_preferencial_de_credor, :retorna_codigo], raise: false
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:configurar_elemento_de_despesa_update, :retorna_codigo]

	before_action :set_contexto, only: [:index, :new, :create, :edit, :update, :configurar_elemento_de_despesa, :configurar_elemento_de_despesa_update]
	before_action :set_base_elemento_de_despesa, only: [:edit, :update, :configurar_elemento_de_despesa, :configurar_elemento_de_despesa_update, :vincular_matriz, :atualizar_matriz]
	before_action :disponibiliza_dependencias, only: [:new, :edit]
	before_action :bloquear_orcamento, only: [:new, :edit, :destroy, :configurar_elemento_de_despesa, :escolher_elementos_de_despesa]

	def index
		@categorias_economicas = @contexto.categorias_economicas.selecionados.order(:codigo)
	end

	def new
		@elemento_de_despesa = Tableless::ElementoDeDespesa.new
	end

	def lista_de_elementos
		@categorias_economicas = @contexto.categorias_economicas.order(:codigo)
	end

	def escolher_elementos_de_despesa
		return if bloqueia_usuario_com_base_em 'lista_de_elementos'
		@elemento_de_despesa = Base::ElementoDeDespesa.find(params[:id] )
		if @elemento_de_despesa
			if @elemento_de_despesa.exibir_elemento_de_despesa == true
				@pode_ser_removido = @elemento_de_despesa.sub_elementos_de_despesa.count > 0 || @elemento_de_despesa.elementos_de_despesa_por_subacao.count > 0 || @elemento_de_despesa.orcamentos_da_despesa.count > 0 ? false : true

				if @pode_ser_removido
					@elemento_de_despesa.exibir_elemento_de_despesa = false
					@elemento_de_despesa.save(validate: false)
				end
			else
				@pode_ser_removido = true
				@elemento_de_despesa.exibir_elemento_de_despesa = true
				@elemento_de_despesa.save(validate: false)
			end
		end
		respond_to do |format|
			format.js {}
		end
	end

	def create
		@elemento_de_despesa = Tableless::ElementoDeDespesa.new( elemento_de_despesa_params )
		if @elemento_de_despesa.valid? && @elemento_de_despesa.gerar_elemento_de_despesa( @contexto )
			redirect_to base_elementos_de_despesa_path(modulo: @contexto.class.to_s.downcase, exercicio: @contexto.exercicio), notice: "Elemento de despesa cadastrado com sucesso."
		else
			disponibiliza_dependencias
			render :new
		end
	end

	def edit
		categoria_economica = NaturezaDaDespesa::CategoriaEconomica.find_by_codigo(@base_elemento_de_despesa.codigo[0])
		base_elemento_de_despesa_params = {
			categoria_economica_id:  categoria_economica.id,
			grupo_de_natureza_da_despesa_id: NaturezaDaDespesa::GrupoDeNaturezaDaDespesa.find_by(codigo: @base_elemento_de_despesa.codigo[1]).id,
			modalidade_de_aplicacao_id: NaturezaDaDespesa::ModalidadeDeAplicacao.find_by_codigo(@base_elemento_de_despesa.codigo[2..3] ).id,
			elemento_de_despesa_id: @base_elemento_de_despesa.elemento_de_gasto.id
		}
		@elemento_de_despesa = Tableless::ElementoDeDespesa.new( base_elemento_de_despesa_params )
		@grupos_de_natureza_da_despesa = NaturezaDaDespesa::CategoriaEconomica.find( base_elemento_de_despesa_params[:categoria_economica_id] ).grupos_de_natureza_da_despesa.order(:codigo)
	end

	def update
		@elemento_de_despesa = Tableless::ElementoDeDespesa.new( elemento_de_despesa_params )

		if @elemento_de_despesa.valid? && @elemento_de_despesa.gerar_elemento_de_despesa( @contexto, @base_elemento_de_despesa )
			redirect_to base_elementos_de_despesa_path(modulo: @contexto.class.to_s.downcase, exercicio: @contexto.exercicio), notice: "Elemento de despesa atualizado com sucesso."
		else
			disponibiliza_dependencias
			@grupos_de_natureza_da_despesa = elemento_de_despesa_params[:categoria_economica_id].present? ? NaturezaDaDespesa::CategoriaEconomica.find( elemento_de_despesa_params[:categoria_economica_id] ).grupos_de_natureza_da_despesa.order(:codigo) : []
			render :edit
		end
	end

	def retornar_grupos_de_despesa
		@grupos_de_natureza_da_despesa = NaturezaDaDespesa::GrupoDeNaturezaDaDespesa.where(categoria_economica_id: params[:classificacao_da_despesa_id]).order(:codigo)

		respond_to do |format|
			format.json { render json: @grupos_de_natureza_da_despesa, methods: :codigo_e_descricao }
			format.js
		end
	end

	def retorna_sub_elementos
		@sub_elementos_do_elemento = NaturezaDaDespesa::ElementoDeDespesa.find(params[:elemento_de_despesa_id]).sub_elementos_de_despesa.order(:codigo)

		respond_to do |format|
			format.json { render json: @sub_elementos_do_elemento, methods: :codigo_e_descricao }
			format.js
		end
	end

	def retorna_elementos_por_acao_do_contingenciamento
		fonte_de_recursos = Contabilidade::Contigenciamento.find(params[:contingenciamento_id]).fonte_de_recurso
		@elementos_por_acao_do_contingenciamento = Loa::Acao.find(params[:acao_id]).elementos_de_despesa
			.joins(:orcamentos_da_despesa).where(loa_orcamentos_da_despesa: { fonte_de_recursos_id: fonte_de_recursos.id })
			.where(exibir_elemento_de_despesa: true).distinct.order(:codigo)

		respond_to do |format|
			format.json { render json: @elementos_por_acao_do_contingenciamento, methods: :codigo_e_descricao }
		end
	end

	def tipo_preferencial_de_credor
		@elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.find( params[:id] )
		respond_to do |format|
			format.json { render json:
				{
					pessoa_fisica: @elemento_de_despesa_por_subacao.elemento_de_despesa.preferencialmente_pessoa_fisica,
					pessoa_juridica: @elemento_de_despesa_por_subacao.elemento_de_despesa.preferencialmente_pessoa_juridica,
					codigo_elemento: @elemento_de_despesa_por_subacao.elemento_de_despesa.categoria
				}
			}
		end
	end

	def retorna_codigo
		@elemento_de_despesa_por_subacao = Loa::ElementoDeDespesaPorSubacao.find( params[:id] )
		respond_to do |format|
			format.json { render json:
				{
					codigo_elemento: @elemento_de_despesa_por_subacao.elemento_de_despesa.codigo,
				}
			}
		end
	end

	def configurar_elemento_de_despesa
		if @base_elemento_de_despesa.percentuais_mensais == nil
			@base_elemento_de_despesa.create_percentuais_mensais
		end
	end

	def configurar_elemento_de_despesa_update
		if @base_elemento_de_despesa.update( base_elemento_de_despesa_params )
			redirect_to base_elementos_de_despesa_path(modulo: @contexto.class.to_s.downcase, exercicio: @contexto.exercicio), notice: "Elemento de despesa configurado com sucesso."
		else
			render :configurar_elemento_de_despesa
		end
	end

	def vincular_matriz
		@base_elemento_de_despesa.build_sub_elementos_de_despesa_com_matriz_vinculada
	end

	def atualizar_matriz
		if @base_elemento_de_despesa.update(base_elemento_de_despesa_params)
			redirect_to base_elementos_de_despesa_path(modulo: contexto_atual.class.to_s.downcase, exercicio: contexto_atual.exercicio), notice: 'Matriz Vinculada com sucesso'
		else
			render :vincular_matriz
		end
	end

	private
	def set_contexto
		@contexto = params[:modulo].capitalize.constantize.find_by!( exercicio: params[:exercicio] )
	end

	def set_base_elemento_de_despesa
		@base_elemento_de_despesa = Base::ElementoDeDespesa.find(params[:id] )
	end

	def carrega_select_box_para_edit

	end

	def disponibiliza_dependencias
		@categorias_economicas = NaturezaDaDespesa::CategoriaEconomica.where.not(codigo: '9').order(:codigo)
		@grupos_de_natureza_da_despesa = []
		@modalidades_de_aplicacao = NaturezaDaDespesa::ModalidadeDeAplicacao.where.not(codigo: '99').order(:codigo)
		@elementos_de_despesa = NaturezaDaDespesa::ElementoDeDespesa.where.not(codigo: '99').order(:codigo)
	end

	def elemento_de_despesa_params
		params.require(:tableless_elemento_de_despesa).permit( :categoria_economica_id, :grupo_de_natureza_da_despesa_id, :modalidade_de_aplicacao_id, :elemento_de_despesa_id )
	end

	def base_elemento_de_despesa_params
		params.require(:base_elemento_de_despesa).permit(:exibir_elemento_de_despesa, :preferencialmente_pessoa_fisica, :preferencialmente_pessoa_juridica,
			:folha_de_pagamento, :despesa_financeira, :compoe_obras, :despesa_pessoal, :deducao_despesa_pessoal, :transferencia_intraorcamentaria,
			:deducao_pasep, :contabil_obrigatorio, :padrao_rpps,
			percentuais_mensais_attributes: [
				:percentual_janeiro,
				:percentual_fevereiro,
				:percentual_marco,
				:percentual_abril,
				:percentual_maio,
				:percentual_junho,
				:percentual_julho,
				:percentual_agosto,
				:percentual_setembro,
				:percentual_outubro,
				:percentual_novembro,
				:percentual_dezembro,
				:natureza_da_receita_id
			],
			sub_elementos_de_despesa_com_matriz_vinculada_attributes: [
				:id,
				:sub_elemento_de_despesa_id,
				:sub_elemento_de_despesa_da_matriz_id,
				:elemento_de_despesa_id,
				:_destroy, 
			]
		)
	end
end
