package com.example.cuida.ui.schedule;

import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.cuida.R;
import java.util.Calendar;

public class ScheduleAppointmentFragment extends Fragment {

    private ScheduleViewModel scheduleViewModel;
    private DatePicker datePicker;
    private AutoCompleteTextView spinnerDoctor;
    private RecyclerView recyclerTimeSlots;
    private Button btnConfirm;
    private TimeSlotAdapter timeSlotAdapter;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_schedule_appointment, container, false);

        scheduleViewModel = new ViewModelProvider(this).get(ScheduleViewModel.class);

        datePicker = root.findViewById(R.id.datePicker);
        spinnerDoctor = root.findViewById(R.id.spinner_doctor);
        recyclerTimeSlots = root.findViewById(R.id.recycler_time_slots);
        btnConfirm = root.findViewById(R.id.btn_confirm_appointment);

        setupDoctorSpinner();
        setupDatePicker();
        setupRecyclerView();
        setupObservers();

        btnConfirm.setOnClickListener(v -> {
            com.google.android.material.textfield.TextInputEditText editReason = getView()
                    .findViewById(R.id.edit_reason);
            String reason = editReason.getText().toString();

            if (scheduleViewModel.getSelectedTime().getValue() == null) {
                Toast.makeText(getContext(), "Selecione um horário.", Toast.LENGTH_SHORT).show();
                return;
            }

            if (reason.isEmpty()) {
                Toast.makeText(getContext(), "Indique o motivo.", Toast.LENGTH_SHORT).show();
                return;
            }

            String selectedDoctor = spinnerDoctor.getText().toString();
            if (selectedDoctor.isEmpty()) {
                Toast.makeText(getContext(), "Selecione um médico.", Toast.LENGTH_SHORT).show();
                return;
            }
            
            if (isUrgentSymptom(reason)) {
                showUrgencyAlert(selectedDoctor, reason);
            } else {
                scheduleViewModel.confirmAppointment(selectedDoctor, reason);
            }
        });

        return root;
    }

    private boolean isUrgentSymptom(String reason) {
        String lowerReason = reason.toLowerCase();
        String[] urgentKeywords = {
            "dor no peito", "falta de ar", "desmaio", "sangramento",
            "paralisia", "perda de vis", "dormência", "confusão",
            "aperto no peito", "convulsão", "hemorragia", "asfixia"
        };
        
        for (String keyword : urgentKeywords) {
            if (lowerReason.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    private void showUrgencyAlert(String selectedDoctor, String reason) {
        new AlertDialog.Builder(requireContext())
            .setTitle("Aviso de Urgência Médica")
            .setMessage("O motivo indicado parece necessitar de atendimento urgente. Para situações graves, dirija-se ao Hospital mais próximo ou ligue 112.\n\nPretende continuar com o agendamento normal?")
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setPositiveButton("Agendar na mesma", (dialog, which) -> {
                scheduleViewModel.confirmAppointment(selectedDoctor, reason);
            })
            .setNegativeButton("Cancelar", null)
            .show();
    }

    private void setupDoctorSpinner() {
        scheduleViewModel.getDoctorsList().observe(getViewLifecycleOwner(), doctors -> {
            if (doctors != null) {
                java.util.List<String> shuffledDoctors = new java.util.ArrayList<>(doctors);
                java.util.Collections.shuffle(shuffledDoctors); // Randomize the names as requested
                ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_dropdown_item_1line, shuffledDoctors);
                spinnerDoctor.setAdapter(adapter);
            }
        });

        spinnerDoctor.setOnItemClickListener((parent, view, position, id) -> {
            String selectedDoctor = (String) parent.getItemAtPosition(position);
            scheduleViewModel.setSelectedDoctor(selectedDoctor);
        });
    }

    private void setupDatePicker() {
        Calendar today = Calendar.getInstance();
        datePicker.init(today.get(Calendar.YEAR), today.get(Calendar.MONTH),
                today.get(Calendar.DAY_OF_MONTH), (view, year, monthOfYear, dayOfMonth) -> {
                    scheduleViewModel.setDate(year, monthOfYear, dayOfMonth);
                });

        // Set initial valid date in VM
        scheduleViewModel.setDate(today.get(Calendar.YEAR), today.get(Calendar.MONTH),
                today.get(Calendar.DAY_OF_MONTH));

        // Prevent past dates
        datePicker.setMinDate(System.currentTimeMillis() - 1000);

        // Hide the year component
        int yearSpinnerId = android.content.res.Resources.getSystem().getIdentifier("year", "id", "android");
        if (yearSpinnerId != 0) {
            View yearSpinner = datePicker.findViewById(yearSpinnerId);
            if (yearSpinner != null) {
                yearSpinner.setVisibility(View.GONE);
            }
        }

        int daySpinnerId = android.content.res.Resources.getSystem().getIdentifier("day", "id", "android");
        int monthSpinnerId = android.content.res.Resources.getSystem().getIdentifier("month", "id", "android");
        if (daySpinnerId != 0 && monthSpinnerId != 0) {
            View daySpinner = datePicker.findViewById(daySpinnerId);
            View monthSpinner = datePicker.findViewById(monthSpinnerId);
            if (daySpinner != null && monthSpinner != null) {
                if (monthSpinner instanceof android.widget.NumberPicker) {
                    String[] ptMonths = new String[]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"};
                    ((android.widget.NumberPicker) monthSpinner).setDisplayedValues(ptMonths);
                }
                ViewGroup parent = (ViewGroup) daySpinner.getParent();
                if (parent != null && parent.equals(monthSpinner.getParent())) {
                    int dIndex = parent.indexOfChild(daySpinner);
                    int mIndex = parent.indexOfChild(monthSpinner);
                    // We want Day to be before Month (Day on Left, Month on Right)
                    if (dIndex > mIndex) {
                        parent.removeView(daySpinner);
                        parent.addView(daySpinner, mIndex);
                    }
                }
            }
        }
    }

    private void setupRecyclerView() {
        timeSlotAdapter = new TimeSlotAdapter();
        timeSlotAdapter.setOnTimeSlotSelectedListener(time -> scheduleViewModel.setTime(time));

        recyclerTimeSlots.setLayoutManager(new GridLayoutManager(getContext(), 4));
        recyclerTimeSlots.setAdapter(timeSlotAdapter);
    }

    private void setupObservers() {
        scheduleViewModel.getTimeSlots().observe(getViewLifecycleOwner(), slots -> {
            timeSlotAdapter.setTimeSlots(slots);
        });

        scheduleViewModel.getSaveSuccess().observe(getViewLifecycleOwner(), success -> {
            if (success) {
                Toast.makeText(getContext(), "Consulta agendada!", Toast.LENGTH_SHORT).show();
                if (getActivity() != null) {
                    getActivity().getSupportFragmentManager().popBackStack();
                }
            }
        });
        
        scheduleViewModel.getSaveError().observe(getViewLifecycleOwner(), errorMsg -> {
            if (errorMsg != null && !errorMsg.isEmpty()) {
                new AlertDialog.Builder(requireContext())
                    .setTitle("Horário Indisponível")
                    .setMessage(errorMsg)
                    .setPositiveButton("OK", null)
                    .show();
            }
        });

        scheduleViewModel.getSelectedDoctorSchedule().observe(getViewLifecycleOwner(), schedule -> {
            android.widget.TextView textSchedule = getView().findViewById(R.id.text_doctor_schedule);
            if (textSchedule != null) {
                textSchedule.setText(schedule);
            }
        });
    }
}
