package com.example.pap_teste; import android.os.Bundle; import androidx.recyclerview.widget.RecyclerView; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import android.widget.Button; public class NovaReservaActivity extends AppCompatActivity { private enum State { CATEGORIES, RESTAURANTS, DETAILS } private State currentState = State.CATEGORIES; private String selectedCategory = null; private com.example.pap_teste.models.Restaurant selectedRestaurant = null; private androidx.recyclerview.widget.RecyclerView rvCategories, rvRestaurants; private android.view.View scrollNovaReserva; private android.widget.TextView txtTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_nova_reserva); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.novaReservaRoot), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); rvCategories = findViewById(R.id.rvCategories); rvRestaurants = findViewById(R.id.rvRestaurants); scrollNovaReserva = findViewById(R.id.scrollNovaReserva); txtTitle = findViewById(R.id.txtTituloNovaReserva); Button back = findViewById(R.id.btnVoltar); if (back != null) { back.setOnClickListener(v -> handleBackNavigation()); } setupCategories(); updateViewState(); } private void handleBackNavigation() { if (currentState == State.RESTAURANTS) { currentState = State.CATEGORIES; updateViewState(); } else if (currentState == State.DETAILS) { currentState = State.RESTAURANTS; updateViewState(); } else { finish(); } } private void updateViewState() { rvCategories .setVisibility(currentState == State.CATEGORIES ? android.view.View.VISIBLE : android.view.View.GONE); rvRestaurants .setVisibility(currentState == State.RESTAURANTS ? android.view.View.VISIBLE : android.view.View.GONE); scrollNovaReserva .setVisibility(currentState == State.DETAILS ? android.view.View.VISIBLE : android.view.View.GONE); if (currentState == State.CATEGORIES) { txtTitle.setText("Escolha o tema"); } else if (currentState == State.RESTAURANTS) { txtTitle.setText("Restaurantes: " + selectedCategory); } else { txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : "")); setupReservationOptions(); } } private void setupCategories() { java.util.List cats = new java.util.ArrayList<>(); cats.add(new com.example.pap_teste.models.FoodCategory("Carnes", R.drawable.cat_carnes)); cats.add(new com.example.pap_teste.models.FoodCategory("Massas", R.drawable.cat_massas)); cats.add(new com.example.pap_teste.models.FoodCategory("Sushi", R.drawable.cat_sushi)); cats.add(new com.example.pap_teste.models.FoodCategory("Pizzas", R.drawable.cat_pizzas)); cats.add(new com.example.pap_teste.models.FoodCategory("Sobremesas", R.drawable.cat_sobremesas)); rvCategories.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(this)); rvCategories.setAdapter(new FoodCategoryAdapter(cats, category -> { selectedCategory = category.getName(); currentState = State.RESTAURANTS; setupRestaurants(); updateViewState(); })); } private void setupRestaurants() { java.util.List filteredList = new java.util.ArrayList<>(); com.google.firebase.database.DatabaseReference usersRef = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("users"); usersRef.orderByChild("category").equalTo(selectedCategory).addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { @Override public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { filteredList.clear(); for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) { String role = ds.child("role").getValue(String.class); String accountType = ds.child("accountType").getValue(String.class); if ("ADMIN".equalsIgnoreCase(role) || "ESTABELECIMENTO".equalsIgnoreCase(accountType)) { String name = ds.child("establishmentName").getValue(String.class); if (name == null) name = ds.child("displayName").getValue(String.class); String email = ds.child("email").getValue(String.class); String cat = ds.child("category").getValue(String.class); if (name != null && email != null) { filteredList.add(new com.example.pap_teste.models.Restaurant(name, cat, email, false)); } } } rvRestaurants.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(NovaReservaActivity.this)); rvRestaurants.setAdapter(new RestaurantAdapter(filteredList, restaurant -> { selectedRestaurant = restaurant; currentState = State.DETAILS; updateViewState(); })); } @Override public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) { android.widget.Toast.makeText(NovaReservaActivity.this, "Erro ao carregar restaurantes.", android.widget.Toast.LENGTH_SHORT).show(); } }); } private String selectedDate = null; private String selectedTime = null; private void setupReservationOptions() { android.widget.Button btnDate = findViewById(R.id.btnSelectDate); android.widget.Button btnTime = findViewById(R.id.btnSelectTime); btnDate.setOnClickListener(v -> { java.util.Calendar cal = java.util.Calendar.getInstance(); new android.app.DatePickerDialog(this, (view, year, month, dayOfMonth) -> { selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year; btnDate.setText(selectedDate); }, cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), cal.get(java.util.Calendar.DAY_OF_MONTH)).show(); }); btnTime.setOnClickListener(v -> { java.util.Calendar cal = java.util.Calendar.getInstance(); new android.app.TimePickerDialog(this, (view, hourOfDay, minute) -> { selectedTime = String.format(java.util.Locale.getDefault(), "%02d:%02d", hourOfDay, minute); btnTime.setText(selectedTime); }, cal.get(java.util.Calendar.HOUR_OF_DAY), cal.get(java.util.Calendar.MINUTE), true).show(); }); findViewById(R.id.btnConfirmarReserva).setOnClickListener(v -> saveReservation()); } private void saveReservation() { android.widget.EditText etPartySize = findViewById(R.id.etPartySize); int val = 0; try { val = Integer.parseInt(etPartySize.getText().toString()); } catch (Exception e) {} final int partySize = val; if (selectedDate == null || selectedTime == null || partySize == 0) { android.widget.Toast.makeText(this, "Por favor, selecione data, hora e número de pessoas.", android.widget.Toast.LENGTH_SHORT).show(); return; } String restEmail = selectedRestaurant.getEmail(); com.google.firebase.database.DatabaseReference mesasRef = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("Mesas"); mesasRef.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { @Override public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { int totalMesas = 0; for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) { com.example.pap_teste.models.Mesa m = ds.getValue(com.example.pap_teste.models.Mesa.class); if (m != null && restEmail.equals(m.getRestauranteEmail())) { totalMesas++; } } if (totalMesas == 0) { proceedWithReservation(partySize); return; } checkReservationsAndSave(totalMesas, partySize); } @Override public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) { proceedWithReservation(partySize); } }); } private void checkReservationsAndSave(int totalMesas, final int partySize) { String restEmail = selectedRestaurant.getEmail(); com.google.firebase.database.DatabaseReference reservasRef = com.google.firebase.database.FirebaseDatabase.getInstance().getReference("reservas"); reservasRef.orderByChild("restauranteEmail").equalTo(restEmail).addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() { @Override public void onDataChange(@androidx.annotation.NonNull com.google.firebase.database.DataSnapshot snapshot) { int ocupadas = 0; java.util.Map ocupacaoPorHora = new java.util.HashMap<>(); for (com.google.firebase.database.DataSnapshot ds : snapshot.getChildren()) { com.example.pap_teste.models.Reserva r = ds.getValue(com.example.pap_teste.models.Reserva.class); if (r != null && selectedDate.equals(r.getData()) && !"Cancelada".equals(r.getEstado()) && !"Recusada".equals(r.getEstado())) { int count = ocupacaoPorHora.getOrDefault(r.getHora(), 0) + 1; ocupacaoPorHora.put(r.getHora(), count); if (selectedTime.equals(r.getHora())) { ocupadas++; } } } if (ocupadas >= totalMesas) { String sugestao = ""; String[] horasComuns = {"12:00", "12:30", "13:00", "13:30", "14:00", "19:00", "19:30", "20:00", "20:30", "21:00", "21:30", "22:00"}; for (String h : horasComuns) { if (ocupacaoPorHora.getOrDefault(h, 0) < totalMesas && !h.equals(selectedTime)) { sugestao = h; break; // Encontramos a primeira sugestão livre } } String msg = "Não há mesas disponíveis para as " + selectedTime + "."; if (!sugestao.isEmpty()) { msg += " Sugestão: tente reservar para as " + sugestao + "."; } else { msg += " Tente para outro dia."; } android.widget.Toast.makeText(NovaReservaActivity.this, msg, android.widget.Toast.LENGTH_LONG).show(); } else { proceedWithReservation(partySize); } } @Override public void onCancelled(@androidx.annotation.NonNull com.google.firebase.database.DatabaseError error) { proceedWithReservation(partySize); } }); } private void proceedWithReservation(int partySize) { String userEmail = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser() != null ? com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser().getEmail() : "cliente@teste.com"; com.google.firebase.database.DatabaseReference ref = com.google.firebase.database.FirebaseDatabase.getInstance() .getReference("reservas"); String id = ref.push().getKey(); com.example.pap_teste.models.Reserva reserva = new com.example.pap_teste.models.Reserva( id, userEmail, selectedRestaurant.getName(), selectedRestaurant.getEmail(), selectedDate, selectedTime, partySize, "Pendente"); if (id != null) { ref.child(id).setValue(reserva).addOnCompleteListener(task -> { if (task.isSuccessful()) { android.widget.Toast .makeText(NovaReservaActivity.this, "Reserva solicitada com sucesso!", android.widget.Toast.LENGTH_SHORT) .show(); finish(); } else { android.widget.Toast.makeText(NovaReservaActivity.this, "Erro ao salvar reserva.", android.widget.Toast.LENGTH_SHORT) .show(); } }); } } }