module Contabilidade
class EventosContabeisController < ApplicationController
	include ContabilidadeControllerConcern
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, only: [:index, :show, :new, :edit, :create, :update, :destroy]
	before_action :set_evento_contabil, only: [:show, :edit, :update, :destroy, :lancamento_manual, :adiciona_dotacao, :salvar_dotacao, :atualiza_dotacao, :adiciona_receita, :salvar_receita, :atualiza_receita, :editar_contas, :atualizar_contas]
	before_action :disponibiliza_dependencias, only: [:index, :new, :create, :edit, :update]

	# GET /contabilidade/eventos_contabeis
	def index
		if request.format.json?
			if params[:conta_debito_id].present? && params[:conta_credito_id].present?
				tipo_debito = Contabilidade::MovimentacaoDoPlanoDeContas.tipo_de_lancamentos[:debito]
				tipo_credito = Contabilidade::MovimentacaoDoPlanoDeContas.tipo_de_lancamentos[:credito]

				@q = contexto_atual.eventos_contabeis.joins(sql_joins_por_contas).where(ativo: true).where(sql_filtro_por_contas, tipo_debito, params[:conta_debito_id], tipo_credito, params[:conta_credito_id]).search(params[:q])
			else
				@q = contabilidade_atual.eventos_contabeis.where(ativo: true).order(:id).search(params[:q])
			end
		else
			@q = contabilidade_atual.eventos_contabeis.where(ativo: true).order(:id).search(params[:q])
			@eventos_contabeis = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		end

		respond_to do |format|
			format.html
			format.json { render json: @q.result(distinct: true).includes(:contas_por_eventos_contabeis), methods: [:contas_por_eventos_contabeis, :grupo_de_evento_contabil] }
		end
	end

	# GET /contabilidade/eventos_contabeis/1
	def show
		@exibir_alerta_contexto = self.send(:exibir_alerta_de_contexto?, nil, nil, @evento_contabil.orcamento)
	end

	# GET /contabilidade/eventos_contabeis/new
	def new
		if params[:acao_do_sistema_id].present?
			@evento_contabil = contabilidade_atual.eventos_contabeis.new(acao_do_sistema_id: params[:acao_do_sistema_id])
		else
			@evento_contabil = contabilidade_atual.eventos_contabeis.new
		end
	end

	# GET /contabilidade/eventos_contabeis/1/edit
	def edit
	end

	# POST /contabilidade/eventos_contabeis
	def create
		@evento_contabil = contabilidade_atual.eventos_contabeis.new(evento_contabil_params)

		if @evento_contabil.save
			redirect_to @evento_contabil, notice: 'Evento contabil foi criado(a) com sucesso.'
		else
			render :new
		end
	end

	# PATCH/PUT /contabilidade/eventos_contabeis/1
	def update
		if @evento_contabil.update( evento_contabil_params )
			redirect_to @evento_contabil, notice: 'Evento contabil foi atualizado(a) com sucesso.'
		else
			render :edit
		end
	end

	# DELETE /contabilidade/eventos_contabeis/1
	def destroy
		mensagem = apaga_e_retorna_mensagem(@evento_contabil)
		redirect_to contabilidade_eventos_contabeis_url(contabilidade_atual), mensagem
	end

	# GET /contabilidade/eventos_contabeis/1/lancamento_manual
	def lancamento_manual
		return if bloqueia_usuario_com_base_em 'create'
		@unidades_orcamentarias = contabilidade_atual.unidades_orcamentarias.ordenado_por_orgao
		@lancamento_manual = @evento_contabil.lancamentos_manuais_do_evento_contabil.build
	end

	# POST /contabilidade/eventos_contabeis/1/cria_lancamento_manual
	def cria_lancamento_manual
		@evento_contabil = Contabilidade::EventoContabil.find(params[:id])
		@lancamento_manual = Contabilidade::LancamentoManualDoEventoContabil.new(data_de_lancamento: Date.today, evento_contabil: @evento_contabil)
		@lancamento_manual.assign_attributes(lancamento_manual_params)
		if @lancamento_manual.save
			redirect_to contabilidade_evento_contabil_path(@evento_contabil), notice: 'Lançamento manual realizado com sucesso.'
		else
			@unidades_orcamentarias = contabilidade_atual.unidades_orcamentarias.ordenado_por_orgao
			render :lancamento_manual
		end
	end

	# POST /contabilidade/eventos_contabeis/1/adiciona_dotacao
	def adiciona_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		if params[:dotacao_id].present? && !params[:dotacao_id].nil?
			@orcamento_da_despesa_por_evento_contabil = @evento_contabil.orcamentos_da_despesa_por_evento_contabil.find(params[:dotacao_id])
		else
			@orcamento_da_despesa_por_evento_contabil = @evento_contabil.orcamentos_da_despesa_por_evento_contabil.new
		end
		carrega_select_box_dotacao
	end

	# POST /contabilidade/eventos_contabeis/1/salvar_dotacao
	def salvar_dotacao
		@orcamento_da_despesa_por_evento_contabil = @evento_contabil.orcamentos_da_despesa_por_evento_contabil.new(dotacao_params)
		if @orcamento_da_despesa_por_evento_contabil.save
			redirect_path = contabilidade_evento_contabil_path(@evento_contabil, tab: "dotacoes_do_evento_contabil")
			redirect_to redirect_path, success: 'Dotação foi adicionada com sucesso.'
		else
			carrega_select_box_dotacao
			render :adiciona_dotacao
		end
	end

	# POST /contabilidade/eventos_contabeis/1/atualiza_dotacao
	def atualiza_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		@orcamento_da_despesa_por_evento_contabil = @evento_contabil.orcamentos_da_despesa_por_evento_contabil.find(dotacao_params[:id])
		if @orcamento_da_despesa_por_evento_contabil.update(dotacao_params)
			redirect_path = contabilidade_evento_contabil_path(@evento_contabil, tab: "dotacoes_do_evento_contabil")
			redirect_to redirect_path, success: 'Dotação foi atualizada com sucesso.'
		else
			carrega_select_box_dotacao
			render :adiciona_dotacao
		end
	end

	# DELETE /contabilidade/eventos_contabeis/excluir_dotacao/1
	def excluir_dotacao
		return if bloqueia_usuario_com_base_em 'update'
		orcamento_da_despesa_por_evento_contabil = Contabilidade::OrcamentoDaDespesaPorEventoContabil.find(params[:orcamento_da_despesa_por_evento_contabil_id])
		mensagem = apaga_e_retorna_mensagem(orcamento_da_despesa_por_evento_contabil)
		redirect_to contabilidade_evento_contabil_path(orcamento_da_despesa_por_evento_contabil.evento_contabil) + "?tab=dotacoes_do_evento_contabil", mensagem
	end

	# POST /contabilidade/eventos_contabeis/1/adiciona_receita
	def adiciona_receita
		return if bloqueia_usuario_com_base_em 'update'
		if params[:receita_id].present? && !params[:receita_id].nil?
			@orcamento_da_receita_por_evento_contabil = @evento_contabil.orcamentos_da_receita_por_evento_contabil.find(params[:receita_id])
		else
			@orcamento_da_receita_por_evento_contabil = @evento_contabil.orcamentos_da_receita_por_evento_contabil.new
		end
		carrega_select_box_receita
	end

	# POST /contabilidade/eventos_contabeis/1/salvar_receita
	def salvar_receita
		@orcamento_da_receita_por_evento_contabil = @evento_contabil.orcamentos_da_receita_por_evento_contabil.new(receita_params)
		if @orcamento_da_receita_por_evento_contabil.save
			redirect_path = contabilidade_evento_contabil_path(@evento_contabil, tab: "receitas_do_evento_contabil")
			redirect_to redirect_path, success: 'Receita foi adicionada com sucesso.'
		else
			carrega_select_box_receita
			render :adiciona_receita
		end
	end

	# POST /contabilidade/eventos_contabeis/1/atualiza_receita
	def atualiza_receita
		return if bloqueia_usuario_com_base_em 'update'
		@orcamento_da_receita_por_evento_contabil = @evento_contabil.orcamentos_da_receita_por_evento_contabil.find(receita_params[:id])
		if @orcamento_da_receita_por_evento_contabil.update(receita_params)
			redirect_path = contabilidade_evento_contabil_path(@evento_contabil, tab: "receitas_do_evento_contabil")
			redirect_to redirect_path, success: 'Receita foi atualizada com sucesso.'
		else
			carrega_select_box_receita
			render :adiciona_receita
		end
	end

	# DELETE /contabilidade/eventos_contabeis/excluir_receita/1
	def excluir_receita
		return if bloqueia_usuario_com_base_em 'update'
		orcamento_da_receita_por_evento_contabil = Contabilidade::OrcamentoDaReceitaPorEventoContabil.find(params[:orcamento_da_receita_por_evento_contabil_id])
		mensagem = apaga_e_retorna_mensagem(orcamento_da_receita_por_evento_contabil)
		redirect_to contabilidade_evento_contabil_path(orcamento_da_receita_por_evento_contabil.evento_contabil) + "?tab=receitas_do_evento_contabil", mensagem
	end

	def index_grupos_dos_eventos
		@q = Contabilidade::GrupoDeEventoContabil.search(params[:q])
		resultados = @q.result
		resultados = @q.result.where(lancamento_manual: session[:lancamento_manual]) if (session[:lancamento_manual] != nil && !params[:todos].present?)

		respond_to do |format|
			if session[:lancamento_manual] == "precatorio"
				format.json { render json: @q.result.where(lancamento_manual: session[:lancamento_manual]).where("titulo IS NOT null") }
			else
				format.json { render json: @q.result.where(lancamento_manual: session[:lancamento_manual])}
			end
			format.json { render json: resultados }
		end
	end

	def atualizar_contas
		if @evento_contabil.update(evento_contabil_params)
			redirect_to @evento_contabil
		else
			render :editar_contas
		end
	end

	private
	def set_evento_contabil
		@evento_contabil = Contabilidade::EventoContabil.find( params[:id] )
	end

	def carrega_select_box_dotacao
		@elementos_de_despesa = contabilidade_atual.elementos_de_despesa.order(:codigo).distinct
		if @orcamento_da_despesa_por_evento_contabil.present? && @orcamento_da_despesa_por_evento_contabil.persisted?
			@sub_elementos_de_despesa = @orcamento_da_despesa_por_evento_contabil.sub_elemento_de_despesa.nil? ? [] : [@orcamento_da_despesa_por_evento_contabil.sub_elemento_de_despesa]
		else
			@sub_elementos_de_despesa = []
		end
	end

	def carrega_select_box_receita
		@receitas_stn = contabilidade_atual.receitas_stn.where(analitica: true).order(:codigo)
	end

	# Permite apenas os parâmetros específicos
	def evento_contabil_params
		params.require(:contabilidade_evento_contabil).permit(
			:nome, :acao_do_sistema_id, :tipo, :classe, :saldo_inicial, :descricao, :tipo_de_fornecedor, :classificacao_tipo_de_material, :ativo, :modelo, :grupo_de_evento_contabil_id,
			contas_por_eventos_contabeis_attributes:[
				:id,
				:conta_id,
				:evento_contabil_id,
				:conta_par_id,
				:tipo_de_lancamento,
				:ordem_de_lancamento,
				:utilizando_form,
				:_destroy
			]
		)
	end

	def lancamento_manual_params
		params.require(:contabilidade_lancamento_manual_do_evento_contabil).permit(:id, :valor, :unidade_orcamentaria_id, :descricao, :evento_contabil_id)
	end

	def dotacao_params
		params.require(:contabilidade_orcamento_da_despesa_por_evento_contabil).permit(:id, :sub_elemento_de_despesa_id)
	end

	def receita_params
		params.require(:contabilidade_orcamento_da_receita_por_evento_contabil).permit(:id, :receita_stn_id)
	end

	def disponibiliza_dependencias
		@classificacoes_tipo_de_material = Contabilidade::EventoContabil.classificacoes_tipo_de_material
		@acoes_do_sistema = Contabilidade::AcaoDoSistema.all.map {|acao_do_sistema|
			[
				acao_do_sistema.id,
				acao_do_sistema.codigo_e_nome,
				{
					"data-acao-codigo" => acao_do_sistema.codigo
				}
			]
		}

		@grupos_de_eventos = Contabilidade::GrupoDeEventoContabil.where("lancamento_manual > 0") rescue []
	end

	def sql_filtro_por_contas
		'(conta_debito.tipo_de_lancamento = ?
		AND conta_debito.conta_id = ?)
		AND (conta_credito.tipo_de_lancamento = ?
		AND conta_credito.conta_id = ?)'
	end
	
	def sql_joins_por_contas
		'INNER JOIN contabilidade_contas_por_eventos_contabeis AS conta_credito ON contabilidade_eventos_contabeis.id = conta_credito.evento_contabil_id 
		INNER JOIN contabilidade_contas_por_eventos_contabeis AS conta_debito ON contabilidade_eventos_contabeis.id = conta_debito.evento_contabil_id'
	end
end
end
