module Base
	class AlertasController < ApplicationController
		include ControllerConcern
		include TradutorConcern
		include MensagemConcern
		before_action :authenticate_usuario!
		before_action :autoriza_usuario!

		def index
			if(params[:dias].blank?)
				@dias = 15
			else
				@dias = params[:dias].to_i
			end

			if(params[:unidade_orcamentaria].blank?)
				@unidade_orcamentaria = ""
			else
				@unidade_orcamentaria = Loa::UnidadeOrcamentaria.find(params[:unidade_orcamentaria])
			end
			@data_de_hoje = Date.today
			@estoque_habilitado = ParametrizacaoModulo.find_by(nome_do_modulo: "gestao_de_estoque").permite_uso_do_modulo
			@tipo = params[:tipo]
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
			alertas_do_almoxarifado if @estoque_habilitado && (logado_no_administrativo? || logado_na_gestao_de_estoque? )

			if(@tipo.eql?("processos") || @tipo.blank?)
				@processos_homologados = pesquisar_processos_homologados(@dias, params[:unidade_orcamentaria])
			end

			if(@tipo.eql?("contratos") || @tipo.blank?)
				@vigencia_de_contratos = pesquisar_vigencia_de_contrato(params[:unidade_orcamentaria])
				@contratos_encerrados = pesquisar_contratos_encerrados(@dias, params[:unidade_orcamentaria])
			end

			if(@tipo.eql?("atas") || @tipo.blank?)
				@vigencia_de_atas_de_registro_de_precos = pesquisar_vigencia_de_atas_de_registro_de_precos(params[:unidade_orcamentaria])
				@atas_encerradas = pesquisar_atas_encerradas(@dias, params[:unidade_orcamentaria])
			end
			@dias = nil if params[:dias].blank?
		end

		def pesquisar_vigencia_de_contrato(unidade_orcamentaria)
			aditivo_confirmado = "1"
			pesquisa = "
				(
					licitacao_aditivos.fim_da_vigencia IS NOT NULL
					AND
					(
						(
							SELECT MAX(fim_da_vigencia)
							FROM licitacao_aditivos
							WHERE contrato_id =  licitacao_contratos.id
							AND fim_da_vigencia IS NOT NULL
							AND status = #{aditivo_confirmado}
						)
						BETWEEN :hoje AND :em_60_dias
					)
				)
				OR
				(
					licitacao_aditivos.fim_da_vigencia IS NULL
					AND :hoje <= licitacao_contratos.fim_da_vigencia
					AND licitacao_contratos.fim_da_vigencia <= :em_60_dias
				)"
			if(unidade_orcamentaria.blank?)
				if current_usuario.administrador?
					contratos_validos = Licitacao::Contrato.where.not(status: :rescindido).left_joins(:aditivos)
						.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
						.where( pesquisa, hoje: Date.today, em_60_dias: Date.today + 60.day).distinct.order('data_fim asc')
				else
					if current_usuario.unidades_orcamentarias.count > 0
						contratos_validos = current_usuario.contratos.where.not(status: :rescindido).left_joins(:aditivos)
						.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
						.where( pesquisa, hoje: Date.today, em_60_dias: Date.today + 60.day).distinct.order('data_fim asc')
					else
						contratos_validos = nil
					end
				end
			else
				if current_usuario.administrador? || current_usuario.contratos.ids.include?( unidade_orcamentaria )
					contratos_validos = Loa::UnidadeOrcamentaria.find(unidade_orcamentaria).contratos.where.not(status: :rescindido).left_joins(:aditivos)
						.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
						.where( pesquisa, hoje: Date.today, em_60_dias: Date.today + 60.day).distinct.order('data_fim asc')
				else
					contratos_validos = nil
				end
			end

			contratos = Hash.new
			contratos[:vigencia_5] = Set.new
			contratos[:vigencia_15] = Set.new
			contratos[:vigencia_30] = Set.new
			contratos[:vigencia_60] = Set.new
			if !contratos_validos.nil?
				contratos_validos.each { |contrato|
					if contrato.data_final_de_acordo_com_aditivos <= Date.today+5.day
						contratos[:vigencia_5] << contrato
					elsif contrato.data_final_de_acordo_com_aditivos <= Date.today+15.day
						contratos[:vigencia_15] << contrato
					elsif contrato.data_final_de_acordo_com_aditivos <= Date.today+30.day
						contratos[:vigencia_30] << contrato
					else
						contratos[:vigencia_60] << contrato
					end
				}
			end
			return contratos
		end

		def pesquisar_vigencia_de_atas_de_registro_de_precos(unidade_orcamentaria)
			if(unidade_orcamentaria.blank?)
				if current_usuario.administrador?
					atas_validas = Licitacao::AtaDeRegistroDePrecos.where(":hoje <= data_final_de_vigencia AND data_final_de_vigencia <= :em_60 AND status = :confirmado", hoje: Date.today, em_60: Date.today+60.day, confirmado: Licitacao::AtaDeRegistroDePrecos.status[:confirmado]).distinct.order(:data_final_de_vigencia)
				else
					if current_usuario.unidades_orcamentarias.count > 0
						atas_validas = current_usuario.atas_de_registro_de_precos.where(":hoje <= data_final_de_vigencia AND data_final_de_vigencia <= :em_60", hoje: Date.today, em_60: Date.today+60.day).where(status: Licitacao::AtaDeRegistroDePrecos.status[:confirmado]).distinct.order(:data_final_de_vigencia)
					else
						atas_validas = nil
					end
				end
			else
				if current_usuario.administrador?
					atas_validas = Licitacao::AtaDeRegistroDePrecos.joins(:unidades_orcamentarias_da_ata).where("licitacao_unidades_orcamentarias_da_ata.unidade_orcamentaria_id = :uo AND :hoje <= data_final_de_vigencia AND data_final_de_vigencia <= :em_60 AND status = :confirmado", uo: unidade_orcamentaria, hoje: Date.today, em_60: Date.today+60.day, confirmado: Licitacao::AtaDeRegistroDePrecos.status[:confirmado]).distinct.order(:data_final_de_vigencia)
				else
					atas_validas = nil
				end
			end

			atas = Hash.new
			atas[:vigencia_5] = Set.new
			atas[:vigencia_15] = Set.new
			atas[:vigencia_30] = Set.new
			atas[:vigencia_60] = Set.new

			if !atas_validas.nil?
				atas_validas.each { |ata|
					if ata.data_final_de_vigencia <= Date.today+5.day
						atas[:vigencia_5] << ata
					elsif ata.data_final_de_vigencia <= Date.today+15.day
						atas[:vigencia_15] << ata
					elsif ata.data_final_de_vigencia <= Date.today+30.day
						atas[:vigencia_30] << ata
					elsif ata.data_final_de_vigencia <= Date.today+60.day
						atas[:vigencia_60] << ata
					end
				}
			end

			return atas
		end

		def pesquisar_processos_homologados(dias, unidade_orcamentaria)
			pesquisa = nil
			if unidade_orcamentaria.blank?
				if current_usuario.administrador?
					pesquisa = Licitacao::Processo.joins(:pedido).where(status: Licitacao::Processo.status[:homologado]).where(":data_do_filtro <= data_da_homologacao AND data_da_homologacao <= :hoje", hoje: Date.today, data_do_filtro: Date.today - dias.day).distinct.order(data_da_homologacao: :asc)
				else
					if current_usuario.unidades_orcamentarias.count > 0
						pesquisa = current_usuario.processos.where(status: Licitacao::Processo.status[:homologado]).where(":data_do_filtro <= data_da_homologacao AND data_da_homologacao <= :hoje", hoje: Date.today, data_do_filtro: Date.today - dias.day).distinct.order(data_da_homologacao: :asc)
					else
						pesquisa = nil
					end
				end
			else
				#admin ou usuário possui esta UO
				if current_usuario.administrador? || current_usuario.unidades_orcamentarias.ids.include?( unidade_orcamentaria )
					pesquisa = Loa::UnidadeOrcamentaria.find(unidade_orcamentaria).processos.homologado.joins(:pedido).where(":data_do_filtro <= data_da_homologacao AND data_da_homologacao <= :hoje", hoje: Date.today, data_do_filtro: Date.today - dias.day).distinct.order(data_da_homologacao: :asc)
				else
					pesquisa = nil
				end
			end
			pesquisa
		end

		def alerta_almoxarifado
			@configuracoes = Configuracao.includes(:parametrizacao_modulos).last
			if(params[:dias].blank?)
				@dias = 15
			else
				@dias = params[:dias].to_i
			end
			if(params[:unidade_orcamentaria].blank?)
				@unidade_orcamentaria = ""
			else
				@unidade_orcamentaria = Loa::UnidadeOrcamentaria.find(params[:unidade_orcamentaria])
			end
			@tipo = params[:tipo]
			@unidades_orcamentarias = contexto_atual.unidades_orcamentarias
			@ordens_de_compra_atrasadas = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega <= ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.yesterday
			)
			@ordens_de_compra_hoje = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega = ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.today
			)
			@ordens_de_compra_cinco_dias = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega >= ?
				AND licitacao_ordens_de_compra.prazo_de_entrega <= ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.today + 1.day,
				Date.today + 5.day
			)
			@ordens_de_compra_quinze_dias = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega >= ?
				AND licitacao_ordens_de_compra.prazo_de_entrega <= ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.today + 6.day,
				Date.today + 15.day
			)
			@ordens_de_compra_vinte_dias = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega >= ?
				AND licitacao_ordens_de_compra.prazo_de_entrega <= ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.today + 16.day,
				Date.today + 20.day
			)
			@ordens_de_compra_trinta_dias = gestao_de_estoque_atual.ordens_de_compra.where(
				"licitacao_ordens_de_compra.status = ?
				AND licitacao_ordens_de_compra.prazo_de_entrega >= ?
				AND licitacao_ordens_de_compra.prazo_de_entrega <= ?
				",
				Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado],
				Date.today + 21.day,
				Date.today + 30.day
			)

			@requisicao_hoje = gestao_de_estoque_atual.requisicoes_de_materiais.where(
				"administrativo_requisicoes_de_materiais.status = ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao = ?
				",
				Administrativo::RequisicaoDeMaterial.status[:enviado_ao_almoxarifado],
				Date.today
			)
			@requisicoes_cinco_dias = gestao_de_estoque_atual.requisicoes_de_materiais.where(
				"administrativo_requisicoes_de_materiais.status = ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ?
				",
				Administrativo::RequisicaoDeMaterial.status[:enviado_ao_almoxarifado],
				Date.today + 1.day,
				Date.today + 5.day,
			)
			@requisicoes_quinze_dias = gestao_de_estoque_atual.requisicoes_de_materiais.where(
				"administrativo_requisicoes_de_materiais.status = ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ?
				",
				Administrativo::RequisicaoDeMaterial.status[:enviado_ao_almoxarifado],
				Date.today + 6.day,
				Date.today + 15.day,
			)
			@requisicoes_vinte_dias = gestao_de_estoque_atual.requisicoes_de_materiais.where(
				"administrativo_requisicoes_de_materiais.status = ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ?
				",
				Administrativo::RequisicaoDeMaterial.status[:enviado_ao_almoxarifado],
				Date.today + 16.day,
				Date.today + 20.day,
			)
			@requisicoes_trinta_dias = gestao_de_estoque_atual.requisicoes_de_materiais.where(
				"administrativo_requisicoes_de_materiais.status = ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
				AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ?
				",
				Administrativo::RequisicaoDeMaterial.status[:enviado_ao_almoxarifado],
				Date.today + 21.day,
				Date.today + 30.day,
			)
			@requisicoes_abertas = gestao_de_estoque_atual.requisicoes_de_materiais.where(status: Licitacao::OrdemDeCompra.status[:enviado_para_almoxarifado]).all
			@data_formatada = Date.today.strftime("%d/%m/%Y")

			@prazo_sem_movimentacao = @configuracoes.prazo_sem_movimentacao_de_material.to_i

			estoques = GestaoDeEstoque::MovimentacaoDoEstoque.where('
				(data_da_movimentacao >= ? AND quantidade_saida > 0) OR (data_da_movimentacao >= ?)', 
				(Date.today - @prazo_sem_movimentacao), (Date.today - @prazo_sem_movimentacao)).distinct.map(&:estoque_id)
			@estoque_parado = GestaoDeEstoque::Estoque.where('id not in (?)', estoques)
		end

		def alerta_patrimonio
			@configuracoes = Configuracao.last
			if @configuracoes.iniciar_fluxo_pelo_patrimonio?
				@ordens_de_compra_a_receber = Licitacao::OrdemDeCompra.joins(:empenho).where(status: :fechado, orcamento: contexto_atual)
			else
				@recebimento_de_bens_a_receber = Patrimonio::RecebimentoDeBem.where(status: :a_receber, orcamento: contexto_atual)
			end
		end

		def pesquisar_contratos_encerrados(dias, unidade_orcamentaria)
			aditivo_confirmado = "1"
			pesquisa = "
			(
				licitacao_aditivos.fim_da_vigencia is not null
				AND
				(
					(
						SELECT MAX(fim_da_vigencia)
						FROM licitacao_aditivos
						WHERE contrato_id =  licitacao_contratos.id
						AND fim_da_vigencia IS NOT NULL
						AND status = #{aditivo_confirmado}
					)
					BETWEEN :dias_atras AND :hoje
				)
			)
			OR
			(
				licitacao_aditivos.fim_da_vigencia IS NULL
				AND :dias_atras <= licitacao_contratos.fim_da_vigencia
				AND licitacao_contratos.fim_da_vigencia <= :hoje
			)"
			contratos_encerrados = nil
			if unidade_orcamentaria.blank?
				if current_usuario.administrador?
					contratos_encerrados = Licitacao::Contrato.where.not(status: :rescindido).left_joins(:aditivos)
					.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
					.where(pesquisa, dias_atras: Date.today - dias, hoje: Date.today).distinct.order('data_fim asc')
				else
					if current_usuario.unidades_orcamentarias.count > 0
						contratos_encerrados = current_usuario.contratos.where.not(status: :rescindido).left_joins(:aditivos)
						.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
						.where(pesquisa, dias_atras: Date.today - dias, hoje: Date.today).distinct.order('data_fim asc')
					else
						contratos_encerrados = nil
					end
				end
			else
				if current_usuario.administrador? || current_usuario.contratos.ids.include?( unidade_orcamentaria )
					contratos_encerrados = Loa::UnidadeOrcamentaria.find(unidade_orcamentaria).contratos.where.not(status: :rescindido).left_joins(:aditivos).where( pesquisa, dias_atras: Date.today - dias, hoje: Date.today).distinct.sort_by { |contrato| contrato.data_final_de_acordo_com_aditivos }
				else
					if current_usuario.unidades_orcamentarias.count > 0
						contratos_encerrados = current_usuario.contratos.where.not(status: :rescindido).left_joins(:aditivos)
							.select("licitacao_contratos.*, (case when licitacao_aditivos.fim_da_vigencia is null then licitacao_contratos.fim_da_vigencia else licitacao_aditivos.fim_da_vigencia end) as data_fim")
							.where(pesquisa, dias_atras: Date.today - dias, hoje: Date.today).joins(unidade_orcamentaria_por_pedido:  :unidade_orcamentaria )
							.where("loa_unidades_orcamentarias.id = :unidade_orcamentaria_id", unidade_orcamentaria_id: unidade_orcamentaria).distinct.order('data_fim asc')
					else
						contratos_encerrados = nil
					end
				end
			end
			contratos_encerrados
		end

		def pesquisar_atas_encerradas(dias, unidade_orcamentaria)
			arp = nil
			if(unidade_orcamentaria.blank?)
				if current_usuario.administrador?
					arp = Licitacao::AtaDeRegistroDePrecos.where(":data_do_filtro <= data_final_de_vigencia AND data_final_de_vigencia <= :hoje AND status = :status", hoje: Date.today, data_do_filtro: Date.today - dias.day, status: Licitacao::AtaDeRegistroDePrecos.status[:confirmado]).distinct.order(data_final_de_vigencia: :asc)
				else
					if current_usuario.unidades_orcamentarias.count > 0
						arp = current_usuario.atas_de_registro_de_precos.where(":data_do_filtro <= data_final_de_vigencia AND data_final_de_vigencia <= :hoje", hoje: Date.today, data_do_filtro: Date.today - dias.day).where(status: Licitacao::AtaDeRegistroDePrecos.status[:confirmado] ).distinct.order(data_final_de_vigencia: :asc)
					else
						arp = nil
					end
				end
			else
				if current_usuario.administrador? || current_usuario.atas_de_registro_de_precos.ids.include?( unidade_orcamentaria )
					arp = Licitacao::AtaDeRegistroDePrecos.joins(:unidades_orcamentarias_da_ata).where("licitacao_unidades_orcamentarias_da_ata.unidade_orcamentaria_id = :uo AND :data_do_filtro <= data_final_de_vigencia AND data_final_de_vigencia <= :hoje AND status = :status", uo: unidade_orcamentaria, hoje: Date.today, data_do_filtro: Date.today - dias.day, status: Licitacao::AtaDeRegistroDePrecos.status[:confirmado]).distinct.order(data_final_de_vigencia: :asc)
				else
					arp = nil
				end
			end
		end

		def alertas_do_almoxarifado
			data_inicial = Date.today - @dias
			data_final = Date.today
			@ordens_de_compra_recebidas = gestao_de_estoque_atual.ordens_de_compra.left_joins(:recebimento_de_materiais)
				.where(
					"licitacao_ordens_de_compra.status = ?
						AND gestao_de_estoque_recebimento_de_materiais.data_do_recebimento >= ?
						AND gestao_de_estoque_recebimento_de_materiais.data_do_recebimento <= ? " , Licitacao::OrdemDeCompra.status[:recebido_pelo_almoxarifado], data_inicial , data_final).all

			@ordens_de_compra_recusadas = gestao_de_estoque_atual.ordens_de_compra.where(status: :recusado_pelo_almoxarifado).all
			@recebimento_de_materiais  = gestao_de_estoque_atual.recebimento_de_materiais
				.where(
					"gestao_de_estoque_recebimento_de_materiais.data_do_recebimento >= ?
						AND gestao_de_estoque_recebimento_de_materiais.data_do_recebimento <= ?" , data_inicial , data_final).all

			@requisicoes_recebidas = gestao_de_estoque_atual.requisicoes_de_materiais
			.where(
				"administrativo_requisicoes_de_materiais.status = ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ? " , Administrativo::RequisicaoDeMaterial.status[:recebido_pelo_almoxarifado], data_inicial , data_final).all

			@requisicoes_em_atendimento = gestao_de_estoque_atual.requisicoes_de_materiais
			.where(
				"administrativo_requisicoes_de_materiais.status = ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ? ", Administrativo::RequisicaoDeMaterial.status[:em_atendimento], data_inicial , data_final).all


			@requisicoes_atendidas = gestao_de_estoque_atual.requisicoes_de_materiais
			.where(
				"administrativo_requisicoes_de_materiais.status = ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ? ", Administrativo::RequisicaoDeMaterial.status[:atendido], data_inicial , data_final).all

			@requisicoes_devolvidas = gestao_de_estoque_atual.requisicoes_de_materiais
			.where(
				"administrativo_requisicoes_de_materiais.status = ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao >= ?
					AND administrativo_requisicoes_de_materiais.data_da_requisicao <= ? ", Administrativo::RequisicaoDeMaterial.status[:devolvido_ao_almoxarifado], data_inicial , data_final).all
		end
	end
end
