module Contabilidade
class LotesBancariosController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!, except: [:imprimir, :remover_item, :finalizar, :cancelar, :reabrir, :download]
	before_action :set_lote_bancario, only: [:show, :edit, :update, :destroy, :download, :imprimir, :remover_item, :finalizar, :reabrir, :cancelar]
	before_action :disponibiliza_dependencias, only: [:new, :edit]

	# GET /contabilidade/lotes_bancarios
	def index

		@q = Contabilidade::LoteBancario.order("created_at desc").search(params[:q])
		@lotes_bancarios = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
		
		@contas_bancarias = Base::ContaBancaria.where(id: Contabilidade::LoteBancario.select(:conta_bancaria_id).distinct.pluck(:conta_bancaria_id).compact).all
	end

	# GET /contabilidade/lotes_bancarios/1
	def show
	end

	# GET /contabilidade/lotes_bancarios/new
	def new
		@lote_bancario = Contabilidade::LoteBancario.new

		@lote_bancario.tipo = params[:tipo].to_sym if params[:tipo].present?
		@lote_bancario.periodo_inicial = params[:periodo_inicial] if params[:periodo_inicial].present?
		@lote_bancario.periodo_final = params[:periodo_final] if params[:periodo_final].present?
		@lote_bancario.conta_bancaria_id = params[:conta_bancaria_id] if params[:conta_bancaria_id].present?
		@lote_bancario.data_do_lote = params[:data_do_lote] if params[:data_do_lote].present?
		@lote_bancario.envio_ao_banco = params[:envio_ao_banco] if params[:envio_ao_banco].present?

		gerar_lista_de_itens_do_lote
	end

	# GET /contabilidade/lotes_bancarios/1/edit
	def edit
		@lote_bancario.periodo_inicial = params[:periodo_inicial] if params[:periodo_inicial].present?
		@lote_bancario.periodo_final = params[:periodo_final] if params[:periodo_final].present?

		if params[:recarregar].to_boolean
			@lote_bancario.pagamentos_do_lote_bancario = @lote_bancario.pagamentos_do_lote_bancario.select(&:persisted?)
			gerar_lista_de_itens_do_lote
		end
	end

	def gerar_lista_de_itens_do_lote
		if @lote_bancario.tipo.present? && @lote_bancario.conta_bancaria.present? #&& @lote_bancario.pagamentos_do_lote_bancario.size == 0
			if @lote_bancario.pagamento?
				@lote_bancario.gerar_lista_de_pagamentos
				@lote_bancario.gerar_lista_de_retencoes
			elsif @lote_bancario.transferencia?
				@lote_bancario.gerar_lista_de_transferencias
			elsif @lote_bancario.despesa_extra?
				@lote_bancario.gerar_lista_de_despesas_extra
			end
		end
	end

	# POST /contabilidade/lotes_bancarios
	def create
		ActiveRecord::Base.transaction do
			@lote_bancario = Contabilidade::LoteBancario.new(lote_bancario_params)
			
			if @lote_bancario.save
				redirect_to @lote_bancario, notice: 'Lote bancario foi criado(a) com sucesso.'
			else
				disponibiliza_dependencias
				render :new
			end
		end
	end

	# PATCH/PUT /contabilidade/lotes_bancarios/1
	def update
		ActiveRecord::Base.transaction do
			if @lote_bancario.update( lote_bancario_params )
				redirect_to @lote_bancario, notice: 'Lote bancario foi atualizado(a) com sucesso.'
			else
				disponibiliza_dependencias
				render :edit
			end
		end
	end

	# DELETE /contabilidade/lotes_bancarios/1
	def destroy
		ActiveRecord::Base.transaction do
			mensagem = apaga_e_retorna_mensagem(@lote_bancario)
			redirect_to contabilidade_lotes_bancarios_url, mensagem
		end
	end
	
	def remover_item
		return if bloqueia_usuario_com_base_em 'create'
		
		pagamento_do_lote_bancario = @lote_bancario.pagamentos_do_lote_bancario.find(params[:pagamento_do_lote_bancario_id])

		if pagamento_do_lote_bancario.present?
			if pagamento_do_lote_bancario.destroy
				redirect_to @lote_bancario, success: "Item removido com sucesso."
			else
				redirect_to @lote_bancario, notice: "Ocorreu um erro na tentativa de remover o item."
			end
		else
			redirect_to @lote_bancario, notice: "Item não encontrado."
		end
	end

	def gerar_lotes
		@gerador_de_lote_bancario = Contabilidade::GeradorDeLoteBancario.new
	end

	def gera_lotes
		@gerador_de_lote_bancario = Contabilidade::GeradorDeLoteBancario.new(gerador_de_lote_bancario_params)
		@gerador_de_lote_bancario.validate
		
		if @gerador_de_lote_bancario.valid? && @gerador_de_lote_bancario.gerar_lotes
			redirect_to contabilidade_lotes_bancarios_path, notice: 'Lote(s) bancario(s) gerado(s) com sucesso.'
		else
			render :gerar_lotes
		end
	end

	def download
		return if bloqueia_usuario_com_base_em 'create'
		
		file = File.open("tmp/#{@lote_bancario.numero}.rem", "w")
		file.write @lote_bancario.texto_para_arquivo.encode('ASCII', invalid: :replace, undef: :replace, replace: "_")
		file.close
		@lote_bancario.update_attribute(:quantidade_de_downloads, @lote_bancario.quantidade_de_downloads.to_i + 1)
		send_data(File.read(file), type: "application/text", disposition:  "attachment", filename: "#{@lote_bancario.numero}.rem")
	end

	def imprimir
		relatorio = "documento"

		if respond_to? relatorio.to_s, :private
			loa = CombinePDF.new
			loa << CombinePDF.parse(send(relatorio))
			send_data loa.to_pdf, filename: "#{relatorio}_#{@lote_bancario.numero}.pdf", type: "application/pdf", disposition: 'inline'
		else
			redirect_to :back, alert: 'Demonstrativo selecionado não existe'
		end
	end

	def cancelar
		return if bloqueia_usuario_com_base_em 'create'
		
		@lote_bancario.update_attribute(:status, :cancelado)
		if @lote_bancario.gerado?
			redirect_to @lote_bancario, success: "Lote finalizado com sucesso."
		else
			redirect_to @lote_bancario, alert: "Lote já estava finalizado/cancelado."
		end
	end

	def reabrir
		return if bloqueia_usuario_com_base_em 'create'
		
		if @lote_bancario.finalizado?
			@lote_bancario.update_attribute(:status, :gerado)
			redirect_to @lote_bancario, success: "Lote reaberto com sucesso."
		else
			redirect_to @lote_bancario, alert: "Lote não está finalizado."
		end
	end

	def finalizar
		return if bloqueia_usuario_com_base_em 'create'

		if @lote_bancario.gerado?
			@lote_bancario.update_attribute(:status, :finalizado)
			redirect_to @lote_bancario, success: "Lote finalizado com sucesso."
		else
			redirect_to @lote_bancario, alert: "Lote já estava finalizado/cancelado."
		end
	end

	private
	def documento
		@nome_da_cidade = Configuracao.last.nome_da_cidade
		render_to_string pdf: "lote_de_pagamento",
			template: "contabilidade/lotes_bancarios/lote_de_pagamento.pdf.slim",
			orientation: 'Portrait',
			disable_smart_shrinking: true,

			dpi: '96',
			page_size: 'A4',
			header: {
				html: {
					template: 'layouts/_cabecalho_pdf.html.slim',
					locals: {
						titulo1: "Relatório de Lote Bancário",
						titulo2: "Lote #{@lote_bancario.numero} - #{@lote_bancario.data_do_lote}"
					}
				},
				spacing: 4
			},
			footer: {
				html: {
					template: 'layouts/_rodape_pdf.html.slim'
				}
			},
			margin: { top: 35, bottom: 10, left: 10, right: 10 }
	end

	def set_lote_bancario
		@lote_bancario = LoteBancario.find( params[:id] )
	end

	def disponibiliza_dependencias
		@contas_bancarias = Base::ContaBancaria.all
		#@agencias = Base::Agencia.includes(:banco).order(:numero_da_agencia)
		@envios_ao_banco = Contabilidade::LoteBancario.envios_ao_banco
		@tipos = Contabilidade::LoteBancario.tipos
	end

	# Permite apenas os parâmetros específicos
	def lote_bancario_params
		params.require(:contabilidade_lote_bancario).permit(:numero, :data_do_lote, :periodo_inicial, :periodo_final, :agencia_id, :envio_ao_banco, :convenio_bancario_id, :conta_bancaria_id, :tipo, pagamentos_do_lote_bancario_attributes:[:id, :transferencia_financeira_id, :pagamento_da_retencao_id, :conta_bancaria_por_pagamento_id, :despesa_extra_orcamentaria_id, :_destroy])
	end

	def gerador_de_lote_bancario_params
		params.require(:contabilidade_gerador_de_lote_bancario).permit(:tipo, pagamentos_ids: [], envios_ao_banco: [])
	end

	def definir_valor_inicial_numero_do_lote
		"#{Contabilidade::LoteBancario.count + 1}".rjust(5, '0')
	end

end
end
