module Contabilidade
class CancelamentosDeRestosAPagarController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:empenhos_por_unidade_nao_processados, :empenhos_por_unidade_processados, :confirmar_cancelamento, :filtra_motivo_por_tipo_de_resto_a_pagar, :motivos_do_cancelamento]
	before_action :set_cancelamento_de_resto_a_pagar, only: [:show, :edit, :update, :destroy, :confirmar_cancelamento, :enviar_para_contabilidade]
	before_action :disponibiliza_dependencias, only: [:new, :create, :edit, :update, :index]

	# GET /contabilidade/cancelamentos_de_restos_a_pagar
	def index
		if query_params["restos_a_pagar_cancelados_empenho_orcamento_id_eq"].present?
			orcamento = Orcamento.find(query_params["restos_a_pagar_cancelados_empenho_orcamento_id_eq"])
		else
			orcamento = Orcamento.find_by(exercicio: exercicio_atual.to_f - 1)
		end

		@unidades_orcamentarias = orcamento.unidades_orcamentarias.order("loa_unidades_orcamentarias.codigo", "loa_unidades_orcamentarias.nome")
		@q = contexto_atual.cancelamentos_de_restos_a_pagar.ransack(params[:q])
		@cancelamentos_de_restos_a_pagar = @q.result(distinct: true).order(data: :desc).paginate(page: params[:page], per_page: 10)

		if request.format.pdf?
			titulo2 = ""
			titulo3 = ""
			if params[:q].present? && params[:q]["restos_a_pagar_cancelados_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_unidade_orcamentaria_id_eq"].present?
				unidade_orcamentaria = Loa::UnidadeOrcamentaria.find(params[:q]["restos_a_pagar_cancelados_empenho_orcamento_da_despesa_elemento_de_despesa_por_subacao_subacao_unidade_orcamentaria_id_eq"])
				titulo2 += "Unidade Orçamentária: #{unidade_orcamentaria.codigo_e_nome}"
			else
				titulo2 += "Unidade Orçamentária: CONSOLIDADO - "
			end
			if params[:q].present? && params[:q]["orcamento_dos_empenhos_id_eq"].present?
				orcamento = Orcamento.find(params[:q]["orcamento_dos_empenhos_id_eq"])
				titulo2 += "Orçamento: #{orcamento.exercicio}"
			end
			titulo3 += "De #{params[:q]["data_gteq"] rescue ''} Até #{params[:q]["data_lteq"] rescue ''} - " if params[:q].present? and (params[:q]["data_gteq"].present? || params[:q]["data_lteq"].present?)
			@cancelamentos_de_restos_a_pagar = @q.result(distinct: false).order(data: :desc)
		else
			@cancelamentos_de_restos_a_pagar = @q.result(distinct: false).order(data: :desc).paginate(page: params[:page], per_page: 10)
		end


		@configuracoes = Configuracao.last
		respond_to do |format|
			format.html
			format.json

			format.pdf do
				render pdf: "cancelamentos_de_restos_a_pagar",
				template: 'contabilidade/cancelamentos_de_restos_a_pagar/index.pdf.slim',
				orientation: 'Landscape',
				header: {
					html: {
						template: 'layouts/_cabecalho_pdf.html.slim',
						locals: { titulo1: 'Relação de Restos a Pagar' , titulo2: titulo2, titulo3: titulo3 }
					},
					spacing: 0
				},
				footer: { right: '[page]', font_size: 8 },
				disable_smart_shrinking: true,
				dpi: '96',
				margin: @configuracoes.margens_customizadas(top: 4)
			end
		end
	end

	# GET /contabilidade/cancelamentos_de_restos_a_pagar/1
	def show
	end

	# GET /contabilidade/cancelamentos_de_restos_a_pagar/new
	def new
		@cancelamento_de_resto_a_pagar = contexto_atual.cancelamentos_de_restos_a_pagar.new
	end

	# POST /contabilidade/cancelamentos_de_restos_a_pagar
	def create
		status = :solicitado
		@cancelamento_de_resto_a_pagar = contexto_atual.cancelamentos_de_restos_a_pagar.new(cancelamento_de_resto_a_pagar_params.merge(status: status))
		if params[:adicionar_todos] == "true"
			unless @cancelamento_de_resto_a_pagar.classificacao == 'individual'
				adicionar_empenhos_selecionados_pelos_filtros
			end
			disponibiliza_dependencias
			render :new
		else			
			@cancelamento_de_resto_a_pagar.usuario_id = current_usuario.id

			if @cancelamento_de_resto_a_pagar.save
				redirect_to @cancelamento_de_resto_a_pagar, notice: 'Cancelamento de restos a pagar foi criado(a) com sucesso.'
			else
				@motivos_do_cancelamento = filtra_motivo_por_tipo_de_resto_a_pagar
				disponibiliza_dependencias
				render :new
			end
		end
	end

	def edit
		@cancelamento_de_resto_a_pagar.restos_a_pagar_cancelados.build if @cancelamento_de_resto_a_pagar.restos_a_pagar_cancelados.empty?
	end

	def update
		if params[:adicionar_todos] == true
			unless @cancelamento_de_resto_a_pagar.classificacao == 'individual'
				adicionar_empenhos_selecionados_pelos_filtros
			end
			disponibiliza_dependencias
			render :edit
		else
			@cancelamento_de_resto_a_pagar.usuario_id = current_usuario.id

			if @cancelamento_de_resto_a_pagar.update( cancelamento_de_resto_a_pagar_params )
				redirect_to @cancelamento_de_resto_a_pagar, notice: 'Cancelamento foi atualizado com sucesso.'
			else
				flash.now[:alert] = 'Não foi possível atualizar o cancelamento, verifique as informações.'
				disponibiliza_dependencias
				render :edit
			end
		end
	end

	def adicionar_empenhos_selecionados_pelos_filtros
		@cancelamento_de_resto_a_pagar.restos_a_pagar_cancelados = []

		orcamento_selecionado = ::Orcamento.find(@cancelamento_de_resto_a_pagar.orcamento_dos_empenhos_id)
		unidades_orcamentarias_vinculadas = Loa::UnidadeOrcamentariaVinculada.where(unidade_orcamentaria_id: @cancelamento_de_resto_a_pagar.unidade_orcamentaria_id, orcamento_id: orcamento_selecionado.id).pluck(:unidade_orcamentaria_vinculada_id)
		ransack_params = {}
		#ransack_params["valor_gteq"] = @cancelamento_de_resto_a_pagar.valor_minimo if @cancelamento_de_resto_a_pagar.valor_minimo.present?
		#ransack_params["valor_lteq"] = @cancelamento_de_resto_a_pagar.valor_maximo if @cancelamento_de_resto_a_pagar.valor_maximo.present?
		ransack_params["pessoa_id_eq"] = @cancelamento_de_resto_a_pagar.fornecedor_id if @cancelamento_de_resto_a_pagar.fornecedor_id.present?
		ransack_params["orcamento_da_despesa_fonte_de_recurso_id_eq"] = @cancelamento_de_resto_a_pagar.fonte_de_recurso_id if @cancelamento_de_resto_a_pagar.fonte_de_recurso_id.present?

		q = Contabilidade::Empenho.confirmados.de_restos_a_pagar.ransack(ransack_params)

		if @cancelamento_de_resto_a_pagar.tipo == 'processado'
			if @cancelamento_de_resto_a_pagar.valor_minimo.present? || @cancelamento_de_resto_a_pagar.valor_maximo.present?
				empenhos = q.result.where(unidade_orcamentaria_id: unidades_orcamentarias_vinculadas).map { |emp| emp if emp.saldo_processado > 0 && emp.saldo_processado >= @cancelamento_de_resto_a_pagar.valor_minimo.to_d && emp.saldo_processado <= @cancelamento_de_resto_a_pagar.valor_maximo.to_d }.compact
			else
				empenhos = q.result.where(unidade_orcamentaria_id: unidades_orcamentarias_vinculadas).map { |emp| emp if emp.saldo_processado > 0 }.compact
			end
		elsif @cancelamento_de_resto_a_pagar.tipo == 'nao_processado'
			if @cancelamento_de_resto_a_pagar.valor_minimo.present? || @cancelamento_de_resto_a_pagar.valor_maximo.present?
				empenhos = q.result.where(unidade_orcamentaria_id: unidades_orcamentarias_vinculadas).map { |emp| emp if emp.saldo_atual_nao_processado > 0 && emp.saldo_atual_nao_processado >= @cancelamento_de_resto_a_pagar.valor_minimo.to_d && emp.saldo_atual_nao_processado <= @cancelamento_de_resto_a_pagar.valor_maximo.to_d }.compact
			else
				empenhos = q.result.where(unidade_orcamentaria_id: unidades_orcamentarias_vinculadas).map { |emp| emp if emp.saldo_atual_nao_processado > 0 }.compact
			end
		end

		empenhos.each do |empenho|
			if @cancelamento_de_resto_a_pagar.restos_a_pagar_cancelados.find_by(empenho: empenho).nil?
				@cancelamento_de_resto_a_pagar.restos_a_pagar_cancelados.build(
					empenho_id: empenho.id,
					saldo_original: @cancelamento_de_resto_a_pagar.tipo == 'processado' ? empenho.saldo_processado : empenho.saldo_atual_nao_processado
				)
			end
		end
	end

	def confirmar_cancelamento
		return if bloqueia_usuario_com_base_em 'create'
		if @cancelamento_de_resto_a_pagar.confirmar!
			redirect_to contabilidade_cancelamento_de_resto_a_pagar_path(@cancelamento_de_resto_a_pagar), success: 'O Cancelamento foi confirmado com sucesso.'
		else
			redirect_to contabilidade_cancelamento_de_resto_a_pagar_path(@cancelamento_de_resto_a_pagar), alert: 'Não foi possível confirmar o cancelamento. Por favor, confira se ele contém erros.'
		end
	end

	def enviar_para_contabilidade
		return if bloqueia_usuario_com_base_em 'create'
		if @cancelamento_de_resto_a_pagar.enviar_para_contabilidade!
			redirect_to contabilidade_cancelamento_de_resto_a_pagar_path, success: 'O Cancelamento foi enviado para a contabilidade.'
		else
			redirect_to contabilidade_cancelamento_de_resto_a_pagar_path(@cancelamento_de_resto_a_pagar), alert: 'Não foi possível encaminhar o cancelamento. Por favor, confira se ele contém erros'
		end
	end

	def disponibiliza_dependencias
		@tipos_do_cancelamento = Contabilidade::CancelamentoDeRestoAPagar.tipos
		@motivos_do_cancelamento = Contabilidade::CancelamentoDeRestoAPagar.motivos
		@classificacoes_do_cancelamento = Contabilidade::CancelamentoDeRestoAPagar.classificacoes
		@orcamentos = Orcamento.all.order(exercicio: :desc).where("orcamentos.exercicio < ?", contexto_atual.exercicio)
		@unidades_orcamentarias = contexto_atual.unidades_orcamentarias

		if @cancelamento_de_resto_a_pagar.present?
			unidades_orcamentarias_vinculadas = Loa::UnidadeOrcamentariaVinculada.where(unidade_orcamentaria_id: @cancelamento_de_resto_a_pagar.unidade_orcamentaria_id, orcamento_id: @cancelamento_de_resto_a_pagar.orcamento_dos_empenhos_id).pluck(:unidade_orcamentaria_vinculada_id)
			empenhos = Contabilidade::Empenho.confirmados.de_restos_a_pagar.where(orcamento_id: @cancelamento_de_resto_a_pagar.orcamento_dos_empenhos_id).where(unidade_orcamentaria_id: unidades_orcamentarias_vinculadas)

			if @cancelamento_de_resto_a_pagar.tipo == 'processado'
				@empenhos = empenhos.map { |emp| emp if emp.saldo_atual_processado > 0 }.compact
			elsif @cancelamento_de_resto_a_pagar.tipo == 'nao_processado'
				@empenhos = empenhos.map { |emp| emp if emp.saldo_atual_nao_processado > 0 || emp&.restos_a_pagar_cancelados&.map{ |rp_cancelado| rp_cancelado&.cancelamento_de_resto_a_pagar&.id}&.include?(@cancelamento_de_resto_a_pagar&.id) && action_name == 'edit' }.compact
			end
		else
			@empenhos = []
		end

		@fontes_de_recursos = []
		@fornecedores = Base::Pessoa.fornecedores.all
	end

	def destroy
		mensagem = apaga_e_retorna_mensagem(@cancelamento_de_resto_a_pagar)
		redirect_to contabilidade_cancelamentos_de_restos_a_pagar_path, mensagem
	end

	def motivos_do_cancelamento
		tipo = params[:tipo_de_cancelamento]
		@motivos = []
		if tipo == 'nao_processado'
			@motivos = Contabilidade::CancelamentoDeRestoAPagar.motivos_i18n.reject { |key| key == 'valores_e_ou_inscricoes_indevidas'}
		elsif tipo == 'processado'
			@motivos = Contabilidade::CancelamentoDeRestoAPagar.motivos_i18n.reject { |key| key == 'insuficiencia_de_saldo_financeiro'}
		end

		respond_to do |format|
			format.json {render json: @motivos}
		end

	end

	private
	def set_cancelamento_de_resto_a_pagar
		@cancelamento_de_resto_a_pagar = CancelamentoDeRestoAPagar.find( params[:id] )
	end

	def filtra_motivo_por_tipo_de_resto_a_pagar
		if @cancelamento_de_resto_a_pagar.nao_processado?
			Contabilidade::CancelamentoDeRestoAPagar.motivos_i18n.reject { |key| key == 'inscricoes_indevidas'}
		elsif @cancelamento_de_resto_a_pagar.processado?
			Contabilidade::CancelamentoDeRestoAPagar.motivos_i18n.reject { |key| key == 'insuficiencia_de_saldo_financeiro'}
		else
			Array.new
		end
	end

	# Permite apenas os parâmetros específicos
	def cancelamento_de_resto_a_pagar_params
		params.require(:contabilidade_cancelamento_de_resto_a_pagar).permit(:data, :decreto, :status, :tipo, :motivo, :classificacao, :empenho_id, :orcamento_id, :unidade_orcamentaria_id, :orcamento_dos_empenhos_id, :valor_minimo, :valor_maximo, :fornecedor_id,
			restos_a_pagar_cancelados_attributes: [:id, :cancelamento_de_resto_a_pagar_id, :empenho_id, :saldo_original, :saldo_atual, :valor_cancelado, :_destroy, :descrimina_itens]
		)
	end
end
end
