module Tcm
class LotesController < ApplicationController
	include ControllerConcern
	before_action :authenticate_usuario!
	before_action :autoriza_usuario!,except: [:download_arquivos_do_lote, :processar_todos, :bloquear_para_geracao_do_sim]
	before_action :set_lote, only: [:show, :edit, :update, :destroy,:download_arquivos_do_lote, :processar_todos, :finalizar, :validar]

	# GET /tcm/lotes
	def index

		if logado_na_contabilidade?
			@q = Lote.where(orcamento: contexto_atual).where(tipo: :contabilidade).where("coalesce(situacao, 0) != 8").order("id DESC").ransack(query_params)
		else
			@q = Lote.where(orcamento: contexto_atual).where("coalesce(situacao, 0) != 8").order("id DESC").ransack(query_params)
		end
		disponibiliza_dependencias
		@lotes = @q.result(distinct: false).paginate(page: params[:page], per_page: 10)
	end

	# GET /tcm/lotes/1
	def show
	end

	# GET /tcm/lotes/new
	def new
		orcamento = Orcamento.find_by( exercicio: params[:exercicio] )
		@lote = orcamento.lotes_do_tcm.new
		disponibiliza_dependencias

		if Configuracao.first.codigo_do_municipio_no_tcm.blank?
			redirect_to tcm_lotes_url(contexto_atual), alert: "O Código do município no TCM não foi informado, acesse configurações para adicionar essa informação."
		elsif orcamento.numero_da_lei.blank? || orcamento.data_de_envio.blank? || orcamento.data_de_aprovacao.blank? || orcamento.data_de_publicacao.blank?
			#redirect_to tcm_lotes_url(orcamento_atual), alert: "Orçamento não está aprovado, confira o número da lei e datas de aprovação no cadastro de Orçamento."
		end
	end

	def edit
	end

	def processar_todos
		bloqueia_usuario_com_base_em 'create'

		begin
			if params[:todos].present? && params[:todos] == 'false'
				arquivos = @lote.arquivos.pendente.order(:nome)
			else
				arquivos = @lote.arquivos.order(:nome)
			end
			arquivos.each do |arquivo|
				arquivo.processar
			end
			configuracao.update_column(:bloqueio_geral, :nao_bloqueado)

			if @lote.arquivo_de_porte_grande?
				PrincipalMailer.arquivo_tcm_processado(@lote, current_usuario.email.to_s.strip).deliver_later unless current_usuario.email.empty?
			end

			redirect_to @lote, notice: 'Lote processado com sucesso.'
		rescue
			redirect_to @lote, notice: 'Houve um erro ao processar o lote.'
		end
	end
	
	def bloquear_para_geracao_do_sim
		bloqueia_usuario_com_base_em 'create'

		begin
			@lote = Lote.find( params[:id] )
			ActionCable.server.broadcast('general_channel', message: 'A geração do SIM será iniciada em 5 minutos, o sistema ficará bloqueado até o término da operação.')

			## BLOQUEIA O SISTEMA SOMENTE 5 MINUTOS DEPOIS DO CLIQUE DO BOTÃO
			#Thread.new do
				#sleep(5.minutes) # Espera 5 minutos
				configuracao.update_column(:bloqueio_geral, :bloqueado_para_o_sim)
			#end

			redirect_to @lote, notice: 'Sistema Bloqueado com sucesso.'
		rescue
			redirect_to @lote, notice: 'Um erro ocorreu na tentativa de bloquear o sistema.'
		end
	end

	def download_arquivos_do_lote
		respond_to do |format|
			format.zip do
				compressed_filestream = Zip::OutputStream.write_buffer do |zos|
					@lote.arquivos.select{ |i| i.qtd_de_linhas > 0}.each do |arquivo|
						zos.put_next_entry "#{arquivo.nome}"
						zos.print arquivo.conteudo
					end
				end
				compressed_filestream.rewind
				descricao = Tcm::Lote.mes_de_referencias[@lote.mes_de_referencia].digitos(2) << "_" << @lote.orcamento.exercicio.to_s
				send_data compressed_filestream.read, filename: "Arquivos_SIM_#{descricao}_#{@lote.tipo_de_poder.downcase}.zip"
			end
		end
	end

	# POST /tcm/lotes
	def create
		orcamento = Orcamento.find_by( exercicio: params[:exercicio] )
		@lote = orcamento.lotes_do_tcm.new(lote_params)
		begin
			if @lote.save
				redirect_to @lote, notice: 'Lote foi criado com sucesso.'
			else
				disponibiliza_dependencias
				render :new
			end
		rescue => e
			flash[:alert] = "Alguns erros foram encontrados."
			disponibiliza_dependencias
			render :new
		end
	end

	def update
		if @lote.update(lote_params)
			redirect_to tcm_lote_path(@lote) + "?tab=arquivos_importados", notice: 'Configurações atualizadas com sucesso'
		else
			disponibiliza_dependencias
			flash[:alert] = "Erro ao atualizar o lote. Verifique os campos."
			render :edit
		end
	end

	# DELETE /tcm/lotes/1
	def destroy
		@lote.situacao = 8 #cancelado
		if @lote.save
			@lote.limpa_arquivos
			redirect_to tcm_lotes_url(exercicio: contexto_atual.exercicio), notice: 'Lote cancelado com sucesso.'
		else
			redirect_to :back, error: "Não foi possível cancelar o lote."
		end
	end

	def finalizar
		return if bloqueia_usuario_com_base_em 'show'

		if @lote.gerado? || @lote.pendente?
			@lote.situacao = 9 #finalizado
			if @lote.save(validate: false)
				redirect_to @lote, notice: 'Lote finalizado com sucesso.'
			else
				redirect_to @lote, error: "Não foi possível finalizar o lote."
			end
		else
			redirect_to @lote, error: "Não foi possível finalizar o lote, pois o mesmo já está cancelado ou finalizado."
		end
	end

	def validar
		return if bloqueia_usuario_com_base_em 'create'

		if @lote.pendente?
			@lote.validar
			redirect_to @lote, notice: 'Lote validado com sucesso.'
		else
			redirect_to @lote, error: "Não foi possível validar o lote, pois o mesmo já está cancelado ou finalizado."
		end
	end

	def criar_lote_individual
		@lote = Tcm::Lote.new
		@metodos_sim = @lote.metodos_que_geram_sim.to_a.sort
		@meses = Tcm::Lote.mes_de_referencias.collect { |t| ["#{t[1]} - #{Date::MONTHNAMES[t[1]]}", t[0]] }
	end

	def salvar_lote_individual
		@lote = Tcm::Lote.new(lote_params)
		@lote.orcamento_id = contexto_atual.id

		if @lote.save
			redirect_to @lote, notice: 'Lote foi criado com sucesso.'
		else
			@metodos_sim = @lote.metodos_que_geram_sim.to_a
			@meses = Tcm::Lote.mes_de_referencias.collect { |t| ["#{t[1]} - #{Date::MONTHNAMES[t[1]]}", t[0]] }
			redirect_to criar_lote_individual_path, alert: @lote.errors.full_messages.join(',')
		end
	end

	private
	def set_lote
		@lote = Lote.find( params[:id] )
	end

	def disponibiliza_dependencias
		@orcamentos = Orcamento.order("exercicio DESC").all
		if current_usuario.desenvolvedor? || current_usuario.ambos?
			@tipos_de_poderes = Tcm::Lote.tipos_de_poder
		else
			@tipos_de_poderes = Tcm::Lote.tipos_de_poder.reject { |i| i != cookies[:poder] }
		end

		if logado_na_contabilidade?
			tipos_contabilidade = ['contabilidade']
			@tipos = Tcm::Lote.tipos.select{|tipo| tipos_contabilidade.include?(tipo)}
		else
			@tipos = Tcm::Lote.tipos
		end
		@meses_de_referencia = Tcm::Lote.mes_de_referencias
	end

	# Permite apenas os parâmetros específicos
	def lote_params
		params.require(:tcm_lote).permit(:orcamento_id, :tipo, :situacao, :mes_de_referencia, :lote, :gerando_lote_individual, 
		:tipo_de_poder, arquivos_attributes: [:id, :nome, :importado, :doc, :_destroy])
	end
end
end
