package com.example.pap_teste;

import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.pap_teste.models.FoodCategory;
import com.example.pap_teste.models.LocalReservation;
import com.example.pap_teste.models.Mesa;
import com.example.pap_teste.models.Restaurant;
import com.example.pap_teste.viewmodels.ReservationViewModel;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

public class NovaReservaActivity extends AppCompatActivity {

    private enum State { CATEGORIES, RESTAURANTS, DETAILS }

    private State currentState = State.CATEGORIES;
    private String selectedCategory = null;
    private Restaurant selectedRestaurant = null;
    private Mesa selectedMesa = null;
    private String selectedDate = null;
    private String selectedTime = null;

    private RecyclerView rvCategories, rvRestaurants, rvTables;
    private View scrollNovaReserva;
    private TextView txtTitle;
    private ProgressBar progressBar;
    private ReservationViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_nova_reserva);
        
        viewModel = new ViewModelProvider(this).get(ReservationViewModel.class);

        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;
        });

        initViews();
        setupCategories();
        updateViewState();
    }

    private void initViews() {
        rvCategories = findViewById(R.id.rvCategories);
        rvRestaurants = findViewById(R.id.rvRestaurants);
        rvTables = findViewById(R.id.rvTables);
        scrollNovaReserva = findViewById(R.id.scrollNovaReserva);
        txtTitle = findViewById(R.id.txtTituloNovaReserva);
        progressBar = findViewById(R.id.progressBar);

        findViewById(R.id.btnVoltar).setOnClickListener(v -> handleBackNavigation());
        findViewById(R.id.btnSelectDate).setOnClickListener(v -> showDatePicker());
        findViewById(R.id.btnSelectTime).setOnClickListener(v -> showTimePicker());
        findViewById(R.id.btnConfirmarReserva).setOnClickListener(v -> validateAndSave());
    }

    private void handleBackNavigation() {
        if (currentState == State.RESTAURANTS) {
            currentState = State.CATEGORIES;
        } else if (currentState == State.DETAILS) {
            currentState = State.RESTAURANTS;
        } else {
            finish();
            return;
        }
        updateViewState();
    }

    private void updateViewState() {
        rvCategories.setVisibility(currentState == State.CATEGORIES ? View.VISIBLE : View.GONE);
        rvRestaurants.setVisibility(currentState == State.RESTAURANTS ? View.VISIBLE : View.GONE);
        scrollNovaReserva.setVisibility(currentState == State.DETAILS ? View.VISIBLE : View.GONE);

        switch (currentState) {
            case CATEGORIES: txtTitle.setText("Escolha o tema"); break;
            case RESTAURANTS: txtTitle.setText("Restaurantes: " + selectedCategory); break;
            case DETAILS: txtTitle.setText("Reserva: " + (selectedRestaurant != null ? selectedRestaurant.getName() : "")); break;
        }
    }

    private void setupCategories() {
        List<FoodCategory> cats = new ArrayList<>();
        cats.add(new FoodCategory("Carnes", R.drawable.cat_carnes));
        cats.add(new FoodCategory("Massas", R.drawable.cat_massas));
        cats.add(new FoodCategory("Sushi", R.drawable.cat_sushi));
        cats.add(new FoodCategory("Pizzas", R.drawable.cat_pizzas));
        cats.add(new FoodCategory("Sobremesas", R.drawable.cat_sobremesas));

        rvCategories.setLayoutManager(new LinearLayoutManager(this));
        rvCategories.setAdapter(new FoodCategoryAdapter(cats, category -> {
            selectedCategory = category.getName();
            currentState = State.RESTAURANTS;
            loadRestaurants();
            updateViewState();
        }));
    }

    private void loadRestaurants() {
        progressBar.setVisibility(View.VISIBLE);
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Restaurantes");
        ref.orderByChild("category").equalTo(selectedCategory).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                progressBar.setVisibility(View.GONE);
                List<Restaurant> list = new ArrayList<>();
                for (DataSnapshot ds : snapshot.getChildren()) {
                    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);
                    String logo = ds.child("logoUrl").getValue(String.class);
                    if (name != null && email != null) {
                        list.add(new Restaurant(name, cat, email, false, logo));
                    }
                }
                rvRestaurants.setLayoutManager(new LinearLayoutManager(NovaReservaActivity.this));
                rvRestaurants.setAdapter(new RestaurantAdapter(list, restaurant -> {
                    selectedRestaurant = restaurant;
                    currentState = State.DETAILS;
                    loadTables();
                    updateViewState();
                }));
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                progressBar.setVisibility(View.GONE);
                Toast.makeText(NovaReservaActivity.this, "Erro ao carregar.", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void loadTables() {
        progressBar.setVisibility(View.VISIBLE);
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Mesas");
        ref.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                progressBar.setVisibility(View.GONE);
                List<Mesa> tables = new ArrayList<>();
                for (DataSnapshot ds : snapshot.getChildren()) {
                    Mesa m = ds.getValue(Mesa.class);
                    if (m != null && selectedRestaurant.getEmail().equalsIgnoreCase(m.getRestauranteEmail())) {
                        tables.add(m);
                    }
                }
                rvTables.setLayoutManager(new GridLayoutManager(NovaReservaActivity.this, 3));
                rvTables.setAdapter(new TableSelectionAdapter(tables, mesa -> selectedMesa = mesa));
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                progressBar.setVisibility(View.GONE);
            }
        });
    }

    private void showDatePicker() {
        Calendar cal = Calendar.getInstance();
        new DatePickerDialog(this, (view, year, month, day) -> {
            selectedDate = String.format(Locale.getDefault(), "%02d/%02d/%d", day, month + 1, year);
            ((Button)findViewById(R.id.btnSelectDate)).setText(selectedDate);
        }, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)).show();
    }

    private void showTimePicker() {
        Calendar cal = Calendar.getInstance();
        new TimePickerDialog(this, (view, hour, min) -> {
            selectedTime = String.format(Locale.getDefault(), "%02d:%02d", hour, min);
            ((Button)findViewById(R.id.btnSelectTime)).setText(selectedTime);
        }, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true).show();
    }

    private void validateAndSave() {
        EditText etPartySize = findViewById(R.id.etPartySize);
        EditText etNotes = findViewById(R.id.etNotes);
        String partySizeStr = etPartySize.getText().toString();

        if (selectedDate == null || selectedTime == null || selectedMesa == null || partySizeStr.isEmpty()) {
            Toast.makeText(this, "Preencha todos os campos e escolha a mesa.", Toast.LENGTH_SHORT).show();
            return;
        }

        int partySize = Integer.parseInt(partySizeStr);
        if (partySize > selectedMesa.getCapacidade()) {
            Toast.makeText(this, "A mesa escolhida só suporta " + selectedMesa.getCapacidade() + " pessoas.", Toast.LENGTH_SHORT).show();
            return;
        }

        // Conflict check
        viewModel.checkConflict(selectedDate, selectedMesa.getNumero(), isAvailable -> {
            runOnUiThread(() -> {
                if (isAvailable) {
                    saveToFirebaseAndRoom(partySize, etNotes.getText().toString());
                } else {
                    Toast.makeText(this, "Esta mesa já está reservada para este dia.", Toast.LENGTH_LONG).show();
                }
            });
        });
    }

    private void saveToFirebaseAndRoom(int guests, String notes) {
        progressBar.setVisibility(View.VISIBLE);
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("reservas");
        String id = ref.push().getKey();
        String userEmail = FirebaseAuth.getInstance().getCurrentUser() != null ? FirebaseAuth.getInstance().getCurrentUser().getEmail() : "anon@test.com";

        LocalReservation local = new LocalReservation();
        local.setFirebaseId(id);
        local.setRestaurantName(selectedRestaurant.getName());
        local.setRestaurantEmail(selectedRestaurant.getEmail());
        local.setDate(selectedDate);
        local.setTime(selectedTime);
        local.setGuests(guests);
        local.setTableNumber(selectedMesa.getNumero());
        local.setNotes(notes);
        local.setStatus("PENDENTE");

        if (id != null) {
            ref.child(id).setValue(local).addOnCompleteListener(task -> {
                progressBar.setVisibility(View.GONE);
                if (task.isSuccessful()) {
                    viewModel.insert(local);
                    Toast.makeText(this, "Reserva realizada com sucesso!", Toast.LENGTH_LONG).show();
                    finish();
                } else {
                    Toast.makeText(this, "Erro ao guardar no servidor.", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}
