package com.example.pap_teste;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

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.List;

public class CheckInAntecipadoActivity extends AppCompatActivity implements LocationListener {

    private TextView txtDistancia, txtStatus, txtEndereco;
    private Button btnConfirmarChegada, btnAbrirMapa;
    private LocationManager locationManager;
    private DatabaseReference databaseReference;

    private double restaurantLat, restaurantLon;
    private int securityDistance = 500; // default 500m
    private boolean settingsLoaded = false;
    private String restaurantAddress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_checkin_antecipado);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.checkinRoot), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        txtDistancia = findViewById(R.id.txtDistancia);
        txtStatus = findViewById(R.id.txtStatusDistancia);
        txtEndereco = findViewById(R.id.txtEnderecoRestaurante);
        btnConfirmarChegada = findViewById(R.id.btnConfirmarChegada);
        btnAbrirMapa = findViewById(R.id.btnAbrirMapa);
        Button back = findViewById(R.id.btnVoltar);

        if (back != null) {
            back.setOnClickListener(v -> finish());
        }

        String restaurantEmail = getIntent().getStringExtra("restaurant_email");
        if (restaurantEmail != null) {
            String restaurantId = restaurantEmail.replace(".", "_").replace("@", "_at_");
            loadRestaurantSettings(restaurantId);
        } else {
            txtStatus.setText("Erro: Restaurante não identificado.");
        }

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (hasRequiredPermissions()) {
            startLocationUpdates();
        } else {
            txtStatus.setText("Permissões em falta para localização/proximidade.");
        }

        btnConfirmarChegada.setOnClickListener(v -> {
            Toast.makeText(this, "Chegada confirmada com sucesso!", Toast.LENGTH_LONG).show();
            finish();
        });

        btnAbrirMapa.setOnClickListener(v -> {
            if (restaurantAddress != null) {
                try {
                    String uri = "geo:0,0?q=" + java.net.URLEncoder.encode(restaurantAddress, "UTF-8");
                    Intent intent = new Intent(Intent.ACTION_VIEW, android.net.Uri.parse(uri));
                    startActivity(intent);
                } catch (Exception e) {
                    Toast.makeText(this, "Erro ao abrir mapa.", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private boolean hasRequiredPermissions() {
        boolean fineLocation = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            boolean btScan = ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
            return fineLocation && btScan;
        }
        return fineLocation;
    }

    private void loadRestaurantSettings(String restaurantId) {
        databaseReference = FirebaseDatabase.getInstance().getReference().child("Restaurantes").child(restaurantId);
        databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {
                    restaurantAddress = snapshot.child("address").getValue(String.class);
                    Integer dist = snapshot.child("securityDistance").getValue(Integer.class);
                    securityDistance = dist != null ? dist : 500;

                    if (restaurantAddress != null) {
                        txtEndereco.setText("Morada: " + restaurantAddress);
                        geocodeAddress(restaurantAddress);
                    } else {
                        txtEndereco.setText("Morada não disponível.");
                        // Fallback to old lat/lon if they exist
                        Double lat = snapshot.child("latitude").getValue(Double.class);
                        Double lon = snapshot.child("longitude").getValue(Double.class);
                        if (lat != null && lon != null) {
                            restaurantLat = lat;
                            restaurantLon = lon;
                            settingsLoaded = true;
                        }
                    }
                } else {
                    txtStatus.setText("Aviso: Definições do restaurante não encontradas.");
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                txtStatus.setText("Erro ao carregar definições do restaurante.");
            }
        });
    }

    private void geocodeAddress(String address) {
        new Thread(() -> {
            try {
                android.location.Geocoder geocoder = new android.location.Geocoder(this);
                List<android.location.Address> addresses = geocoder.getFromLocationName(address, 1);
                if (addresses != null && !addresses.isEmpty()) {
                    restaurantLat = addresses.get(0).getLatitude();
                    restaurantLon = addresses.get(0).getLongitude();
                    settingsLoaded = true;
                } else {
                    runOnUiThread(() -> txtStatus.setText("Erro: Não foi possível localizar a morada no mapa."));
                }
            } catch (Exception e) {
                runOnUiThread(() -> txtStatus.setText("Erro ao obter coordenadas da morada."));
            }
        }).start();
    }

    private void startLocationUpdates() {
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        try {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this);
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 5, this);
        } catch (Exception e) {
            txtStatus.setText("Erro ao iniciar localização: " + e.getMessage());
        }
    }

    @Override
    public void onLocationChanged(@NonNull Location location) {
        if (!settingsLoaded)
            return;

        float[] results = new float[1];
        Location.distanceBetween(location.getLatitude(), location.getLongitude(), restaurantLat, restaurantLon,
                results);
        float distanceInMeters = results[0];

        txtDistancia.setText(String.format("Distância: %.0f metros", distanceInMeters));

        if (distanceInMeters <= securityDistance) {
            txtStatus.setText("Está no raio de segurança. Pode confirmar a sua chegada.");
            txtStatus.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
            btnConfirmarChegada.setEnabled(true);
        } else {
            txtStatus.setText(String.format("Está fora do raio de segurança (%dm). Aproxime-se para fazer check-in.",
                    securityDistance));
            txtStatus.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
            btnConfirmarChegada.setEnabled(false);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (locationManager != null) {
            locationManager.removeUpdates(this);
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    @Override
    public void onProviderEnabled(@NonNull String provider) {
    }

    @Override
    public void onProviderDisabled(@NonNull String provider) {
    }
}
