package com.example.bem;

import android.Manifest;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.GradientDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.QueryDocumentSnapshot;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    private enum Tab {
        ALARMS,
        REMINDERS,
        GUARDIANS,
        CALENDAR
    }

    private FrameLayout tabContainer;
    private LinearLayout tabAlarms, tabReminders, tabGuardians, tabCalendar;
    private ImageView iconAlarms, iconReminders, iconGuardians, iconCalendar;
    private TextView textAlarms, textReminders, textGuardians, textCalendar;

    private LayoutInflater inflater;
    private View alarmsView, remindersView, guardiansView, calendarView;
    private LinearLayout alarmListContainer;
    private final List<AlarmItem> alarms = new ArrayList<>();
    private final List<AlarmItem> patientAlarms = new ArrayList<>();
    private Tab currentTab = null;
    private FirebaseAuth mAuth;
    private FirebaseFirestore db;
    private SharedPreferences prefs;
    private static final String PREF_DARK_MODE = "dark_mode";
    private int editingAlarmIndex = -1;
    private String currentUserId = null;
    private boolean isGuardian = false;
    private String linkedPatientId = null;
    
    private ListenerRegistration guardianAlarmsListener;
    private ListenerRegistration patientCalendarListener;
    private ListenerRegistration historyListener;
    private ListenerRegistration userDocListener;
    
    private FusedLocationProviderClient fusedLocationClient;
    private TextView textLocation, textTemperature, textCondition, textTipDesc1;
    
    private final Map<String, List<String>> confirmationHistory = new HashMap<>(); // key: YYYYMMDD, value: list of alarm titles

    private final ActivityResultLauncher<String> notificationPermissionLauncher = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(), isGranted -> {
                if (!isGranted) {
                    Toast.makeText(this, "Permissão negada. Alarmes podem não tocar.", Toast.LENGTH_LONG).show();
                }
            });

    private final ActivityResultLauncher<String> locationPermissionLauncher = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(), isGranted -> {
                if (isGranted) {
                    fetchLocationAndWeather();
                }
            });

    private AlarmItem editingAlarmForSound;
    private final ActivityResultLauncher<Intent> ringtonePickerLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(), result -> {
                if (result.getResultCode() == RESULT_OK && result.getData() != null && editingAlarmForSound != null) {
                    Uri uri = result.getData().getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
                    if (uri != null) {
                        editingAlarmForSound.ringtoneUri = uri.toString();
                        updateAlarmInFirestore(editingAlarmForSound);
                        android.widget.Toast.makeText(this, "Som alterado!", android.widget.Toast.LENGTH_SHORT).show();
                    }
                    editingAlarmForSound = null;
                }
            });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mAuth = FirebaseAuth.getInstance();
        db = FirebaseFirestore.getInstance();
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

        FirebaseUser currentUser = mAuth.getCurrentUser();
        if (currentUser == null) {
            redirectToLogin();
            return;
        }

        currentUserId = currentUser.getUid();
        prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
        applyThemeFromPrefs();

        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        inflater = LayoutInflater.from(this);

        String userType = prefs.getString("user_type", "user");
        isGuardian = "guardian".equals(userType);
        linkedPatientId = prefs.getString("linked_patient_id", null);

        initViews();
        setupListeners();
        observeUserDocument();

        requestNotificationPermissions();
        
        // Fix: Auto-load the initial tab immediately to avoid white screen
        Tab initialTab = isGuardian ? Tab.GUARDIANS : Tab.ALARMS;
        currentTab = initialTab;
        
        applyUserModeLayout();
        tabContainer.post(() -> loadAndShowTab(currentTab));
        
        loadAlarmsFromFirestore();
        showIntroDialogIfNeeded();
        updateLastActive();
        if (isGuardian) startGuardianServiceIfLinked();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        updateLastActive();
    }

    private void updateLastActive() {
        if (currentUserId != null) {
            db.collection("users").document(currentUserId).update("lastActive", System.currentTimeMillis());
        }
    }

    private void initViews() {
        tabContainer = findViewById(R.id.tabContainer);
        tabAlarms = findViewById(R.id.tabAlarms);
        tabReminders = findViewById(R.id.tabReminders);
        tabGuardians = findViewById(R.id.tabGuardians);
        tabCalendar = findViewById(R.id.tabCalendar);

        iconAlarms = findViewById(R.id.iconAlarms);
        iconReminders = findViewById(R.id.iconReminders);
        iconGuardians = findViewById(R.id.iconGuardians);
        iconCalendar = findViewById(R.id.iconCalendar);

        textAlarms = findViewById(R.id.textAlarms);
        textReminders = findViewById(R.id.textReminders);
        textGuardians = findViewById(R.id.textGuardians);
        textCalendar = findViewById(R.id.textCalendar);

        findViewById(R.id.profileButton).setOnClickListener(v -> showProfileMenu());
    }

    private void setupListeners() {
        tabAlarms.setOnClickListener(v -> switchTab(Tab.ALARMS));
        tabReminders.setOnClickListener(v -> switchTab(Tab.REMINDERS));
        tabGuardians.setOnClickListener(v -> handleGuardianTabClick());
        tabCalendar.setOnClickListener(v -> switchTab(Tab.CALENDAR));
    }

    private void observeUserDocument() {
        if (currentUserId == null) return;
        userDocListener = db.collection("users").document(currentUserId).addSnapshotListener((snapshot, e) -> {
            if (e != null || snapshot == null || !snapshot.exists()) return;
            
            String type = snapshot.getString("type");
            boolean newIsGuardian = "guardian".equals(type);
            
            // Handle patient linkage
            List<String> managed = new ArrayList<>();
            Object val = snapshot.get("managedUsers");
            if (val instanceof List) {
                for (Object item : (List<?>) val) if (item instanceof String) managed.add((String) item);
            }
            String newPatientId = managed.isEmpty() ? null : managed.get(0);
            
            boolean linkageChanged = (newPatientId == null && linkedPatientId != null) || 
                                     (newPatientId != null && !newPatientId.equals(linkedPatientId));
            
            if (newIsGuardian != isGuardian || linkageChanged) {
                isGuardian = newIsGuardian;
                linkedPatientId = newPatientId;
                prefs.edit().putString("user_type", type).apply();
                applyUserModeLayout();
                
                // If the user is currently on a tab that depends on patient data, refresh it
                if (isGuardian && (currentTab == Tab.GUARDIANS || currentTab == Tab.CALENDAR)) {
                    loadAndShowTab(currentTab);
                }
            }
        });
    }

    private void applyUserModeLayout() {
        if (isGuardian) {
            tabAlarms.setVisibility(View.GONE);
            tabReminders.setVisibility(View.GONE);
            tabCalendar.setVisibility(View.VISIBLE);
            if (currentTab == Tab.ALARMS || currentTab == Tab.REMINDERS) {
                switchTab(Tab.GUARDIANS);
            }
        } else {
            tabAlarms.setVisibility(View.VISIBLE);
            tabReminders.setVisibility(View.VISIBLE);
            tabCalendar.setVisibility(View.GONE);
            if (currentTab == Tab.GUARDIANS || currentTab == Tab.CALENDAR) {
                switchTab(Tab.ALARMS);
            }
        }
    }

    private void redirectToLogin() {
        Intent intent = new Intent(this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }

    private void requestNotificationPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
            }
        }
    }

    private void handleGuardianTabClick() {
        if (isGuardian) {
            switchTab(Tab.GUARDIANS);
        } else {
             db.collection("users").document(currentUserId).get().addOnSuccessListener(doc -> {
                if (doc.exists() && (doc.contains("guardianId") || doc.contains("guardians"))) {
                     switchTab(Tab.GUARDIANS);
                } else {
                    new AlertDialog.Builder(this)
                        .setTitle("Responsável")
                        .setMessage("Ainda não tem um responsável associado. Deseja gerar um código de convite?")
                        .setPositiveButton("Gerar Código", (dialog, which) -> {
                            startActivity(new Intent(this, GenerateCodeActivity.class));
                        })
                        .setNegativeButton("Agora Não", null)
                        .show();
                }
            });
        }
    }

    private void showProfileMenu() {
        View dialogView = inflater.inflate(R.layout.dialog_profile, null);
        AlertDialog dialog = new AlertDialog.Builder(this).setView(dialogView).create();
        if (dialog.getWindow() != null) dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

        TextView nameTxt = dialogView.findViewById(R.id.textProfileName);
        TextView emailTxt = dialogView.findViewById(R.id.textProfileEmail);
        
        nameTxt.setText(prefs.getString("user_name", "Utilizador"));
        FirebaseUser currentUser = mAuth.getCurrentUser();
        emailTxt.setText(currentUser != null ? currentUser.getEmail() : "Não disponível");
        
        // Fetch fresh data from Firestore to ensure it's correct
        if (currentUserId != null) {
            db.collection("users").document(currentUserId).get().addOnSuccessListener(doc -> {
                if (doc.exists()) {
                    String name = doc.getString("name");
                    String email = doc.getString("email");
                    if (name != null) nameTxt.setText(name);
                    if (email != null) emailTxt.setText(email);
                }
            });
        }
        
        // Profile buttons
        dialogView.findViewById(R.id.btnProfileSupport).setOnClickListener(v -> { dialog.dismiss(); openSupportEmail(); });
        
        View btnExitGuardian = dialogView.findViewById(R.id.btnProfileExitGuardian);
        btnExitGuardian.setVisibility(isGuardian ? View.VISIBLE : View.GONE);
        btnExitGuardian.setOnClickListener(v -> { dialog.dismiss(); exitGuardianMode(); });

        dialogView.findViewById(R.id.btnProfileLogout).setOnClickListener(v -> { dialog.dismiss(); logout(); });
        dialogView.findViewById(R.id.btnProfileClose).setOnClickListener(v -> dialog.dismiss());
        dialog.show();
    }

    private void exitGuardianMode() {
        prefs.edit().putString("user_type", "user").apply();
        Intent intent = new Intent(this, InviteCodeActivity.class);
        stopService(new Intent(this, GuardianNotificationService.class));
        startActivity(intent);
        finish();
    }

    private void toggleDarkMode() {
        boolean isDarkMode = prefs.getBoolean(PREF_DARK_MODE, false);
        prefs.edit().putBoolean(PREF_DARK_MODE, !isDarkMode).apply();
        recreate();
    }

    private void openSupportEmail() {
        Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:support@bempap.com"));
        intent.putExtra(Intent.EXTRA_SUBJECT, "Suporte App Bem+");
        try { startActivity(intent); } catch (Exception e) { Toast.makeText(this, "Erro ao abrir email.", Toast.LENGTH_SHORT).show(); }
    }

    private void logout() {
        mAuth.signOut();
        stopService(new Intent(this, GuardianNotificationService.class));
        redirectToLogin();
    }

    private void applyThemeFromPrefs() {
        AppCompatDelegate.setDefaultNightMode(prefs.getBoolean(PREF_DARK_MODE, false) ? 
                AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
    }

    private void switchTab(Tab tab) {
        if (tab == currentTab && tabContainer.getChildCount() > 0) return;
        currentTab = tab;
        loadAndShowTab(tab);
    }

    private void loadAndShowTab(Tab tab) {
        if (guardianAlarmsListener != null) { guardianAlarmsListener.remove(); guardianAlarmsListener = null; }
        if (patientCalendarListener != null) { patientCalendarListener.remove(); patientCalendarListener = null; }
        if (historyListener != null) { historyListener.remove(); historyListener = null; }

        View content = null;
        switch (tab) {
            case ALARMS:
                if (alarmsView == null) alarmsView = inflater.inflate(R.layout.layout_tab_alarms, tabContainer, false);
                content = alarmsView;
                Button addAlarm = alarmsView.findViewById(R.id.btnAddAlarm);
                alarmListContainer = alarmsView.findViewById(R.id.alarmListContainer);
                if (addAlarm != null) addAlarm.setOnClickListener(v -> showAddAlarmDialog());
                renderAlarms();
                break;
            case REMINDERS:
                if (remindersView == null) remindersView = inflater.inflate(R.layout.layout_tab_reminders, tabContainer, false);
                content = remindersView;
                textLocation = remindersView.findViewById(R.id.textLocation);
                textTemperature = remindersView.findViewById(R.id.textTemperature);
                textCondition = remindersView.findViewById(R.id.textCondition);
                textTipDesc1 = remindersView.findViewById(R.id.textTipDesc1);
                TextView textGreeting = remindersView.findViewById(R.id.textGreeting);
                if (textGreeting != null) {
                    int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
                    if (hour < 12) textGreeting.setText("Bom dia");
                    else if (hour < 18) textGreeting.setText("Boa tarde");
                    else textGreeting.setText("Boa noite");
                }
                if (!isGuardian) {
                    fetchLocationAndWeather();
                }
                break;
            case GUARDIANS:
                if (guardiansView == null) guardiansView = inflater.inflate(R.layout.layout_tab_guardians, tabContainer, false);
                content = guardiansView;
                loadGuardianData(guardiansView);
                break;
            case CALENDAR:
                calendarView = inflater.inflate(R.layout.layout_tab_calendar, tabContainer, false);
                content = calendarView;
                // Render the calendar grid immediately with days visible
                setupCalendar(calendarView, isGuardian ? patientAlarms : alarms);
                // Then start async listeners to update with real data
                if (isGuardian) loadPatientDataForCalendar(calendarView);
                else setupHistoryListener(currentUserId, calendarView, alarms);
                break;
        }
        
        tabContainer.removeAllViews();
        if (content != null) {
            if (content.getParent() != null) {
                ((android.view.ViewGroup) content.getParent()).removeView(content);
            }
            tabContainer.addView(content);
        }
        updateTabHighlight(tab);
    }

    private void loadPatientDataForCalendar(View view) {
        if (view == null) return;
        if (linkedPatientId != null) {
            setupPatientCalendarListener(view, linkedPatientId);
            setupHistoryListener(linkedPatientId, view, patientAlarms);
        } else {
            db.collection("users").document(currentUserId).get().addOnSuccessListener(doc -> {
                List<String> managed = new ArrayList<>();
                Object val = doc.get("managedUsers");
                if (val instanceof List) {
                    for (Object item : (List<?>) val) if (item instanceof String) managed.add((String) item);
                }
                if (!managed.isEmpty()) {
                    linkedPatientId = managed.get(0);
                    setupPatientCalendarListener(view, linkedPatientId);
                    setupHistoryListener(linkedPatientId, view, patientAlarms);
                } else {
                    setupCalendar(view, new ArrayList<>());
                }
            });
        }
    }

    private void setupPatientCalendarListener(View view, String pId) {
        if (patientCalendarListener != null) patientCalendarListener.remove();
        patientCalendarListener = db.collection("users").document(pId).collection("alarms")
                .addSnapshotListener((snapshots, e) -> {
                    if (e != null || snapshots == null) return;
                    patientAlarms.clear();
                    for (QueryDocumentSnapshot d : snapshots) {
                        AlarmItem item = d.toObject(AlarmItem.class);
                        item.documentId = d.getId();
                        patientAlarms.add(item);
                    }
                    setupCalendar(view, patientAlarms);
                });
    }

    private void setupHistoryListener(String userId, View view, List<AlarmItem> listToDisplay) {
        if (historyListener != null) historyListener.remove();
        if (userId == null) return;
        
        historyListener = db.collection("users").document(userId).collection("history")
                .addSnapshotListener((snapshots, e) -> {
                    if (e != null || snapshots == null) return;
                    confirmationHistory.clear();
                    for (QueryDocumentSnapshot d : snapshots) {
                        String date = d.getString("date"); // YYYYMMDD
                        String title = d.getString("title");
                        if (date != null && title != null) {
                            if (!confirmationHistory.containsKey(date)) {
                                confirmationHistory.put(date, new ArrayList<>());
                            }
                            confirmationHistory.get(date).add(title);
                        }
                    }
                    setupCalendar(view, listToDisplay);
                });
    }

    private void setupCalendar(View view, List<AlarmItem> listToDisplay) {
        if (view == null) return;
        LinearLayout calendarGrid = view.findViewById(R.id.calendarGrid);
        TextView monthTitle = view.findViewById(R.id.textMonthTitle);
        LinearLayout legendContainer = view.findViewById(R.id.legendContainer);
        LinearLayout weekdayHeaders = view.findViewById(R.id.weekdayHeaders);
        if (calendarGrid == null || monthTitle == null || legendContainer == null) return;

        calendarGrid.removeAllViews();
        legendContainer.removeAllViews();

        // Setup month title
        Calendar calendar = Calendar.getInstance();
        int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
        int currentMonth = calendar.get(Calendar.MONTH);
        String[] months = { "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" };
        monthTitle.setText(String.format(Locale.getDefault(), "%s %d", months[currentMonth], calendar.get(Calendar.YEAR)));

        // Setup weekday headers programmatically
        if (weekdayHeaders != null) {
            weekdayHeaders.removeAllViews();
            String[] dayNames = {"DOM", "SEG", "TER", "QUA", "QUI", "SEX", "SÁB"};
            for (int i = 0; i < 7; i++) {
                TextView hdr = new TextView(this);
                hdr.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
                hdr.setText(dayNames[i]);
                hdr.setGravity(android.view.Gravity.CENTER);
                hdr.setTextSize(11);
                hdr.setTypeface(null, android.graphics.Typeface.BOLD);
                hdr.setTextColor(i == 0 ? ContextCompat.getColor(this, R.color.delete) : ContextCompat.getColor(this, R.color.neutral_medium));
                hdr.setPadding(0, 8, 0, 8);
                weekdayHeaders.addView(hdr);
            }
        }

        // Map medication colors
        int[] dotColors = { ContextCompat.getColor(this, R.color.primary), ContextCompat.getColor(this, R.color.guardian_purple_end), ContextCompat.getColor(this, R.color.delete), 0xFFFFA500, 0xFF00C853 };
        Map<String, Integer> medColors = new HashMap<>();
        int colorIndex = 0;
        for (AlarmItem alarm : listToDisplay) {
            if (!medColors.containsKey(alarm.title)) {
                int col = dotColors[colorIndex % dotColors.length];
                medColors.put(alarm.title, col);
                colorIndex++;
                TextView legend = new TextView(this);
                legend.setText(String.format(Locale.getDefault(), "● %s", alarm.title));
                legend.setTextColor(col);
                legend.setTextSize(14);
                legend.setPadding(0, 4, 0, 4);
                legendContainer.addView(legend);
            }
        }

        // Calendar math
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int firstDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 0=Sunday
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        float density = getResources().getDisplayMetrics().density;
        int cellHeight = (int)(44 * density); // 44dp per cell

        // Build grid row by row
        int dayNum = 1;
        int totalCells = firstDayOfWeek + daysInMonth;
        int totalRows = (int)Math.ceil(totalCells / 7.0);

        for (int row = 0; row < totalRows; row++) {
            LinearLayout weekRow = new LinearLayout(this);
            weekRow.setOrientation(LinearLayout.HORIZONTAL);
            weekRow.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            weekRow.setWeightSum(7.0f);

            for (int col = 0; col < 7; col++) {
                int cellIndex = row * 7 + col;

                if (cellIndex < firstDayOfWeek || dayNum > daysInMonth) {
                    // Empty cell
                    View empty = new View(this);
                    empty.setLayoutParams(new LinearLayout.LayoutParams(0, cellHeight, 1.0f));
                    weekRow.addView(empty);
                } else {
                    // Day cell - built entirely in code
                    LinearLayout dayCell = new LinearLayout(this);
                    dayCell.setOrientation(LinearLayout.VERTICAL);
                    dayCell.setLayoutParams(new LinearLayout.LayoutParams(0, cellHeight, 1.0f));
                    dayCell.setGravity(android.view.Gravity.CENTER_HORIZONTAL);
                    dayCell.setPadding((int)(2*density), (int)(2*density), (int)(2*density), (int)(2*density));

                    // Day number
                    TextView numText = new TextView(this);
                    int numSize = (int)(26 * density);
                    LinearLayout.LayoutParams numParams = new LinearLayout.LayoutParams(numSize, numSize);
                    numParams.gravity = android.view.Gravity.CENTER_HORIZONTAL;
                    numText.setLayoutParams(numParams);
                    numText.setText(String.valueOf(dayNum));
                    numText.setGravity(android.view.Gravity.CENTER);
                    numText.setTextSize(13);

                    if (dayNum == currentDay) {
                        GradientDrawable circle = new GradientDrawable();
                        circle.setShape(GradientDrawable.OVAL);
                        circle.setColor(ContextCompat.getColor(this, R.color.primary));
                        numText.setBackground(circle);
                        numText.setTextColor(0xFFFFFFFF);
                        numText.setTypeface(null, android.graphics.Typeface.BOLD);
                    } else {
                        numText.setTextColor(ContextCompat.getColor(this, R.color.neutral_dark));
                    }
                    dayCell.addView(numText);

                    // Dots container
                    LinearLayout dotsRow = new LinearLayout(this);
                    dotsRow.setOrientation(LinearLayout.HORIZONTAL);
                    dotsRow.setGravity(android.view.Gravity.CENTER);
                    LinearLayout.LayoutParams dotsParams = new LinearLayout.LayoutParams(
                            LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                    dotsParams.topMargin = (int)(2 * density);
                    dotsRow.setLayoutParams(dotsParams);

                    Calendar dayCal = (Calendar) calendar.clone();
                    dayCal.set(Calendar.DAY_OF_MONTH, dayNum);
                    String dayShort = getShortDayName(dayCal.get(Calendar.DAY_OF_WEEK));

                    for (AlarmItem alarm : listToDisplay) {
                        if (alarm.days != null && alarm.days.contains(dayShort)) {
                            View dot = new View(this);
                            int dotSize = (int)(6 * density);
                            LinearLayout.LayoutParams dp = new LinearLayout.LayoutParams(dotSize, dotSize);
                            dp.setMargins((int)(1*density), 0, (int)(1*density), 0);
                            dot.setLayoutParams(dp);

                            String dayKey = String.format(Locale.getDefault(), "%04d%02d%02d", dayCal.get(Calendar.YEAR), dayCal.get(Calendar.MONTH) + 1, dayNum);
                            List<String> confirmedToday = confirmationHistory.get(dayKey);
                            boolean taken = confirmedToday != null && confirmedToday.contains(alarm.title);

                            GradientDrawable shape = new GradientDrawable();
                            shape.setShape(GradientDrawable.OVAL);
                            Integer color = medColors.get(alarm.title);
                            if (color != null) shape.setColor(color);
                            if (!taken) shape.setAlpha(60);

                            dot.setBackground(shape);
                            dotsRow.addView(dot);
                        }
                    }
                    dayCell.addView(dotsRow);

                    weekRow.addView(dayCell);
                    dayNum++;
                }
            }
            calendarGrid.addView(weekRow);
        }
    }

    private String getShortDayName(int dayOfWeek) {
        switch (dayOfWeek) {
            case Calendar.MONDAY: return "Seg";
            case Calendar.TUESDAY: return "Ter";
            case Calendar.WEDNESDAY: return "Qua";
            case Calendar.THURSDAY: return "Qui";
            case Calendar.FRIDAY: return "Sex";
            case Calendar.SATURDAY: return "Sáb";
            case Calendar.SUNDAY: return "Dom";
            default: return "";
        }
    }

    private void updateTabHighlight(Tab tab) {
        resetTab(tabAlarms, iconAlarms, textAlarms);
        resetTab(tabReminders, iconReminders, textReminders);
        resetTab(tabGuardians, iconGuardians, textGuardians);
        resetTab(tabCalendar, iconCalendar, textCalendar);
        switch (tab) {
            case ALARMS: highlightTab(tabAlarms, iconAlarms, textAlarms); break;
            case REMINDERS: highlightTab(tabReminders, iconReminders, textReminders); break;
            case GUARDIANS: highlightTab(tabGuardians, iconGuardians, textGuardians); break;
            case CALENDAR: highlightTab(tabCalendar, iconCalendar, textCalendar); break;
        }
    }

    private void highlightTab(LinearLayout l, ImageView i, TextView t) {
        l.setBackground(ContextCompat.getDrawable(this, R.drawable.bg_tab_active));
        i.setColorFilter(ContextCompat.getColor(this, R.color.primary));
        t.setTextColor(ContextCompat.getColor(this, R.color.primary));
    }

    private void resetTab(LinearLayout l, ImageView i, TextView t) {
        l.setBackground(null);
        int neutral = ContextCompat.getColor(this, R.color.neutral_medium);
        i.setColorFilter(neutral);
        t.setTextColor(neutral);
    }

    private void renderAlarms() {
        if (alarmListContainer == null) return;
        alarmListContainer.removeAllViews();
        if (alarms.isEmpty()) {
            TextView empty = new TextView(this);
            empty.setText(R.string.no_alarms_message);
            empty.setTextColor(ContextCompat.getColor(this, R.color.neutral_medium));
            empty.setPadding(0, 24, 0, 24);
            alarmListContainer.addView(empty);
            return;
        }
        for (int i = 0; i < alarms.size(); i++) {
            final int idx = i;
            AlarmItem item = alarms.get(i);
            View card = inflater.inflate(R.layout.item_alarm_card, alarmListContainer, false);
            SwitchCompat toggle = card.findViewById(R.id.switchAlarm);
            Button confirmBtn = card.findViewById(R.id.btnConfirmMedication);

            ((TextView)card.findViewById(R.id.textAlarmTitle)).setText(item.title);
            ((TextView)card.findViewById(R.id.textAlarmTime)).setText(item.time);
            ((TextView)card.findViewById(R.id.textAlarmDays)).setText(item.days);
            toggle.setChecked(item.enabled);
            if (isTakenToday(item)) {
                confirmBtn.setText(R.string.taken_confirmed);
                confirmBtn.setBackgroundColor(ContextCompat.getColor(this, R.color.neutral_medium));
                confirmBtn.setEnabled(true); // Keep enabled for revert
            } else {
                confirmBtn.setText(R.string.confirm_medication);
                confirmBtn.setBackground(ContextCompat.getDrawable(this, R.drawable.bg_new_button));
                confirmBtn.setEnabled(true);
            }

            confirmBtn.setOnClickListener(v -> {
                if (isTakenToday(item)) {
                    showRevertDialog(item);
                } else {
                    item.lastTakenTimestamp = System.currentTimeMillis();
                    item.takenToday = true;
                    updateAlarmInFirestore(item);
                    saveMedicationConfirmationToFirestore(item);
                    saveMedicationConfirmationLocally(item);
                    renderAlarms();
                    Toast.makeText(this, "Medicação confirmada!", Toast.LENGTH_SHORT).show();
                }
            });

            toggle.setOnCheckedChangeListener((b, checked) -> { item.enabled = checked; updateAlarmInFirestore(item); });
            card.findViewById(R.id.buttonEditAlarm).setOnClickListener(v -> showEditAlarmDialog(item, idx));
            card.findViewById(R.id.buttonDeleteAlarm).setOnClickListener(v -> deleteAlarmFromFirestore(item, idx));
            alarmListContainer.addView(card);
        }
    }
    private void showRevertDialog(AlarmItem item) {
        new AlertDialog.Builder(this)
                .setTitle("Anular Toma")
                .setMessage("Deseja anular a confirmação de hoje para " + item.title + "?")
                .setPositiveButton("Sim, Anular", (d, w) -> revertMedicationConfirmation(item))
                .setNegativeButton("Não", null)
                .show();
    }

    private void revertMedicationConfirmation(AlarmItem item) {
        item.lastTakenTimestamp = 0;
        item.takenToday = false;
        updateAlarmInFirestore(item);
        
        String dateKey = new java.text.SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(new java.util.Date());
        db.collection("users").document(currentUserId).collection("history")
                .document(dateKey + "_" + item.documentId).delete()
                .addOnSuccessListener(aVoid -> {
                    renderAlarms();
                    Toast.makeText(this, "Toma anulada.", Toast.LENGTH_SHORT).show();
                });
        
        // Also remove from local prefs if applicable
        prefs.edit().remove("taken_" + dateKey + "_" + item.documentId).apply();
    }

    private boolean isTakenToday(AlarmItem item) {
        if (item.lastTakenTimestamp == 0) return false;
        Calendar last = Calendar.getInstance(); last.setTimeInMillis(item.lastTakenTimestamp);
        Calendar now = Calendar.getInstance();
        return last.get(Calendar.YEAR) == now.get(Calendar.YEAR) && last.get(Calendar.DAY_OF_YEAR) == now.get(Calendar.DAY_OF_YEAR);
    }

    private void saveMedicationConfirmationLocally(AlarmItem item) {
        SharedPreferences confirmPrefs = getSharedPreferences("medication_log", MODE_PRIVATE);
        String key = "med_" + item.title.replaceAll("\\s+", "_") + "_" + new java.text.SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(new java.util.Date());
        confirmPrefs.edit().putLong(key, item.lastTakenTimestamp).putBoolean(key + "_taken", true).putString(key + "_title", item.title).apply();
    }

    private void saveMedicationConfirmationToFirestore(AlarmItem item) {
        if (currentUserId == null) return;
        String dateKey = new java.text.SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(new java.util.Date());
        Map<String, Object> data = new HashMap<>();
        data.put("date", dateKey);
        data.put("alarmId", item.documentId);
        data.put("title", item.title);
        data.put("takenAt", System.currentTimeMillis());
        
        db.collection("users").document(currentUserId).collection("history")
                .document(dateKey + "_" + item.documentId)
                .set(data);
    }

    private void loadGuardianData(View view) {
        TextView patientName = view.findViewById(R.id.textPatientName);
        TextView patientStatus = view.findViewById(R.id.textPatientStatus);
        LinearLayout list = view.findViewById(R.id.medicationStatusList);
        LinearLayout guardianListContainer = view.findViewById(R.id.guardianListContainer);
        View btnRefresh = view.findViewById(R.id.btnRefreshGuardian);
        if (patientName == null || list == null) return;
        
        if (btnRefresh != null) {
            btnRefresh.setOnClickListener(v -> {
                linkedPatientId = null; // Force re-fetch of patient ID
                loadGuardianData(view);
                Toast.makeText(this, "A atualizar dados do utilizador...", Toast.LENGTH_SHORT).show();
            });
        }

        if (isGuardian) {
            if (linkedPatientId != null) {
                setupGuardianAlarmsListener(view, linkedPatientId, patientName, patientStatus, list);
            } else {
                db.collection("users").document(currentUserId).get().addOnSuccessListener(doc -> {
                    List<String> managed = new ArrayList<>();
                    Object val = doc.get("managedUsers");
                    if (val instanceof List) {
                        for (Object item : (List<?>) val) if (item instanceof String) managed.add((String) item);
                    }
                    android.util.Log.d("GuardianTab", "Managed users found: " + managed.size());
                    if (!managed.isEmpty()) {
                        linkedPatientId = managed.get(0);
                        prefs.edit().putString("linked_patient_id", linkedPatientId).apply();
                        db.collection("users").document(linkedPatientId).get().addOnSuccessListener(pDoc -> {
                            String pName = pDoc.getString("name");
                            if (pName != null) prefs.edit().putString("linked_patient_name", pName).apply();
                            setupGuardianAlarmsListener(view, linkedPatientId, patientName, patientStatus, list);
                        });
                    } else { 
                        // FALLBACK: Search for patients that have this user as guardian
                        db.collection("users").whereArrayContains("guardians", currentUserId).get().addOnSuccessListener(q -> {
                            if (!q.isEmpty()) {
                                com.google.firebase.firestore.DocumentSnapshot d = q.getDocuments().get(0);
                                String fId = d.getId();
                                linkedPatientId = fId;
                                prefs.edit().putString("linked_patient_id", linkedPatientId).apply();
                                String pName = d.getString("name");
                                if (pName != null) prefs.edit().putString("linked_patient_name", pName).apply();
                                setupGuardianAlarmsListener(view, linkedPatientId, patientName, patientStatus, list);
                            } else {
                                patientName.setText("Nenhum utilizador associado");
                                patientStatus.setText("Certifique-se que o utilizador gerou o código.");
                            }
                        });
                    }
                });
            }
        } else {
            patientName.setText(prefs.getString("user_name", "Utilizador"));
            patientStatus.setText(R.string.online_updated_now);
            list.removeAllViews();
            for (AlarmItem a : alarms) renderPatientAlarmStatus(list, a);
            
            if (guardianListContainer != null) {
                db.collection("users").document(currentUserId).get().addOnSuccessListener(doc -> {
                    guardianListContainer.removeAllViews();
                    List<String> guardians = new ArrayList<>();
                    if (doc.contains("guardians")) {
                        Object val = doc.get("guardians");
                        if (val instanceof List) {
                            for (Object item : (List<?>) val) if (item instanceof String) guardians.add((String) item);
                        }
                    } else if (doc.contains("guardianId")) {
                        String gid = doc.getString("guardianId");
                        if (gid != null && !gid.isEmpty()) guardians.add(gid);
                    }
                    
                    if (guardians.isEmpty()) {
                        TextView empty = new TextView(this);
                        empty.setText("Nenhum responsável associado.");
                        empty.setTextColor(ContextCompat.getColor(this, R.color.neutral_medium));
                        empty.setPadding(0, 16, 0, 16);
                        guardianListContainer.addView(empty);
                    } else {
                        for (String gid : guardians) {
                            db.collection("users").document(gid).get().addOnSuccessListener(gDoc -> {
                                View gCard = inflater.inflate(R.layout.item_saved_account, guardianListContainer, false);
                                TextView nameTxt = gCard.findViewById(R.id.textSavedName);
                                TextView emailTxt = gCard.findViewById(R.id.textSavedEmail);
                                ImageView closeBtn = gCard.findViewById(R.id.btnRemoveAccount);
                                View statusDot = gCard.findViewById(R.id.viewOnlineStatus); // I'll add this to layout
                                
                                nameTxt.setText(gDoc.getString("name"));
                                String email = gDoc.getString("email");
                                Long lastActive = gDoc.getLong("lastActive");
                                boolean isOnline = lastActive != null && (System.currentTimeMillis() - lastActive < 300000); // 5 mins
                                
                                emailTxt.setText(isOnline ? "Online" : (email != null ? email : ""));
                                emailTxt.setTextColor(ContextCompat.getColor(this, isOnline ? R.color.primary : R.color.neutral_medium));
                                
                                closeBtn.setVisibility(View.GONE);
                                if (statusDot != null) {
                                    statusDot.setVisibility(View.VISIBLE);
                                    GradientDrawable bg = (GradientDrawable) statusDot.getBackground().mutate();
                                    bg.setColor(ContextCompat.getColor(this, isOnline ? R.color.primary : R.color.neutral_medium));
                                }
                                
                                guardianListContainer.addView(gCard);
                            });
                        }
                    }
                });
            }
        }
        
        View btnAdd = view.findViewById(R.id.btnAddGuardian);
        if (btnAdd != null) btnAdd.setOnClickListener(v -> startActivity(new Intent(this, GenerateCodeActivity.class)));
    }

    private void setupGuardianAlarmsListener(View view, String pId, TextView nameView, TextView statusView, LinearLayout list) {
        db.collection("users").document(pId).get().addOnSuccessListener(pDoc -> {
            nameView.setText(pDoc.getString("name"));
            statusView.setText("Conectado ao Utilizador");
            
            if (guardianAlarmsListener != null) guardianAlarmsListener.remove();
            guardianAlarmsListener = db.collection("users").document(pId).collection("alarms")
                .addSnapshotListener((snaps, e) -> {
                if (e != null) {
                    android.util.Log.e("GuardianTab", "Error fetching alarms for " + pId + ": " + e.getMessage());
                    // Don't show toast on background errors unless it's critical
                    return;
                }
                if (snaps == null || view == null) return;
                
                android.util.Log.d("GuardianTab", "Received " + snaps.size() + " alarms for " + pId);
                patientAlarms.clear();
                for (QueryDocumentSnapshot d : snaps) {
                    AlarmItem alarm = d.toObject(AlarmItem.class);
                    alarm.documentId = d.getId();
                    patientAlarms.add(alarm);
                }
                
                // Sort by time
                java.util.Collections.sort(patientAlarms, (a1, a2) -> {
                    int c = Integer.compare(a1.hour, a2.hour);
                    return c != 0 ? c : Integer.compare(a1.minute, a2.minute);
                });

                list.removeAllViews();
                int takenCount = 0;
                AlarmItem nextMed = null;
                Calendar now = Calendar.getInstance();
                int nowH = now.get(Calendar.HOUR_OF_DAY);
                int nowM = now.get(Calendar.MINUTE);

                for (AlarmItem alarm : patientAlarms) {
                    renderPatientAlarmStatus(list, alarm);
                    if (isTakenToday(alarm)) takenCount++;
                    else if (nextMed == null && (alarm.hour > nowH || (alarm.hour == nowH && alarm.minute > nowM))) {
                        nextMed = alarm;
                    }
                }
                
                // Refresh calendar with updated patient alarms
                setupCalendar(calendarView, patientAlarms);

                // Update Dashboard
                TextView statusTitle = view.findViewById(R.id.textStatusTitle);
                TextView statusDesc = view.findViewById(R.id.textStatusDesc);
                ImageView statusIcon = view.findViewById(R.id.iconStatus);
                if (statusTitle != null) {
                    if (takenCount == patientAlarms.size() && !patientAlarms.isEmpty()) {
                        statusTitle.setText("Tudo em ordem");
                        statusDesc.setText("Todas as medicações de hoje foram tomadas.");
                        if (statusIcon != null) statusIcon.setImageResource(android.R.drawable.checkbox_on_background);
                    } else {
                        statusTitle.setText("Acompanhamento ativo");
                        statusDesc.setText(String.format(Locale.getDefault(), "O utilizador tomou %d de %d medicações hoje.", takenCount, patientAlarms.size()));
                        if (statusIcon != null) statusIcon.setImageResource(android.R.drawable.ic_menu_recent_history);
                    }
                }

                // Update Next Medication Card
                View nextCard = view.findViewById(R.id.cardNextMedication);
                if (nextCard != null) {
                    if (nextMed != null) {
                        nextCard.setVisibility(View.VISIBLE);
                        ((TextView)view.findViewById(R.id.textNextTime)).setText(String.format(Locale.getDefault(), "%02d:%02d", nextMed.hour, nextMed.minute));
                        ((TextView)view.findViewById(R.id.textNextTitle)).setText(nextMed.title);
                        String detail = nextMed.time.contains("•") ? nextMed.time.split("•")[1].trim() : "";
                        ((TextView)view.findViewById(R.id.textNextDetail)).setText(detail);
                    } else {
                        nextCard.setVisibility(View.GONE);
                    }
                }
            });
            
            // Start Notification Service
            if (pId != null) {
                String pName = pDoc.getString("name");
                Intent serviceIntent = new Intent(this, GuardianNotificationService.class);
                serviceIntent.putExtra("patientId", pId);
                serviceIntent.putExtra("patientName", pName);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(serviceIntent);
                else startService(serviceIntent);
            }
            
            setupHistoryListener(pId, calendarView, patientAlarms);
        });
    }

    private void startGuardianServiceIfLinked() {
        String pId = prefs.getString("linked_patient_id", null);
        String pName = prefs.getString("linked_patient_name", "Utilizador");
        if (pId != null) {
            Intent serviceIntent = new Intent(this, GuardianNotificationService.class);
            serviceIntent.putExtra("patientId", pId);
            serviceIntent.putExtra("patientName", pName);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(serviceIntent);
            else startService(serviceIntent);
        }
    }

    private void renderPatientAlarmStatus(LinearLayout container, AlarmItem alarm) {
        View card = inflater.inflate(R.layout.item_alarm_card, container, false);
        card.findViewById(R.id.btnConfirmMedication).setVisibility(View.GONE);
        card.findViewById(R.id.switchAlarm).setVisibility(View.GONE);
        card.findViewById(R.id.buttonDeleteAlarm).setVisibility(View.GONE);
        card.findViewById(R.id.buttonEditAlarm).setVisibility(View.GONE);

        ((TextView)card.findViewById(R.id.textAlarmTitle)).setText(alarm.title);
        ((TextView)card.findViewById(R.id.textAlarmTime)).setText(alarm.time);

        TextView statusText = card.findViewById(R.id.textAlarmDays);
        if (isTakenToday(alarm)) {
            String timeStr = new java.text.SimpleDateFormat("HH:mm", Locale.getDefault()).format(new java.util.Date(alarm.lastTakenTimestamp));
            statusText.setText(String.format(Locale.getDefault(), "✓ Tomado às %s", timeStr));
            statusText.setTextColor(ContextCompat.getColor(this, R.color.primary));
            statusText.setBackgroundResource(R.drawable.bg_day_chip); // Reusing chip background
            if (statusText.getBackground() != null) statusText.getBackground().setTint(ContextCompat.getColor(this, R.color.primary_light_bg));
        } else {
            statusText.setText("Aguardando confirmação");
            statusText.setTextColor(ContextCompat.getColor(this, R.color.neutral_medium));
            statusText.setBackgroundResource(R.drawable.bg_day_chip);
            if (statusText.getBackground() != null) statusText.getBackground().setTint(0x1A000000); // Light gray
        }
        container.addView(card);
    }

    private void showAddAlarmDialog() {
        View dialogView = inflater.inflate(R.layout.dialog_add_alarm, null, false);
        EditText titleInput = dialogView.findViewById(R.id.inputAlarmTitle);
        TextView timeDisplay = dialogView.findViewById(R.id.textSelectedTime);
        final int[] selTime = { 8, 0 };
        timeDisplay.setText(String.format(Locale.getDefault(), "%02d:%02d", selTime[0], selTime[1]));

        ((View) timeDisplay.getParent()).setOnClickListener(v -> {
            new android.app.TimePickerDialog(this, (view, h, m) -> {
                selTime[0] = h; selTime[1] = m;
                timeDisplay.setText(String.format(Locale.getDefault(), "%02d:%02d", h, m));
            }, selTime[0], selTime[1], true).show();
        });

        new AlertDialog.Builder(this).setView(dialogView).setPositiveButton("Guardar", (d, w) -> {
            String title = titleInput.getText().toString().trim();
            if (TextUtils.isEmpty(title)) return;
            String time = String.format(Locale.getDefault(), "%02d:%02d", selTime[0], selTime[1]);
            AlarmItem newItem = new AlarmItem(title, time + " • " + ((EditText)dialogView.findViewById(R.id.inputAlarmDetails)).getText().toString().trim(), "Seg • Ter • Qua • Qui • Sex", true);
            newItem.hour = selTime[0]; newItem.minute = selTime[1];
            saveAlarmInFirestore(newItem);
        }).setNegativeButton("Cancelar", null).show();
    }

    private void showEditAlarmDialog(AlarmItem item, int index) {
        editingAlarmIndex = index;
        String[] opts = { "⏰ Alterar horário", "📝 Editar título", "📅 Alterar dias", "🔊 Alterar som" };
        new AlertDialog.Builder(this).setTitle("Editar: " + item.title).setItems(opts, (dialog, which) -> {
            if (which == 0) showChangeTimeDialog(item);
            else if (which == 1) showEditTitleDialog(item);
            else if (which == 2) showEditDaysDialog(item);
            else if (which == 3) showRingtonePicker(item);
        }).setNegativeButton("Fechar", null).show();
    }

    private void showEditDaysDialog(AlarmItem item) {
        String[] days = {"Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"};
        boolean[] checked = new boolean[7];
        if (item.days != null) {
            String[] shorts = {"Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"};
            for (int i=0; i<7; i++) if (item.days.contains(shorts[i])) checked[i] = true;
        }
        new AlertDialog.Builder(this).setTitle("Escolher dias").setMultiChoiceItems(days, checked, (d, w, isC) -> checked[w] = isC)
                .setPositiveButton("OK", (d, w) -> {
                    StringBuilder sb = new StringBuilder();
                    String[] shorts = {"Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"};
                    for (int i=0; i<7; i++) if (checked[i]) { if (sb.length() > 0) sb.append(" • "); sb.append(shorts[i]); }
                    item.days = sb.length() == 0 ? "Nenhum dia" : sb.toString();
                    updateAlarmInFirestore(item);
                }).show();
    }

    private void showChangeTimeDialog(AlarmItem item) {
        new android.app.TimePickerDialog(this, (v, h, m) -> {
            item.hour = h; item.minute = m;
            String det = item.time.contains("•") ? item.time.split("•")[1].trim() : "";
            item.time = String.format(Locale.getDefault(), "%02d:%02d • %s", h, m, det);
            updateAlarmInFirestore(item);
        }, item.hour, item.minute, true).show();
    }

    private void showEditTitleDialog(AlarmItem item) {
        EditText input = new EditText(this); input.setText(item.title);
        new AlertDialog.Builder(this).setTitle("Editar nome").setView(input).setPositiveButton("Guardar", (d, w) -> {
            if (!TextUtils.isEmpty(input.getText())) { item.title = input.getText().toString().trim(); updateAlarmInFirestore(item); }
        }).show();
    }

    private void showRingtonePicker(AlarmItem item) {
        editingAlarmForSound = item;
        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Selecionar som do alarme");
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM);
        if (item.ringtoneUri != null) intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(item.ringtoneUri));
        ringtonePickerLauncher.launch(intent);
    }

    private void loadAlarmsFromFirestore() {
        if (currentUserId == null) return;
        db.collection("users").document(currentUserId).collection("alarms").get().addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                alarms.clear();
                for (QueryDocumentSnapshot d : task.getResult()) {
                    AlarmItem item = d.toObject(AlarmItem.class);
                    item.documentId = d.getId();
                    alarms.add(item);
                    if (item.enabled) scheduleAlarm(item);
                }
                if (currentTab == Tab.ALARMS) renderAlarms();
            }
        });
    }

    private void saveAlarmInFirestore(AlarmItem item) {
        db.collection("users").document(currentUserId).collection("alarms").add(item).addOnSuccessListener(ref -> {
            item.documentId = ref.getId(); alarms.add(item); renderAlarms(); scheduleAlarm(item);
        });
    }

    private void updateAlarmInFirestore(AlarmItem item) {
        if (currentUserId != null && item.documentId != null)
            db.collection("users").document(currentUserId).collection("alarms").document(item.documentId).set(item).addOnSuccessListener(a -> {
                renderAlarms(); scheduleAlarm(item);
            });
    }

    private void scheduleAlarm(AlarmItem item) {
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (am == null) return;

        if (!item.enabled) {
            cancelAlarm(item);
            return;
        }

        Intent intent = new Intent(this, AlarmReceiver.class);
        intent.putExtra("alarm_title", item.title);
        intent.putExtra("alarm_message", "Hora de tomar: " + item.title);
        intent.putExtra("ringtone_uri", item.ringtoneUri);
        intent.putExtra("alarm_doc_id", item.documentId);
        
        int reqCode = item.documentId != null ? item.documentId.hashCode() : (int) System.currentTimeMillis();
        PendingIntent pi = PendingIntent.getBroadcast(this, reqCode, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, item.hour);
        cal.set(Calendar.MINUTE, item.minute);
        cal.set(Calendar.SECOND, 0);

        if (cal.getTimeInMillis() <= System.currentTimeMillis()) cal.add(Calendar.DAY_OF_YEAR, 1);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
        } else {
            am.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
        }
    }

    private void cancelAlarm(AlarmItem item) {
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (am == null || item.documentId == null) return;
        Intent intent = new Intent(this, AlarmReceiver.class);
        int reqCode = item.documentId.hashCode();
        PendingIntent pi = PendingIntent.getBroadcast(this, reqCode, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_NO_CREATE);
        if (pi != null) { am.cancel(pi); pi.cancel(); }
    }

    private void deleteAlarmFromFirestore(AlarmItem item, int index) {
        new AlertDialog.Builder(this).setTitle("Remover").setMessage("Remover " + item.title + "?")
                .setPositiveButton("Sim", (d, w) -> {
                    db.collection("users").document(currentUserId).collection("alarms").document(item.documentId).delete().addOnSuccessListener(a -> {
                        cancelAlarm(item); alarms.remove(index); renderAlarms();
                    });
                }).show();
    }

    private void showIntroDialogIfNeeded() {
        if (!prefs.getBoolean("has_seen_intro", false)) {
            View v = inflater.inflate(R.layout.dialog_intro, null);
            AlertDialog d = new AlertDialog.Builder(this).setView(v).setCancelable(false).create();
            v.findViewById(R.id.btnSkipIntro).setOnClickListener(view -> { prefs.edit().putBoolean("has_seen_intro", true).apply(); d.dismiss(); });
            d.show();
        }
    }

    private void fetchLocationAndWeather() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION);
            return;
        }

        fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
            if (location != null) {
                // Reverse geocode to get city name
                try {
                    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
                    List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
                    if (addresses != null && !addresses.isEmpty()) {
                        String city = addresses.get(0).getLocality();
                        if (city == null) city = addresses.get(0).getSubAdminArea();
                        if (city == null) city = addresses.get(0).getAdminArea();
                        if (textLocation != null && city != null) {
                            textLocation.setText(city);
                        }
                    }
                } catch (Exception e) {
                    Log.e("Geocoder", "Failed to get city name", e);
                    if (textLocation != null) textLocation.setText("Localização");
                }

                // Fetch weather data
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl("https://api.open-meteo.com/")
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

                WeatherService service = retrofit.create(WeatherService.class);
                service.getCurrentWeather(location.getLatitude(), location.getLongitude()).enqueue(new Callback<WeatherResponse>() {
                    @Override
                    public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) {
                        if (response.isSuccessful() && response.body() != null) {
                            double temp = response.body().currentWeather.temperature;
                            int code = response.body().currentWeather.weatherCode;
                            if (textTemperature != null) {
                                textTemperature.setText(String.format(Locale.getDefault(), "%.1f°C", temp));
                            }
                            if (textCondition != null) {
                                textCondition.setText(getWeatherCondition(code));
                            }
                            if (textTipDesc1 != null) {
                                textTipDesc1.setText(String.format(Locale.getDefault(), "%s, %.1f°C", getWeatherCondition(code), temp));
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<WeatherResponse> call, Throwable t) {
                        if (textCondition != null) textCondition.setText("Clima indisponível");
                    }
                });
            } else {
                Log.e("Location", "Last location is null");
                if (textLocation != null) textLocation.setText("GPS indisponível");
            }
        }).addOnFailureListener(e -> {
            Log.e("Location", "Failed to get location", e);
            if (textLocation != null) textLocation.setText("Erro GPS");
        });
    }

    private String getWeatherCondition(int code) {
        if (code == 0) return "Céu limpo";
        if (code <= 3) return "Parcialmente nublado";
        if (code <= 48) return "Nevoeiro";
        if (code <= 57) return "Chuviscos";
        if (code <= 67) return "Chuva";
        if (code <= 77) return "Neve";
        if (code <= 82) return "Aguaceiros";
        if (code <= 86) return "Neve forte";
        if (code <= 99) return "Trovoada";
        return "Sem dados";
    }

    @Override protected void onDestroy() { 
        super.onDestroy(); 
        if (guardianAlarmsListener != null) guardianAlarmsListener.remove(); 
        if (patientCalendarListener != null) patientCalendarListener.remove(); 
        if (historyListener != null) historyListener.remove();
        if (userDocListener != null) userDocListener.remove();
    }

    public static class AlarmItem {
        public String documentId, title, time, days, ringtoneUri;
        public boolean enabled, takenToday;
        public int hour, minute;
        public long lastTakenTimestamp;
        public AlarmItem() { }
        public AlarmItem(String title, String time, String days, boolean enabled) {
            this.title = title; this.time = time; this.days = days; this.enabled = enabled;
        }
    }
}
