import moment from 'moment';

$(document).ready(function(){
    // Variable global para almacenar los días disponibles del doctor
    window.doctorScheduleDays = [];

    // Deshabilitar inicialmente el select de doctores si no hay especialidad seleccionada
    const especialitySelect = document.querySelector('#especiality');
    const doctorSelect = document.querySelector('#doctorId');
    
    // Si no hay especialidad seleccionada, deshabilitar el select de doctores
    if (especialitySelect && doctorSelect && (!especialitySelect.value || especialitySelect.value === 'SELECT')) {
        doctorSelect.disabled = true;
        
        // Agregar texto de ayuda al select de doctores
        $(doctorSelect).empty().append(`<option value="">${window.translations["create-appointment"].selectSpecialityFirst}</option>`);
    }

    // Si ya hay una especialidad seleccionada al cargar la página, cargar los doctores relacionados
    if (especialitySelect && especialitySelect.value && especialitySelect.value !== 'SELECT') {
        loadDoctorsBySpeciality(especialitySelect.value);
        
        // Habilitar el select de doctores
        if (doctorSelect) doctorSelect.disabled = false;
    }
    
    // Si ya hay un doctor seleccionado al cargar la página, cargar su horario
    if (doctorSelect && doctorSelect.value && doctorSelect.value !== 'SELECT') {
        loadDoctorSchedule(doctorSelect.value);
        
        // Si también hay una fecha seleccionada, cargar las horas disponibles
        const dateInput = document.querySelector('#dateAppointment');
        if (dateInput && dateInput.value) {
            loadAvailableHours(dateInput.value);
        }
    }

    // Evento para cuando el usuario intenta interactuar con el select de doctores sin haber seleccionado especialidad
    $(doctorSelect).on('mousedown', function(e) {
        const especialityValue = $('#especiality').val();
        if (!especialityValue || especialityValue === 'SELECT') {
            e.preventDefault();
            alert(window.translations["create-appointment"].selectSpecialityFirst);
            return false;
        }
    });

    $.fn.getDays = function(){
        var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        return days;
    }
    /**
     * 
     * @returns 
     */
    $.fn.validations = function(){
        return [
            {
            "name":"noEmpty",
            "message":window.translations["create-appointment"].fieldRequired,
            "run":function (field){
                if((field.key === "date") || (field.key==="dateAppointment")) 
                    return true;
                return ((field.value != undefined) && (field.value.trim() !== "")); 
            },
            },
            {
                "name":"noEmptySelect",
                "message":window.translations["create-appointment"].fieldRequired,
                "run":function (field){
                    return (field.value !== "SELECT"); 
                },
            }
        ];
    }

    $.dateAppointment = null;
    $("#appointment").on("submit",function(e){
        let form    = document.querySelector("#appointment");
        let data    = $.fn.getDataForm.call(this,form);
        let valid   = $.fn.runValidations(data,$.fn.validations());
        
        // Obtener la fecha del calendario
        const dateAppointment = $.dateAppointment;
        
        // Obtener la hora seleccionada del listado de horas disponibles
        const selectedTime = $("#available-hours").val();
        
        if(!valid.valid) {
            e.preventDefault();
        } 
        // Validar que se haya seleccionado fecha y hora
        else if(!dateAppointment) {
            alert(window.translations["create-appointment"].emptyDate);
            e.preventDefault();
        }
        else if(!selectedTime) {
            alert("Por favor seleccione una hora disponible");
            e.preventDefault();
        }
        else {
            try {
                // Crear fecha combinando la fecha seleccionada con la hora del listado
                const selectedDate = new Date(dateAppointment);
                
                // Obtener hora y minutos de la hora seleccionada
                const timeParts = selectedTime.split(':');
                if (timeParts.length >= 2) {
                    const hour = parseInt(timeParts[0]);
                    const minute = parseInt(timeParts[1]);
                    
                    // Establecer la hora y minutos en la fecha
                    selectedDate.setHours(hour, minute, 0);
                    
                    // Formatear la fecha y hora para el envío
                    const formattedDateTime = moment(selectedDate).format('YYYY-MM-DD HH:mm:ss');
                    $("#date").val(formattedDateTime);
                    
                    // También actualizar los campos antiguos para compatibilidad
                    let displayHour = hour;
                    const scheduleValue = hour >= 12 ? 'PM' : 'AM';
                    
                    // Ajustar para formato 12 horas
                    if (displayHour > 12) {
                        displayHour -= 12;
                    } else if (displayHour === 0) {
                        displayHour = 12;
                    }
                    
                    $("#hour").val(displayHour < 10 ? '0' + displayHour : displayHour);
                    $("#minute").val(minute < 10 ? '0' + minute : minute);
                    $("#schedule").val(scheduleValue);
                } else {
                    console.error("Formato de hora inválido");
                    e.preventDefault();
                }
            } catch (error) {
                console.error('Error al formatear la fecha y hora:', error);
                e.preventDefault();
            }
        }
    });

    $("#RegisterPatient").on("click",function(){
        let form    = document.querySelector("#appointment");
        let data    = $.fn.getDataForm.call(this,form);
        let dataSend = {};

        if((window.appointmentDate != undefined) && (window.appointmentDate !== ""))
            dataSend.date = window.appointmentDate.toString();
        if(data.dateAppointment !== "")
            dataSend.dateAppointment = data.dateAppointment;
        if(data.especiality !== "")
            dataSend.especiality = data.especiality;
        if(data.hour !== "")
            dataSend.hour = data.hour;
        if(data.minute !== "")
            dataSend.minute = data.minute;
        if(data.schedule !== "")
            dataSend.schedule = data.schedule; 
        if(data.summary !== "")
            dataSend.summary = data.summary; 
        if(data.doctorname !== "")
            dataSend.doctorname = data.doctorname;

        let params = new URLSearchParams(dataSend).toString();
        let url = "create-patient?continueFromAppointment=1&" + params;
        
        window.location.href=url;
        //console.log(JSON.stringify(data));
    });

    // Evento para cuando cambia el doctor seleccionado
    $("#doctorId").change(function() {
        var doctorId = $(this).val();
        if (doctorId && doctorId !== 'SELECT') {
            loadDoctorSchedule(doctorId);
            // Limpiar fecha y hora seleccionada
            $("#dateAppointment").val("");
            $("#hour").val("");
            $("#minute").val("");
            $("#schedule").val("SELECT");
            $("#available-hours").empty().append('<option value="">Seleccione una fecha primero</option>');
        } else {
            window.doctorScheduleDays = [];
            // Limpiar fecha y hora seleccionada
            $("#dateAppointment").val("");
            $("#hour").val("");
            $("#minute").val("");
            $("#schedule").val("SELECT");
            $("#available-hours").empty().append('<option value="">Seleccione un doctor y una fecha primero</option>');
            // Resetear checkboxes de días
            document.querySelectorAll('.doctor-day-checkbox').forEach(checkbox => {
                checkbox.checked = false;
                checkbox.parentElement.classList.remove('active');
            });
        }
    });

    // Evento para cuando cambia la especialidad seleccionada
    $("#especiality").change(function() {
        const especialityId = $(this).val();
        if (especialityId && especialityId !== 'SELECT') {
            // Habilitar el select de doctores
            $("#doctorId").prop('disabled', false);
            
            loadDoctorsBySpeciality(especialityId);
        } else {
            // Deshabilitar y resetear el select de doctores
            $("#doctorId").prop('disabled', true)
                .empty()
                .append(`<option value="">${window.translations["create-appointment"].selectSpecialityFirst}</option>`);
            
            // Limpiar fecha y hora seleccionada
            $("#dateAppointment").val("");
            $("#hour").val("");
            $("#minute").val("");
            $("#schedule").val("SELECT");
            $("#available-hours").empty().append('<option value="">Seleccione un doctor y una fecha primero</option>');
            
            // Resetear checkboxes de días
            document.querySelectorAll('.doctor-day-checkbox').forEach(checkbox => {
                checkbox.checked = false;
                checkbox.parentElement.classList.remove('active');
            });
        }
    });

    // Evento para cuando se selecciona una hora disponible
    $(document).on('change', '#available-hours', function() {
        const selectedTime = $(this).val();
        if (!selectedTime) return;
        
        // Parsear la hora seleccionada
        const timeParts = selectedTime.split(':');
        if (timeParts.length < 2) return;
        
        let hour = parseInt(timeParts[0]);
        const minute = timeParts[1];
        
        // Configurar AM/PM
        const scheduleValue = hour >= 12 ? 'PM' : 'AM';
        $("#schedule").val(scheduleValue);
        
        // Ajustar hora para formato 12 horas
        if (hour > 12) {
            hour -= 12;
        } else if (hour === 0) {
            hour = 12;
        }
        
        // Actualizar campos originales
        $("#hour").val(hour < 10 ? '0' + hour : hour);
        $("#minute").val(minute);
        
        // Si estamos en un formulario de cita, también actualizar el campo oculto date
        // con la fecha y hora completa para el envío
        const dateAppointment = $("#dateAppointment").val();
        if (dateAppointment) {
            try {
                const selectedDate = new Date(dateAppointment);
                
                // Configurar hora y minutos
                let submitHour = parseInt(timeParts[0]);
                let submitMinute = parseInt(timeParts[1]);
                
                selectedDate.setHours(submitHour, submitMinute, 0);
                
                // Actualizar el campo oculto date con el valor formateado
                const formattedDateTime = moment(selectedDate).format('YYYY-MM-DD HH:mm:ss');
                $("#date").val(formattedDateTime);
            } catch (error) {
                console.error('Error al formatear la fecha:', error);
            }
        }
    });



    // Aplicar estilos CSS para días disponibles/no disponibles
    if (!$("#calendar-styles").length) {
        $("head").append(
            '<style id="calendar-styles">' +
            '.doctor-available-day { background-color: #e6f7ff !important; }' +
            '.doctor-unavailable-day { background-color: #f5f5f5 !important; opacity: 0.7; }' +
            '</style>'
        );
    }
})

/**
 * Cargar el horario del doctor
 */
function loadDoctorSchedule(doctorId) {
    if (!doctorId) return;

    // Mostrar spinner o indicador de carga
    const dateInput = document.querySelector('#dateAppointment');
    const hourInput = document.querySelector('#available-hours');
    
    // Deshabilitar campos mientras se carga
    if (dateInput) dateInput.disabled = true;
    if (hourInput) hourInput.disabled = true;
    
    // Limpiar valores anteriores
    if (dateInput) dateInput.value = '';
    if (hourInput) hourInput.innerHTML = '<option value="">Seleccione una hora</option>';
    
    // Resetear todos los checkboxes de días
    document.querySelectorAll('.doctor-day-checkbox').forEach(checkbox => {
        checkbox.checked = false;
        checkbox.parentElement.classList.remove('active');
    });
    
    // Eliminar mensaje de alerta anterior si existe
    $('.doctor-schedule-alert').remove();
    
    // Hacer la petición AJAX para obtener el horario del doctor
    $.ajax({
        url: `/api/doctors/${doctorId}/available-schedules`,
        type: 'GET',
        success: function(response) {
            // Guardar los días disponibles
            window.doctorScheduleDays = response.availableDays.map(day => day.dayOfWeek);
            
            // Verificar si hay días disponibles
            if (!response.availableDays || response.availableDays.length === 0) {
                // Mostrar alerta de que no hay horarios configurados
                const alertMessage = `
                    <div class="alert alert-warning doctor-schedule-alert mt-2 mb-3">
                        <i class="fas fa-exclamation-triangle"></i> 
                        El doctor seleccionado no tiene horarios configurados.
                    </div>
                `;
                $('.doctor-days-container').after(alertMessage);
                
                // Deshabilitar selección de fecha
                if (dateInput) dateInput.disabled = true;
                return;
            }
            
            // Actualizar los checkboxes de días disponibles
            response.availableDays.forEach(day => {
                const dayCheckbox = document.querySelector(`#day-${day.dayOfWeek}`);
                if (dayCheckbox) {
                    dayCheckbox.checked = true;
                    dayCheckbox.parentElement.classList.add('active');
                }
            });
            
            // Crear un array de índices de días disponibles para el datepicker
            const availableDays = response.availableDays.map(day => day.dayOfWeek);
            
            // Habilitar el campo de fecha
            if (dateInput) dateInput.disabled = false;
            
            // Inicializar o actualizar el datepicker si existe
            if (dateInput && typeof flatpickr !== 'undefined') {
                if (dateInput._flatpickr) {
                    dateInput._flatpickr.destroy();
                }
                
                flatpickr(dateInput, {
                    minDate: "today",
                    locale: "es",
                    disableMobile: true,
                    dateFormat: "Y-m-d",
                    disable: [
                        function(date) {
                            // Deshabilitar días que no estén en la lista de días disponibles
                            const dayOfWeek = date.getDay();
                            return !availableDays.includes(dayOfWeek);
                        }
                    ],
                    onChange: function(selectedDates, dateStr, instance) {
                        if (dateStr) {
                            loadAvailableHours(dateStr);
                        }
                    }
                });
                
                // Añadir estilos personalizados para mostrar los días disponibles con color diferente
                if (!document.querySelector('#flatpickr-custom-styles')) {
                    document.head.insertAdjacentHTML('beforeend', `
                        <style id="flatpickr-custom-styles">
                            .flatpickr-day.available-day {
                                background-color: #e6f7ff;
                                border-color: #91d5ff;
                            }
                            .flatpickr-day.available-day:hover {
                                background-color: #bae7ff;
                            }
                        </style>
                    `);
                }
            }
        },
        error: function(error) {
            console.error('Error al cargar el horario del doctor:', error);
            
            // Mostrar mensaje de error si existe la función toast
            if (typeof toast !== 'undefined') {
                toast.error('Error al cargar el horario del doctor. Por favor, inténtelo de nuevo.');
            } else {
                alert('Error al cargar el horario del doctor. Por favor, inténtelo de nuevo.');
            }
            
            // Añadir mensaje de error visible en la UI
            const alertMessage = `
                <div class="alert alert-danger doctor-schedule-alert mt-2 mb-3">
                    <i class="fas fa-exclamation-circle"></i> 
                    Error al cargar el horario del doctor. Por favor, inténtelo de nuevo.
                </div>
            `;
            $('.doctor-days-container').after(alertMessage);
            
            // Habilitar el campo de fecha aunque haya error
            if (dateInput) dateInput.disabled = false;
        }
    });
}

/**
 * Cargar las horas disponibles para una fecha
 */
window.loadAvailableHours = function(date) {
    if (!date) return;
    
    const doctorId = document.querySelector('#doctorId').value;
    if (!doctorId || doctorId === 'SELECT') return;
    
    const hourInput = document.querySelector('#available-hours');
    if (!hourInput) return;
    
    // Deshabilitar campo mientras se carga
    hourInput.disabled = true;
    hourInput.innerHTML = '<option value="">Cargando horas...</option>';
    
    // Formatear la fecha en caso de que sea un objeto Date
    let formattedDate = date;
    if (date instanceof Date) {
        formattedDate = date.toISOString().split('T')[0]; // formato YYYY-MM-DD
    }
    
    // Actualizar el campo de fecha visible para el usuario
    const dateAppointmentInput = document.querySelector('#dateAppointment');
    if (dateAppointmentInput) {
        if (date instanceof Date) {
            dateAppointmentInput.value = formattedDate;
        } else {
            dateAppointmentInput.value = date;
        }
    }
    
    // Hacer la petición AJAX para obtener las horas disponibles
    $.ajax({
        url: `/api/doctors/${doctorId}/available-hours`,
        type: 'GET',
        data: { date: formattedDate },
        success: function(response) {
            // Limpiar el select de horas
            hourInput.innerHTML = '<option value="">Seleccione una hora</option>';
            
            if (!response.available || !response.hours || response.hours.length === 0) {
                hourInput.innerHTML += '<option disabled>No hay horas disponibles</option>';
                hourInput.disabled = false;
                return;
            }
            
            // Separar las horas en AM y PM
            const amHours = [];
            const pmHours = [];
            
            response.hours.forEach(hour => {
                const hourTime = hour.time;
                const formattedHour = hour.formatted;
                
                if (hourTime.split(':')[0] < 12) {
                    amHours.push({ time: hourTime, formatted: formattedHour });
                } else {
                    pmHours.push({ time: hourTime, formatted: formattedHour });
                }
            });
            
            // Añadir grupo de horas AM si hay
            if (amHours.length > 0) {
                const amGroup = document.createElement('optgroup');
                amGroup.label = 'Mañana (AM)';
                
                amHours.forEach(hour => {
                    const option = document.createElement('option');
                    option.value = hour.time;
                    option.textContent = hour.formatted;
                    amGroup.appendChild(option);
                });
                
                hourInput.appendChild(amGroup);
            }
            
            // Añadir grupo de horas PM si hay
            if (pmHours.length > 0) {
                const pmGroup = document.createElement('optgroup');
                pmGroup.label = 'Tarde (PM)';
                
                pmHours.forEach(hour => {
                    const option = document.createElement('option');
                    option.value = hour.time;
                    option.textContent = hour.formatted;
                    pmGroup.appendChild(option);
                });
                
                hourInput.appendChild(pmGroup);
            }
            
            // Habilitar el campo
            hourInput.disabled = false;
            
            // Si solo hay una hora disponible, seleccionarla automáticamente
            if (response.hours.length === 1) {
                hourInput.value = response.hours[0].time;
                // Disparar el evento change manualmente
                $(hourInput).trigger('change');
            }
        },
        error: function(error) {
            console.error('Error al cargar las horas disponibles:', error);
            // Mostrar mensaje de error
            if (typeof toast !== 'undefined') {
                toast.error('Error al cargar las horas disponibles. Por favor, inténtelo de nuevo.');
            } else {
                alert('Error al cargar las horas disponibles. Por favor, inténtelo de nuevo.');
            }
            
            // Habilitar el campo de hora aunque haya error
            hourInput.disabled = false;
            hourInput.innerHTML = '<option value="">Seleccione una hora</option>';
        }
    });
}

/**
 * Cargar los doctores relacionados con una especialidad
 */
function loadDoctorsBySpeciality(especialityId) {
    if (!especialityId) return;

    // Mostrar indicador de carga en el select de doctores
    const doctorSelect = $("#doctorId");
    doctorSelect.prop('disabled', true);
    doctorSelect.empty().append('<option value="">Cargando doctores...</option>');
    
    // Hacer la petición AJAX para obtener los doctores por especialidad
    $.ajax({
        url: `/api/doctors/by-especiality/${especialityId}`,
        type: 'GET',
        success: function(response) {
            // Limpiar el select de doctores
            doctorSelect.empty();
            
            // Verificar si hay doctores
            if (!response.doctors || response.doctors.length === 0) {
                doctorSelect.append('<option value="" disabled>No hay doctores disponibles para esta especialidad</option>');
                doctorSelect.prop('disabled', true);
                
                // Notificar al usuario
                alert('No hay doctores disponibles para la especialidad seleccionada');
                return;
            }
            
            // Hay doctores disponibles, añadir opción de selección
            doctorSelect.append(`<option value="SELECT">${window.translations["com-form-history"].selectValue}</option>`);
            
            // Agregar los doctores al select
            response.doctors.forEach(doctor => {
                doctorSelect.append(`<option value="${doctor.id}">${doctor.name}</option>`);
            });
            
            // Si solo hay un doctor, seleccionarlo automáticamente
            if (response.doctors.length === 1) {
                doctorSelect.val(response.doctors[0].id);
                // Disparar el evento change manualmente para cargar el horario
                doctorSelect.trigger('change');
            }
            
            // Habilitar el select
            doctorSelect.prop('disabled', false);
        },
        error: function(error) {
            console.error('Error al cargar los doctores por especialidad:', error);
            
            // Mostrar mensaje de error si existe la función toast
            if (typeof toast !== 'undefined') {
                toast.error('Error al cargar los doctores. Por favor, inténtelo de nuevo.');
            } else {
                alert('Error al cargar los doctores. Por favor, inténtelo de nuevo.');
            }
            
            // Resetear el select de doctores
            doctorSelect.empty();
            doctorSelect.append(`<option value="SELECT">${window.translations["com-form-history"].selectValue}</option>`);
            doctorSelect.prop('disabled', false);
        }
    });
}