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

        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);
                }
                java.util.Collections.sort(selectedTimes);
                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.US, "%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
            selectedTimes.add(defaultTime);
            refreshTimeChips();
        }

        // Positive button sem lógica — a validação é feita no setOnShowListener abaixo
        builder.setView(view)
                .setPositiveButton("Guardar", null);

        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) {
                // Estilo do botão 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);

                // Validação ao clicar em Guardar (impede o fecho automático do dialog)
                btnPos.setOnClickListener(v -> {
                    String name = editName.getText() != null ? editName.getText().toString().trim() : "";

                    // 1. Nome obrigatório
                    if (name.isEmpty()) {
                        Toast.makeText(getContext(), "Preencha o nome.", Toast.LENGTH_SHORT).show();
                        editName.requestFocus();
                        return;
                    }

                    // 2. Via de administração obrigatória
                    int selectedId = radioGroupRoute.getCheckedRadioButtonId();
                    if (selectedId == -1) {
                        Toast.makeText(getContext(), "Selecione a via.", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    // 3. Pelo menos um horário obrigatório
                    if (selectedTimes.isEmpty()) {
                        Toast.makeText(getContext(), "Adicione um horário.", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    // Tudo válido — construir e guardar
                    String notes = editNotes.getText() != null ? editNotes.getText().toString() : "";

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

                    String dosage;
                    if (selectedId == R.id.radio_oral) {
                        dosage = "Via Oral";
                    } else if (selectedId == R.id.radio_topical) {
                        dosage = "Via Tópica";
                    } else {
                        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);
                    }

                    alertDialog.dismiss();
                });
            }

            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.US, "%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 || getContext() == null) return;
        chipGroupTimes.removeAllViews();
        for (String time : selectedTimes) {
            Chip chip = new Chip(getContext());
            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();
        }
    }
}
