Files
cuidamais/documentacao_projecto/backups_codigo/MedicationDialog.java

369 lines
16 KiB
Java

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<Comprimido> searchResults = new ArrayList<>();
private List<Comprimido> 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<String> 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();
}
}
}