module Contabilidade
	class EstornosDeLiquidacaoController < ApplicationController
		include ControllerConcern
		include Contabilidade::LiquidacaoHelper
		include EstornosDeLiquidacaoHelper

		before_action -> { verifica_modulo_na_sessao(["administrativo", "contabilidade", "controladoria"]) }
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!
		before_action :set_liquidacao, only: [:new, :create]
		before_action :set_estorno_de_liquidacao, except: [:index, :new, :create, :destroy, :receber_varios_itens, :confirmar_varios_itens]
		before_action :recupera_liquidacao, only: [:destroy]
		before_action -> {verifica_mes_bloqueado(@estorno_de_liquidacao)}, only: [:edit, :destroy]
		before_action -> { redirect_back(fallback_location: root_path, alert: 'Não é possível estornar uma liquidação de restos a pagar processada') if (@liquidacao&.restos_a_pagar? && @liquidacao&.empenho&.data_do_empenho&.year.to_i == @liquidacao&.data_da_liquidacao&.year.to_i) }, only: [:new, :create]

		def index
			@q =
			if params[:a_receber].present?
				@url_estornos = a_receber_contabilidade_estornos_de_liquidacao_path
				contexto_atual.estornos_de_liquidacao.enviado_para_contabilidade.search(params[:q])
			elsif params[:a_confirmar].present?
				@url_estornos = a_confirmar_contabilidade_estornos_de_liquidacao_path
				contexto_atual.estornos_de_liquidacao.recebido.search(params[:q])
			else
				@url_estornos = contabilidade_estornos_de_liquidacao_path
				contexto_atual.estornos_de_liquidacao.search(params[:q])
			end
			@modelo_estorno_de_liquidacao = Contabilidade::EstornoDeLiquidacao.new
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
			@estornos_de_liquidacao = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		end

		# GET MODULO/liquidacoes/:liquidacao_id/estorno_de_liquidacao/new
		def new
			if @liquidacao.confirmado_ou_acima? == false && @liquidacao.estornada? == false
				if logado_na_contabilidade?
					redirect_to @liquidacao, alert: 'Liquidação já possui pagamento, portanto não pode ser estornada.'
				elsif logado_no_administrativo?
					redirect_to administrativo_liquidacao_path(@liquidacao), alert: 'Liquidação já possui pagamento, portanto não pode ser estornada.'
				else
					redirect_to :back, alert: 'Só é possivel estornar liquidações confirmadas.'
				end
			elsif @liquidacao.estornada?
				if logado_na_contabilidade?
					redirect_to @liquidacao, alert: 'Liquidação já foi estornada.'
				elsif logado_no_administrativo?
					redirect_to administrativo_liquidacao_path(@liquidacao), alert: 'Liquidação já foi estornada.'
				else
					redirect_to :back, alert: 'Liquidação já foi estornada.'
				end
			elsif @liquidacao.pagamentos.where(estornado: false).any?
				if logado_na_contabilidade?
					redirect_to @liquidacao, alert: 'Liquidação já possui pagamento, portanto não pode ser estornada.'
				elsif logado_no_administrativo?
					redirect_to administrativo_liquidacao_path(@liquidacao), alert: 'Liquidação já possui pagamento, portanto não pode ser estornada.'
				else
					redirect_to :back, alert: 'Liquidação já possui pagamento, portanto não pode ser estornada.'
				end
			else
				@estorno_de_liquidacao = Contabilidade::EstornoDeLiquidacao.new(liquidacao_id: @liquidacao.id)
			end
		end

		# POST MODULO/liquidacoes/:liquidacao_id/estorno_de_liquidacao/new
		def create
			@estorno_de_liquidacao = Contabilidade::EstornoDeLiquidacao.new(estorno_de_liquidacao_params.merge(liquidacao_id: @liquidacao.id))
			@estorno_de_liquidacao.usuario_id = current_usuario.try(:id)
			if logado_na_contabilidade?
				@estorno_de_liquidacao.status = Contabilidade::EstornoDeLiquidacao.status[:confirmado]
			else
				@estorno_de_liquidacao.status = Contabilidade::EstornoDeLiquidacao.status[:solicitado]
			end

			if @estorno_de_liquidacao.save
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@liquidacao.estorno_de_liquidacao), notice: "Foi criada uma Solicitação de Estorno de Liquidação com sucesso"
				else
					redirect_to contabilidade_estorno_de_liquidacao_path(@liquidacao.estorno_de_liquidacao), notice: "Estorno de Liquidação criado com sucesso"
				end
			else
				render :new
			end
		end

		# GET MODULO/liquidacoes/:liquidacao_id/estorno_de_liquidacao
		def show
		end

		# GET MODULO/liquidacoes/:liquidacao_id/estorno_de_liquidacao/edit
		def edit
		end

		# PATCH MODULO/liquidacoes/:liquidacao_id/estorno_de_liquidacao/edit
		def update
			if estorno_de_liquidacao_params.nil? || @estorno_de_liquidacao.update(estorno_de_liquidacao_params)
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'O Estorno de Liquidação foi editado com sucesso.'
				elsif logado_na_contabilidade?
					redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'O Estorno de Liquidação foi editado com sucesso.'
				end
			else
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), alert: "Falha em editar o Estorno de Liquidação."
				elsif logado_na_contabilidade?
					redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), alert: "Falha em editar o Estorno de Liquidação."
				end
			end
		end

		# DELETE /contabilidade/estornos_de_liquidacao/:id
		def destroy
			mensagem = apaga_e_retorna_mensagem(@liquidacao.estorno_de_liquidacao)
			redirect_to rota_liquidacao(@liquidacao), mensagem
		end

		#PATCH MODULO/liquidacao/:liquidacai_id/enviar_para_contabilidade
		def enviar_para_contabilidade
			if @estorno_de_liquidacao.enviado_para_contabilidade!
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Estorno de Liquidação enviado para a Contabilidade com sucesso'
				end
			else
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), alert: 'Não foi possível enviar o Estorno de Liquidação para a Contabilidade'
				end
			end
		end

		# PATCH MODULO/liquidacao/:liquidacao_id/estorno_de_liquidacao/confirmar
		def receber_estorno_de_liquidacao
			if @estorno_de_liquidacao.receber!
				redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Estorno de Liquidação foi Recebido com sucesso'
			else
				redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Não foi possível receber o Estorno da Liquidação'
			end
		end

		# PATCH MODULO/liquidacao/:liquidacao_id/estorno_de_liquidacao/confirmar
		def confirmar_estorno_de_liquidacao
			if @estorno_de_liquidacao.confirmar!
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Estorno de Liquidação foi Confirmado com sucesso'
				elsif logado_na_contabilidade?
					redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Estorno de Liquidação foi Confirmado com sucesso'
				end
			else
				if logado_no_administrativo?
					redirect_to administrativo_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Não foi possível confirmar o Estorno da Liquidação'
				elsif logado_na_contabilidade?
					redirect_to contabilidade_estorno_de_liquidacao_path(@estorno_de_liquidacao), notice: 'Não foi possível confirmar o Estorno da Liquidação'
				end
			end
		end

		# PATCH MODULO/liquidacao/:liquidacao_id/estorno_de_liquidacao/
		def retornar_para_solicitado
			if @estorno_de_liquidacao.solicitado!
				if logado_na_contabilidade?
					redirect_to estorno_de_liquidacao_path(liquidacao_id: @estorno_de_liquidacao.liquidacao), notice: 'Estorno de Liquidação retornando para o Administrativo com sucesso'
				end
			else
			end
		end

		# POST /estornos_de_liquidacao/receber_varios_itens
		def receber_varios_itens
			estornos_de_liquidacao = params[:contabilidade_estorno_de_liquidacao]
			recebidas = Array.new
			erros = Set.new
			quantidade_enviada = 0
			ActiveRecord::Base.transaction do
				estornos_de_liquidacao.each do |chave, valor|
					if valor.to_i == 1
						quantidade_enviada += 1
						if Contabilidade::EstornoDeLiquidacao.find(chave.to_s.to_i).receber!
							recebidas << chave.to_s.to_i
						else
							estorno_de_liquidacao.errors.full_messages.each do |erro|
								erros << erro
							end
							raise ActiveRecord::Rollback
						end
					end
				end
			end

			if recebidas.size == 0
				if erros.size == 0
					redirect_to a_receber_contabilidade_estornos_de_liquidacao_path, alert: "Nenhum Estorno de Liquidação foi recebido"
				else
					redirect_to a_receber_contabilidade_estornos_de_liquidacao_path, alert: "Falha ao receber Estornos de Liquidação: #{erros.to_a.join(', ')}"
				end
			elsif recebidas.size == 1
				redirect_to estorno_de_liquidacao_path(recebidas[0]), success: "Estorno de Liquidação recebido com sucesso"
			else
				redirect_to a_receber_contabilidade_estornos_de_liquidacao_path, success: "Todos #{recebidas.size} Estornos de Liquidação foram recebidas com sucesso"
			end
		end

		#POST /estornos_de_liquidacao/confirmar_varios_itens
		def confirmar_varios_itens
			estornos_de_liquidacao = params[:contabilidade_estorno_de_liquidacao]
			confirmados = Array.new
			erros = Set.new
			quantidade_enviada = 0
			ActiveRecord::Base.transaction do
				estornos_de_liquidacao.each do |chave, valor|
					if valor.to_i == 1
						quantidade_enviada += 1
						if Contabilidade::EstornoDeLiquidacao.find(chave.to_s.to_i).confirmar!
							confirmados << chave.to_s.to_i
						else
							estornos_de_liquidacao.errors.full_messages.each do |erro|
								erros << erro
							end
							raise ActiveRecord::Rollback
						end
					end
				end
			end

			if confirmados.size == 0
				if erros.size == 0
					redirect_to a_confirmar_contabilidade_estornos_de_liquidacao_path, alert: "Nenhum Estorno de Liquidação foi confirmado"
				else
					redirect_to a_confirmar_contabilidade_estornos_de_liquidacao_path, alert: "Falha ao confirmar Estornos de Liquidação: #{erros.to_a.join(', ')}"
				end
			elsif confirmados.size == 1
				redirect_to estorno_de_liquidacao_path(confirmados[0]), success: "Estrorno de Liquidação confirmado com sucesso"
			else
				redirect_to a_confirmar_contabilidade_estornos_de_liquidacao_path, success: "Todos #{confirmados.size} Estornos de Liquidação foram confirmados com sucesso"
			end
		end

		private
		def set_liquidacao
			@liquidacao = Contabilidade::Liquidacao.find( params[:liquidacao_id] )
		end

		def set_estorno_de_liquidacao
			@estorno_de_liquidacao = Contabilidade::EstornoDeLiquidacao.find(params[:id])
		end

		def recupera_liquidacao
			@liquidacao = Contabilidade::EstornoDeLiquidacao.find(params[:id]).liquidacao
		end

		# Permite apenas os parâmetros específicos
		def estorno_de_liquidacao_params
			if params[:contabilidade_estorno_de_liquidacao].present?
				params.require(:contabilidade_estorno_de_liquidacao).permit(:justificativa, :data_do_estorno)
			end
		end
end
end
