package com.example.cuida.ui.medication; import android.app.Dialog; import android.app.TimePickerDialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; import android.widget.TextView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.textfield.TextInputEditText; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import com.example.cuida.R; import com.example.cuida.data.model.Medication; import java.util.Calendar; import java.util.Locale; import java.util.ArrayList; import java.util.List; 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 android.text.Editable; import android.text.TextWatcher; import com.example.cuida.data.model.Comprimido; import android.widget.AdapterView; import android.widget.Toast; import com.google.android.material.chip.Chip; import com.google.android.material.chip.ChipGroup; import com.google.android.material.button.MaterialButton; import java.util.Collections; public class MedicationDialog extends DialogFragment { private TextInputEditText editName; private RecyclerView recyclerResults; private ComprimidoRecyclerAdapter recyclerAdapter; private List searchResults = new ArrayList<>(); private List fullPillsList = new ArrayList<>(); private DatabaseReference medicationRef; private EditText editNotes; private android.widget.RadioButton radioOral, radioTopical, radioInhalatory; private android.widget.RadioGroup radioGroupRoute; private ChipGroup chipGroupTimes; private List selectedTimes = new ArrayList<>(); private Medication medicationToEdit; private OnMedicationSaveListener listener; private OnMedicationDeleteListener deleteListener; public interface OnMedicationSaveListener { void onSave(Medication medication); } public interface OnMedicationDeleteListener { void onDelete(Medication medication); } public void setListener(OnMedicationSaveListener listener) { this.listener = listener; } public void setDeleteListener(OnMedicationDeleteListener listener) { this.deleteListener = listener; } public void setMedicationToEdit(Medication medication) { this.medicationToEdit = medication; } @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); LayoutInflater inflater = requireActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.dialog_add_medication, null); editName = view.findViewById(R.id.edit_med_name); recyclerResults = view.findViewById(R.id.recycler_search_results); editNotes = view.findViewById(R.id.edit_med_notes); chipGroupTimes = view.findViewById(R.id.chip_group_times); MaterialButton btnAddTime = view.findViewById(R.id.btn_add_time); radioGroupRoute = view.findViewById(R.id.radio_group_route); radioOral = view.findViewById(R.id.radio_oral); radioTopical = view.findViewById(R.id.radio_topical); radioInhalatory = view.findViewById(R.id.radio_inhalatory); final android.content.Context currentContext = getContext(); if (currentContext != null) { recyclerAdapter = new ComprimidoRecyclerAdapter(searchResults, selected -> { editName.setText(selected.nome); editName.setSelection(selected.nome.length()); // Adiciona a dosagem/informação ao campo de notas automaticamente if (selected.dosagem != null && !selected.dosagem.isEmpty()) { editNotes.setText(selected.dosagem); } recyclerResults.setVisibility(View.GONE); searchResults.clear(); }); recyclerResults.setLayoutManager(new LinearLayoutManager(currentContext)); recyclerResults.setAdapter(recyclerAdapter); String dbUrl = "https://cuidamais-7b904-default-rtdb.firebaseio.com/"; medicationRef = FirebaseDatabase.getInstance(dbUrl).getReference("medication"); // Carregar todos os medicamentos uma única vez para filtragem local rápida fetchAllMedsOnce(); editName.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterMedsLocally(s.toString().trim()); } @Override public void afterTextChanged(Editable s) {} }); } radioGroupRoute = view.findViewById(R.id.radio_group_route); radioOral = view.findViewById(R.id.radio_oral); radioTopical = view.findViewById(R.id.radio_topical); radioInhalatory = view.findViewById(R.id.radio_inhalatory); // Set up TimePicker btnAddTime.setOnClickListener(v -> showTimePicker()); if (medicationToEdit != null) { editName.setText(medicationToEdit.name); editNotes.setText(medicationToEdit.notes); if (medicationToEdit.time != null && !medicationToEdit.time.isEmpty()) { String[] times = medicationToEdit.time.split(",\\s*"); for (String t : times) { if (!t.isEmpty()) selectedTimes.add(t); } refreshTimeChips(); } String dosage = medicationToEdit.dosage; if (dosage != null) { if (dosage.contains("Oral")) radioOral.setChecked(true); else if (dosage.contains("Tópica")) radioTopical.setChecked(true); else if (dosage.contains("Inalatória")) radioInhalatory.setChecked(true); } builder.setTitle("Editar Medicamento"); } else { builder.setTitle("Adicionar Medicamento"); // Default time to current time Calendar cal = Calendar.getInstance(); String defaultTime = String.format(Locale.getDefault(), "%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); selectedTimes.add(defaultTime); refreshTimeChips(); } builder.setView(view) .setPositiveButton("Guardar", (dialog, id) -> { String name = editName.getText().toString(); String notes = editNotes.getText().toString(); // Join times with comma StringBuilder timeBuilder = new StringBuilder(); for (int i = 0; i < selectedTimes.size(); i++) { timeBuilder.append(selectedTimes.get(i)); if (i < selectedTimes.size() - 1) timeBuilder.append(", "); } String time = timeBuilder.toString(); int selectedId = radioGroupRoute.getCheckedRadioButtonId(); String dosage = "Via não especificada"; if (selectedId == R.id.radio_oral) { dosage = "Via Oral"; } else if (selectedId == R.id.radio_topical) { dosage = "Via Tópica"; } else if (selectedId == R.id.radio_inhalatory) { dosage = "Via Inalatória"; } if (medicationToEdit != null) { medicationToEdit.name = name; medicationToEdit.dosage = dosage; medicationToEdit.notes = notes; medicationToEdit.time = time; if (listener != null) listener.onSave(medicationToEdit); } else { Medication newMed = new Medication(name, time, dosage, notes, null); if (listener != null) listener.onSave(newMed); } }); if (medicationToEdit != null) { builder.setNeutralButton("Eliminar", (dialog, id) -> { if (deleteListener != null) { deleteListener.onDelete(medicationToEdit); } }); } AlertDialog alertDialog = builder.create(); alertDialog.setOnShowListener(d -> { android.widget.Button btnPos = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); if (btnPos != null) { // Apply our custom outline drawable to "Guardar" btnPos.setBackgroundResource(R.drawable.btn_outline_primary); btnPos.setTextColor(androidx.core.content.ContextCompat.getColor(requireContext(), R.color.primary_color)); int paddingPx = (int) (16 * getResources().getDisplayMetrics().density); btnPos.setPadding(paddingPx, 0, paddingPx, 0); } android.widget.Button btnNeu = alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL); if (btnNeu != null) { btnNeu.setTextColor(androidx.core.content.ContextCompat.getColor(requireContext(), R.color.error_color)); btnNeu.setBackgroundResource(R.drawable.btn_outline_error); int paddingPx = (int) (16 * getResources().getDisplayMetrics().density); btnNeu.setPadding(paddingPx, 0, paddingPx, 0); android.view.ViewGroup.LayoutParams lp = btnNeu.getLayoutParams(); if (lp instanceof android.view.ViewGroup.MarginLayoutParams) { android.view.ViewGroup.MarginLayoutParams marginLp = (android.view.ViewGroup.MarginLayoutParams) lp; int marginPx = (int) (8 * getResources().getDisplayMetrics().density); marginLp.setMargins(marginLp.leftMargin, marginLp.topMargin, marginLp.rightMargin + marginPx, marginLp.bottomMargin); btnNeu.setLayoutParams(marginLp); } } }); return alertDialog; } private void showTimePicker() { Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); TimePickerDialog timePickerDialog = new TimePickerDialog(getContext(), (view, hourOfDay, minute1) -> { String time = String.format(Locale.getDefault(), "%02d:%02d", hourOfDay, minute1); if (!selectedTimes.contains(time)) { selectedTimes.add(time); Collections.sort(selectedTimes); refreshTimeChips(); } }, hour, minute, true); timePickerDialog.show(); } private void refreshTimeChips() { if (chipGroupTimes == null) return; chipGroupTimes.removeAllViews(); for (String time : selectedTimes) { Chip chip = new Chip(requireContext()); chip.setText(time); chip.setCloseIconVisible(true); chip.setOnCloseIconClickListener(v -> { selectedTimes.remove(time); refreshTimeChips(); }); chipGroupTimes.addView(chip); } } private void fetchAllMedsOnce() { String dbUrl = "https://cuidamais-7b904-default-rtdb.firebaseio.com/"; DatabaseReference rootRef = FirebaseDatabase.getInstance(dbUrl).getReference(); String[] nodes = {"medication", "medicamentos", "Medicamentos", "comprimidos"}; fullPillsList.clear(); // 1. Tentar nos nós específicos for (String node : nodes) { rootRef.child(node).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { parseSnapshot(snapshot, "Nó: " + node); } } @Override public void onCancelled(@NonNull DatabaseError error) {} }); } // 2. Tentar também na raiz (caso os medicamentos estejam diretamente no topo) rootRef.limitToFirst(50).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { parseSnapshot(snapshot, "Raiz"); } } @Override public void onCancelled(@NonNull DatabaseError error) {} }); } private void parseSnapshot(DataSnapshot snapshot, String source) { int count = 0; for (DataSnapshot child : snapshot.getChildren()) { String name = child.child("nome").getValue(String.class); if (name == null) name = child.child("name").getValue(String.class); if (name == null && !(child.getValue() instanceof java.util.Map)) { // Se o valor for a própria string (ex: "Paracetamol") name = child.getValue() instanceof String ? (String) child.getValue() : null; } if (name == null) name = child.getKey(); String dosage = child.child("dosagem").getValue(String.class); if (dosage == null) dosage = child.child("dosage").getValue(String.class); if (dosage == null) dosage = ""; if (name != null && !name.isEmpty()) { boolean exists = false; for (Comprimido p : fullPillsList) { if (name.equals(p.nome)) { exists = true; break; } } if (!exists) { fullPillsList.add(new Comprimido(name, dosage)); count++; } } } if (count > 0 && getContext() != null) { Log.d("FirebaseSearch", "Carregados " + count + " de " + source); // Toast.makeText(getContext(), "Fonte: " + source + " (" + count + ")", Toast.LENGTH_SHORT).show(); } } private void filterMedsLocally(String query) { searchResults.clear(); if (query.isEmpty()) { recyclerResults.setVisibility(View.GONE); recyclerAdapter.notifyDataSetChanged(); return; } String lowerQuery = query.toLowerCase(); for (Comprimido p : fullPillsList) { if (p.nome != null && p.nome.toLowerCase().contains(lowerQuery)) { searchResults.add(p); } } recyclerAdapter.notifyDataSetChanged(); recyclerResults.setVisibility(searchResults.isEmpty() ? View.GONE : View.VISIBLE); } private void handleError(DatabaseError error) { Log.e("FirebaseSearch", "Erro: " + error.getMessage()); if (getContext() != null) { Toast.makeText(getContext(), "Erro no Firebase: " + error.getMessage(), Toast.LENGTH_LONG).show(); } } }