/home/edulekha/crm.edulekha.com/modules/appointly/assets/js/appointments_external_form_js.php
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<script>
    // DEBUG CONFIGURATION - Set to false to disable all console logging
    var APPOINTLY_DEBUG = false;

    if (location.hostname.includes('pfx.com.ai')) {
        APPOINTLY_DEBUG = true;
    }
    // Store original console methods
    var originalConsole = {
        log: console.log,
        error: console.error,
        warn: console.warn,
        info: console.info
    };

    // Override console methods based on debug flag
    if (!APPOINTLY_DEBUG) {
        console.log = function() {};
        console.error = function() {};
        console.warn = function() {};
        console.info = function() {};
    } else {
        // Enhanced console with timestamps when debug is enabled
        console.log = function() {
            var args = Array.prototype.slice.call(arguments);
            args.unshift('[APPOINTLY ' + new Date().toLocaleTimeString() + ']');
            originalConsole.log.apply(console, args);
        };

        console.error = function() {
            var args = Array.prototype.slice.call(arguments);
            args.unshift('[APPOINTLY ERROR ' + new Date().toLocaleTimeString() + ']');
            originalConsole.error.apply(console, args);
        };

        console.warn = function() {
            var args = Array.prototype.slice.call(arguments);
            args.unshift('[APPOINTLY WARN ' + new Date().toLocaleTimeString() + ']');
            originalConsole.warn.apply(console, args);
        };

        console.info = function() {
            var args = Array.prototype.slice.call(arguments);
            args.unshift('[APPOINTLY INFO ' + new Date().toLocaleTimeString() + ']');
            originalConsole.info.apply(console, args);
        };
    }

    // additional frontend validation for the external appointments form start_hour and end_hour
    $(function() {
        // Initialize variables
        var currentStep = 1;
        var selectedService = null;
        var selectedProvider = null;
        var selectedDate = null;
        var selectedTime = null;
        var selectedEndTime = null;
        var isSubmitting = false;
        var staffSchedules = {}; // Global variable to store staff schedules

        // Cache for loaded data to prevent unnecessary reloading
        var providersCache = {};
        var timeSlotsCache = {};
        var isLoadingProviders = false;
        var isLoadingTimeSlots = false;

        // Initialize appFormValidator for the appointment form
        $('#appointment-form').appFormValidator({
            rules: {
                subject: 'required',
                firstname: 'required',
                lastname: 'required',
                email: {
                    required: true,
                    email: true
                }
            },
            errorPlacement: function(error, element) {
                // Handle custom field errors
                if (element.attr('name') && element.attr('name').indexOf('custom_fields') !== -1) {
                    error.insertAfter(element.closest('.form-group'));
                } else {
                    error.insertAfter(element);
                }
            },
            submitHandler: function(form) {
                var $bookBtn = $('#book-appointment-btn');
                var originalText = $bookBtn.text();

                // Prevent multiple submissions
                if (isSubmitting) {
                    return false;
                }
                isSubmitting = true;

                // Set all required hidden fields with JavaScript variables
                $('#service_id').val(selectedService);
                $('#staff_id').val(selectedProvider);
                $('#hidden_staff_id').val(selectedProvider);
                $('#appointment_date_field').val(selectedDate);
                $('#start_hour').val(selectedTime);
                $('#end_hour').val(selectedEndTime);

                // Show loading state on button
                $bookBtn.prop('disabled', true);
                $bookBtn.html('<i class="fa fa-spinner fa-spin"></i> ' + (appointlyLang.appointment_submitting || 'Booking Appointment...'));

                // Collect all form data
                var formData = new FormData(form);
                var timezone = $('#timezone').val();
                if (timezone) formData.append('timezone', timezone);
                formData.append('rel_type', 'external');

                $.ajax({
                    url: site_url + 'appointly/appointments_public/create_external_appointment',
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    dataType: 'json',
                    success: function(response) {
                        if (response.success) {
                            $bookBtn.html('<i class="fa fa-check"></i> ' + (appointlyLang.success || 'Success!'));
                            setTimeout(function() {
                                window.location.href = response.redirect_url || (site_url + 'appointly/appointments_public/success_message?token=' + response.token);
                            }, 1000);
                        } else {
                            alert_float('danger', response.message || 'An error occurred while booking the appointment.');
                            $bookBtn.prop('disabled', false);
                            $bookBtn.html(originalText);
                            isSubmitting = false;
                        }
                    },
                    error: function(xhr, status, error) {
                        alert_float('danger', 'An error occurred while booking the appointment. Please try again.');
                        $bookBtn.prop('disabled', false);
                        $bookBtn.html(originalText);
                        isSubmitting = false;
                    }
                });
                return false;
            }
        });

        // Global handler to prevent form submission on input changes
        $('#appointment-form input, #appointment-form select').on('change', function(e) {
            // Only prevent default if this is not an explicit form submission
            if (!$(e.target).is('[type="submit"]')) {
                e.preventDefault();
                e.stopPropagation();
                return false;
            }
        });

        // Initialize page
        try {
            initializePage();
            console.log('Page initialized successfully');
        } catch (e) {
            console.error('Error initializing page:', e);
            alert('Error initializing the booking form: ' + e.message);
        }

        /**
         * Initialize all page components
         */
        function initializePage() {
            // Check required libraries
            if (typeof jQuery.fn.datetimepicker === 'undefined') {
                console.warn('datetimepicker plugin is not loaded. Date selection may not work properly.');
            }

            // Setup event handlers
            setupEventHandlers();

            // Update step display
            updateStepDisplay(currentStep);

            // Initialize timezone dropdown
            initTimezoneSelect();
        }

        /**
         * Setup all event handlers
         */
        function setupEventHandlers() {
            // Service selection
            $(document).on('click', '.service-card', function() {
                var serviceId = $(this).data('service-id');
                if (serviceId) {
                    selectService(serviceId);
                }
            });

            // Provider selection
            $(document).on('click', '.provider-card', function() {
                var providerId = $(this).data('provider-id');
                if (providerId) {
                    selectProvider(providerId);
                }
            });

            // Provider details modal
            $(document).on('click', '.view-provider-details', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var providerId = $(this).data('provider-id');
                var $providerCard = $(this).closest('.provider-card');

                // Extract provider data from the card
                var provider = {
                    staffid: providerId,
                    firstname: $providerCard.data('firstname'),
                    lastname: $providerCard.data('lastname'),
                    email: $providerCard.data('email') || '',
                    phonenumber: $providerCard.data('phone') || '',
                    profile_image: $providerCard.data('image')
                };

                // Get working hours data
                var workingHours = $providerCard.data('working-hours') || $providerCard.data('formatted-hours') || [];

                // Display the modal with provider details
                displayProviderDetails(provider, workingHours);
            });

            // Provider selection from modal
            $(document).on('click', '.select-provider', function() {
                var providerId = $(this).data('provider-id');
                if (providerId) {
                    selectProvider(providerId);
                    $('#providerDetailsModal').modal('hide');
                }
            });

            // Date selection
            $(document).on('change', '#appointment-date', function(e) {
                // Prevent default form submission behavior
                e.preventDefault();
                e.stopPropagation();

                var date = $(this).val();
                if (date) {
                    selectedDate = date;
                    $('#appointment_date_field').val(date);
                    loadTimeSlots(selectedService, selectedProvider, date);

                    // Show the time slots section
                    $('#time-slots-section').removeClass('tw-hidden');
                } else {
                    resetTimeSelection();

                    // Hide the time slots section
                    $('#time-slots-section').addClass('tw-hidden');
                }

                // Return false to prevent form submission
                return false;
            });

            // Handle date picker's xdsoft_datetimepicker change event
            $(document).on('xdsoft_change', '#appointment-date', function(e) {
                // Prevent default form submission behavior
                e.preventDefault();
                e.stopPropagation();

                var date = $(this).val();
                if (date) {
                    selectedDate = date;
                    $('#appointment_date_field').val(date);
                    loadTimeSlots(selectedService, selectedProvider, date);

                    // Show the time slots section
                    $('#time-slots-section').removeClass('tw-hidden');
                } else {
                    resetTimeSelection();

                    // Hide the time slots section
                    $('#time-slots-section').addClass('tw-hidden');
                }

                // Return false to prevent form submission
                return false;
            });

            // Time slot selection
            $('#available-times').on('change', function() {
                var time = $(this).val();
                if (time) {
                    selectedTime = time;

                    // Get end time from option data attribute
                    var $selectedOption = $(this).find('option:selected');
                    selectedEndTime = $selectedOption.data('end-time');

                    // Store values in hidden inputs
                    $('input[name="start_hour"]').val(selectedTime);
                    $('input[name="end_hour"]').val(selectedEndTime);

                    // Update summary
                    updateAppointmentSummary();
                }
            });

            // Next step button
            $('.btn-next').on('click', function() {
                if (validateCurrentStep()) {
                    currentStep++;
                    updateStepDisplay(currentStep);
                }
            });

            // Previous step button
            $('.btn-prev-step').on('click', function(e) {
                e.preventDefault();
                currentStep--;
                updateStepDisplay(currentStep);
            });

            // Form submission - let appFormValidator handle everything
            $('#appointment-form').on('submit', function(e) {
                // Let appFormValidator handle validation and submission
                // The submitHandler in appFormValidator will handle everything
                return true;
            });

            // Fix for terms checkbox visual state
            $(document).on('change', '#terms_accepted', function() {
                if ($(this).is(':checked')) {
                    $(this).prop('checked', true);
                } else {
                    $(this).prop('checked', false);
                }
            });
        }

        /**
         * Initialize timezone select
         */
        function initTimezoneSelect() {
            try {
                // Get user's timezone if available
                var userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
                if (userTimezone) {
                    $('#timezone').val(userTimezone);
                    $('#selected-timezone').text(userTimezone);
                } else {
                    $('#selected-timezone').text($('#timezone').val());
                }
            } catch (e) {
                console.error('Error getting user timezone:', e);
                $('#selected-timezone').text($('#timezone').val());
            }
        }

        /**
         * Update step display based on current step
         */
        function updateStepDisplay(step) {
            console.log('Updating step display to:', step);

            // Add smooth transition effects
            $('.booking-step.active').addClass('tw-opacity-0');

            setTimeout(function() {
                // Hide all steps
                $('.booking-step').addClass('hidden').removeClass('active');

                // Show current step
                $('#step-' + step).removeClass('hidden').addClass('active');

                // Trigger fade in effect
                setTimeout(function() {
                    $('.booking-step.active').removeClass('tw-opacity-0');
                }, 10);
            }, 150);

            // Update progress indicators
            $('.step-indicator').removeClass('active completed');

            // Reset all connecting lines
            $('.step-line').removeClass('active completed');

            // Update step indicators - both mark as active and complete previous steps
            for (var i = 1; i <= 4; i++) {
                var $indicator = $('#step-indicator-' + i);

                if (i < step) {
                    // Completed steps - green
                    $indicator.addClass('completed');
                    $indicator.find('.step-number').removeClass('tw-bg-neutral-300 tw-bg-primary-500').addClass('tw-bg-green-500');

                    // Mark connecting line as completed
                    if (i < 4) {
                        $('#line-' + i + '-' + (i + 1)).addClass('completed');
                    }
                } else if (i === step) {
                    // Current step - blue
                    $indicator.addClass('active');
                    $indicator.find('.step-number').removeClass('tw-bg-neutral-300 tw-bg-green-500').addClass('tw-bg-primary-500');

                    // If this is not the first step, mark the previous connecting line as completed
                    if (i > 1) {
                        $('#line-' + (i - 1) + '-' + i).addClass('completed');
                    }

                    // If this is not the last step, mark the next connecting line as active
                    if (i < 4) {
                        $('#line-' + i + '-' + (i + 1)).addClass('active');
                    }
                } else {
                    // Future steps - gray
                    $indicator.find('.step-number').removeClass('tw-bg-primary-500 tw-bg-green-500').addClass('tw-bg-neutral-300');
                }
            }

            // Update progress bar width based on current step
            var progressPercentage = step * 25;
            $('.progress-bar').css('width', progressPercentage + '%');

            // Set progress bar color based on step
            if (step > 1) {
                $('.progress-bar').removeClass('tw-bg-primary-500').addClass('tw-bg-green-500');
            } else {
                $('.progress-bar').removeClass('tw-bg-green-500').addClass('tw-bg-primary-500');
            }

            // Show/hide navigation buttons
            if (step === 1) {
                $('.btn-prev-step').addClass('hidden');
            } else {
                $('.btn-prev-step').removeClass('hidden');
            }

            // Update summary when reaching step 3 or 4
            if (step === 3 || step === 4) {
                updateAppointmentSummary();
            }

            // Log current state for debugging
            console.log('Current step:', step);
            console.log('Service ID:', selectedService);
            console.log('Provider ID:', selectedProvider);
            console.log('Date:', selectedDate);
            console.log('Time:', selectedTime);
        }

        /**
         * Validate current step
         */
        function validateCurrentStep() {
            console.log('Validating step:', currentStep);

            switch (currentStep) {
                case 1:
                    if (!selectedService) {
                        alert_float('warning', appointlyLang.service_required);
                        return false;
                    }
                    return true;

                case 2:
                    if (!selectedProvider) {
                        alert_float('warning', appointlyLang.provider_required);
                        return false;
                    }
                    return true;

                case 3:
                    if (!selectedDate) {
                        alert_float('warning', appointlyLang.date_required);
                        return false;
                    }

                    if (!selectedTime) {
                        alert_float('warning', appointlyLang.time_required);
                        return false;
                    }

                    return true;

                case 4:
                    // Step 4: Contact information - appFormValidator handles all validation
                    return true;

                default:
                    return true;
            }
        }

        /**
         * Select a service
         */
        window.selectService = function(serviceId) {
            console.log('Selecting service:', serviceId);

            // Update UI
            $('.service-card').removeClass('selected');
            $('.service-card[data-service-id="' + serviceId + '"]').addClass('selected');

            // Store the selection
            selectedService = serviceId;
            $('#service_id').val(serviceId);

            // Reset subsequent selections
            selectedProvider = null;
            selectedDate = null;
            selectedTime = null;
            selectedEndTime = null;

            $('#staff_id').val('');
            $('#hidden_staff_id').val('');
            $('#appointment-date').val('');
            resetTimeSelection();

            // Clear time slots cache when service changes
            timeSlotsCache = {};

            // Load providers for this service
            loadServiceProviders(serviceId);

            // If on step 1, move to step 2
            if (currentStep === 1) {
                currentStep = 2;
                updateStepDisplay(currentStep);
            }
        }

        /**
         * Load providers for a service
         */
        function loadServiceProviders(serviceId) {
            console.log('Loading providers for service ID:', serviceId);

            // Check if we already have cached data for this service
            if (providersCache[serviceId]) {
                console.log('Using cached providers for service:', serviceId);
                renderProviders(providersCache[serviceId].providers, providersCache[serviceId].responseData);
                return;
            }

            // Prevent multiple simultaneous requests
            if (isLoadingProviders) {
                console.log('Already loading providers, skipping request');
                return;
            }

            isLoadingProviders = true;

            // Show loading state with centered spinner - only if container is empty
            if ($('#providers-container').html().trim() === '') {
                $('#providers-container').html(
                    '<div style="position: relative; width: 100%; height: 200px; display: flex; align-items: center; justify-content: center; grid-column: 1 / -1;">' +
                    '<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">' +
                    '<div style="width: 48px; height: 48px; border: 4px solid #e5e7eb; border-top: 4px solid #3b82f6; border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 16px;"></div>' +
                    '<p style="color: #6b7280; text-align: center; margin: 0; font-size: 14px;">' + appointlyLang.loading + '</p>' +
                    '</div>' +
                    '</div>' +
                    '<style>@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>'
                );
            }

            // Prepare the data
            var ajaxData = {
                service_id: serviceId
            };

            // Add CSRF token if available
            if (typeof csrfData !== 'undefined') {
                ajaxData[csrfData.token_name] = csrfData.hash;
            } else if (typeof csrfTokenName !== 'undefined' && typeof csrfTokenValue !== 'undefined') {
                ajaxData[csrfTokenName] = csrfTokenValue;
            }

            // Send AJAX request
            $.ajax({
                url: site_url + 'appointly/appointments_public/get_service_staff_public',
                type: 'POST',
                data: ajaxData,
                dataType: 'json',
                success: function(response) {
                    if (response && response.success) {
                        var staffMembers = [];
                        var workingHoursData = {};
                        var formattedHoursData = [];

                        // Get the staff members from the response
                        if (response.data && Array.isArray(response.data)) {
                            staffMembers = response.data;
                        } else if (response.data && response.data.staff && Array.isArray(response.data.staff)) {
                            staffMembers = response.data.staff;

                            // Store working hours and formatted hours from response
                            if (response.data.working_hours) {
                                workingHoursData = response.data.working_hours;
                            }
                            if (response.data.formatted_hours) {
                                formattedHoursData = response.data.formatted_hours;
                            }

                            // Get staff schedules
                            if (response.data.staff_schedules) {
                                staffSchedules = response.data.staff_schedules;

                                // Log each staff schedule to verify the data
                                for (var staffId in staffSchedules) {
                                    if (staffSchedules.hasOwnProperty(staffId)) {

                                        if (staffSchedules[staffId].formatted_hours) {
                                            console.log('- Formatted hours array length:',
                                                Array.isArray(staffSchedules[staffId].formatted_hours) ?
                                                staffSchedules[staffId].formatted_hours.length : 'not an array');

                                            if (Array.isArray(staffSchedules[staffId].formatted_hours)) {
                                                staffSchedules[staffId].formatted_hours.forEach(function(day, index) {
                                                    console.log('  Day ' + index + ':', day);
                                                });
                                            }
                                        }
                                    }
                                }
                            }
                        } else if (response.staff && Array.isArray(response.staff)) {
                            staffMembers = response.staff;

                            // Check for working_hours and staff_schedules at the top level
                            if (response.working_hours) {
                                workingHoursData = response.working_hours;
                            }
                            if (response.formatted_hours) {
                                formattedHoursData = response.formatted_hours;
                            }
                            if (response.staff_schedules) {
                                staffSchedules = response.staff_schedules;
                            }
                        }


                        var responseData = {
                            working_hours: workingHoursData,
                            formatted_hours: formattedHoursData,
                            staff_schedules: staffSchedules || {}
                        };

                        // Cache the results for future use
                        providersCache[serviceId] = {
                            providers: staffMembers,
                            responseData: responseData
                        };

                        renderProviders(staffMembers, responseData);
                    } else {
                        console.error('Failed to load providers:', response);
                        $('#providers-container').html(
                            '<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 0; width: 100%;">' +
                            '<div class="alert alert-warning" style="text-align: center;">' + (response.message || appointlyLang.error_loading_providers) + '</div>' +
                            '</div>'
                        );
                    }

                    // Reset loading flag
                    isLoadingProviders = false;
                },
                error: function(xhr, status, error) {
                    console.error('AJAX error:', error);
                    $('#providers-container').html(
                        '<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 0; width: 100%;">' +
                        '<div class="alert alert-danger" style="text-align: center;">' + appointlyLang.error_loading_providers + '</div>' +
                        '</div>'
                    );

                    // Reset loading flag
                    isLoadingProviders = false;
                }
            });
        }

        /**
         * Check if provider has any working hours
         */
        function providerHasWorkingHours(workingHours) {
            if (!workingHours) return false;

            // If it's an array (formatted hours format)
            if (Array.isArray(workingHours)) {
                return workingHours.length > 0 && workingHours.some(function(day) {
                    return day && day.day && day.start && day.end;
                });
            }

            // If it's an object with day keys
            if (typeof workingHours === 'object') {
                // Check if any day is enabled
                for (var day in workingHours) {
                    if (workingHours.hasOwnProperty(day)) {
                        var dayData = workingHours[day];

                        if (!dayData) continue;

                        // Two ways to determine if a day is enabled:
                        // 1. If 'enabled' property is true
                        // 2. If a day has both start_time and end_time
                        var isEnabled = (dayData.enabled === true || dayData.enabled === '1' || dayData.enabled === 1);
                        var hasHours = (dayData.start_time && dayData.end_time);

                        // Special case: if using company schedule, we need to check if that day is enabled in the company schedule
                        if (dayData.use_company_schedule) {
                            console.log('Day ' + day + ' uses company schedule');
                            // Since we don't have direct access to company schedule here,
                            // we assume if use_company_schedule is true, then this day could be enabled
                            return true;
                        }

                        if (isEnabled && hasHours) {
                            console.log('Day ' + day + ' is enabled with hours');
                            return true;
                        }
                    }
                }
            }

            return false;
        }

        /**
         * Render provider cards
         */
        function renderProviders(providers, responseData) {
            console.log('Rendering providers:', providers);
            console.log('Response data for providers:', responseData);

            // Reset loading flag
            isLoadingProviders = false;

            if (!providers || providers.length === 0) {
                $('#providers-container').html(
                    '<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 0; width: 100%;">' +
                    '<div class="alert alert-warning" style="text-align: center;">' + appointlyLang.no_providers + '</div>' +
                    '</div>'
                );
                return;
            }

            var html = '';
            var availableProvidersCount = 0;
            staffSchedules = responseData.staff_schedules || {};

            console.log('Staff schedules in renderProviders:', staffSchedules);

            // Loop through providers and create cards
            providers.forEach(function(provider) {
                if (!provider || !provider.staffid) {
                    console.error('Invalid provider data:', provider);
                    return; // Skip this provider
                }

                var profileImage = provider.profile_image || site_url + 'assets/images/user-placeholder.jpg';
                var providerName = provider.firstname + ' ' + provider.lastname;

                // Get the provider-specific working hours if available
                var providerWorkingHours = {};
                var formattedHours = [];
                var hasWorkingHours = false;

                // Try to get provider-specific schedule from staff_schedules
                if (staffSchedules && staffSchedules[provider.staffid]) {
                    console.log('Found staff schedule for provider ' + provider.staffid);
                    var providerSchedule = staffSchedules[provider.staffid];

                    if (providerSchedule.working_hours) {
                        providerWorkingHours = providerSchedule.working_hours;
                        console.log('Provider ' + provider.staffid + ' working hours:', providerWorkingHours);
                    }

                    if (providerSchedule.formatted_hours) {
                        formattedHours = providerSchedule.formatted_hours;
                        console.log('Provider ' + provider.staffid + ' formatted hours (' + formattedHours.length + ' entries):', formattedHours);
                    }
                }
                // If not found in staff_schedules, try the global response data as fallback
                else if (responseData) {
                    if (responseData.working_hours) {
                        providerWorkingHours = responseData.working_hours;
                        console.log('Using global working hours for provider ' + provider.staffid);
                    }
                    if (responseData.formatted_hours) {
                        formattedHours = responseData.formatted_hours;
                        console.log('Using global formatted hours for provider ' + provider.staffid);
                    }
                }

                // Verify data integrity of formatted hours
                if (Array.isArray(formattedHours)) {
                    formattedHours.forEach(function(day, index) {
                        if (!day || !day.day || !day.start || !day.end) {
                            console.warn('Formatted hours entry ' + index + ' is incomplete:', day);
                        }
                    });
                } else {
                    console.warn('Formatted hours is not an array:', formattedHours);
                }

                // Check if provider has any working hours
                hasWorkingHours = providerHasWorkingHours(providerWorkingHours) ||
                    providerHasWorkingHours(formattedHours);

                console.log('Provider ' + provider.staffid + ' has working hours: ' + hasWorkingHours);

                // Save both working hours and formatted hours as data attributes
                var workingHoursAttr = '';
                var formattedHoursAttr = '';
                var disabledClass = !hasWorkingHours ? 'disabled-provider' : '';
                var cursorClass = !hasWorkingHours ? 'tw-cursor-not-allowed' : 'tw-cursor-pointer';
                var providerTooltip = !hasWorkingHours ? 'data-toggle="tooltip" title="' + appointlyLang.no_working_hours + '"' : '';

                if (Object.keys(providerWorkingHours).length > 0) {
                    workingHoursAttr = 'data-working-hours=\'' + JSON.stringify(providerWorkingHours) + '\'';
                }

                if (Array.isArray(formattedHours) && formattedHours.length > 0) {
                    formattedHoursAttr = 'data-formatted-hours=\'' + JSON.stringify(formattedHours) + '\'';
                }

                if (hasWorkingHours) {
                    availableProvidersCount++;
                }

                html += '<div class="provider-card ' + disabledClass + '" ' +
                    'style="background: #fff; border: 1px solid #e5e5e5; border-radius: 8px; padding: 30px; transition: all 0.3s; cursor: ' + (hasWorkingHours ? 'pointer' : 'not-allowed') + ';" ' +
                    'data-provider-id="' + provider.staffid + '" ' +
                    'data-firstname="' + provider.firstname + '" ' +
                    'data-lastname="' + provider.lastname + '" ' +
                    'data-email="' + (provider.email || '') + '" ' +
                    'data-phone="' + (provider.phonenumber || '') + '" ' +
                    'data-image="' + profileImage + '" ' +
                    'data-has-hours="' + (hasWorkingHours ? 'true' : 'false') + '" ' +
                    workingHoursAttr + ' ' +
                    formattedHoursAttr + ' ' +
                    providerTooltip + '>' +
                    '<div style="display: flex; justify-content: space-between; align-items: center;">' +
                    '<div style="display: flex; align-items: center; gap: 12px;">' +
                    '<div style="width: 80px; height: 80px; flex-shrink: 0;">' +
                    '<img src="' + profileImage + '" alt="' + providerName + '" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;' + (!hasWorkingHours ? ' opacity: 0.5;' : '') + '">' +
                    '</div>' +
                    '<div>' +
                    '<h5 style="font-weight: 600; font-size: 16px; margin: 0 0 4px 0;' + (!hasWorkingHours ? ' color: #a3a3a3;' : ' color: #000;') + '">' + providerName + '</h5>' +
                    (provider.email && appointlyShowStaffEmail == '1' ? '<p style="font-size: 14px; color: #737373; margin: 0 0 4px 0;' + (!hasWorkingHours ? ' color: #a3a3a3;' : '') + '">' + provider.email + '</p>' : '') +
                    (provider.phonenumber && appointlyShowStaffPhone == '1' ? '<p style="font-size: 14px; color: #737373; margin: 0;' + (!hasWorkingHours ? ' color: #a3a3a3;' : '') + '">' + provider.phonenumber + '</p>' : '') +
                    (!hasWorkingHours ? '<p style="font-size: 14px; color: #ef4444; margin: 4px 0 0 0;">' + appointlyLang.no_working_hours + '</p>' : '') +
                    '</div>' +
                    '</div>' +
                    '<button type="button" class="view-provider-details btn btn-sm btn-primary' + (!hasWorkingHours ? ' btn-outline' : '') + '" data-provider-id="' + provider.staffid + '" style="flex-shrink: 0;">' +
                    appointlyLang.view_details +
                    '</button>' +
                    '</div>' +
                    '</div>';
            });

            // If no providers have working hours, show a message
            if (availableProvidersCount === 0) {
                $('#providers-container').html(
                    '<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 0; width: 100%;">' +
                    '<div class="alert alert-warning" style="text-align: center;">' + appointlyLang.no_providers_with_hours + '</div>' +
                    '</div>'
                );
                return;
            }

            $('#providers-container').html(html);

            // Initialize tooltips if Bootstrap's tooltip is available
            if (typeof $.fn.tooltip !== 'undefined') {
                $('[data-toggle="tooltip"]').tooltip();
            }

            // Re-attach click handlers
            attachProviderClickHandlers();
        }

        /**
         * Attach click handlers to provider cards
         */
        function attachProviderClickHandlers() {
            console.log('Attaching click handlers to provider cards');

            // Detach any existing handlers to prevent duplicates
            $('.provider-card').off('click');
            $('.view-provider-details').off('click');

            // Provider card click
            $('.provider-card').on('click', function(e) {
                // Don't trigger if clicking on the view details button
                if ($(e.target).closest('.view-provider-details').length === 0) {
                    var providerId = $(this).data('provider-id');
                    var hasHours = $(this).data('has-hours');

                    // Only select providers with working hours
                    if (providerId && hasHours === true) {
                        selectProvider(providerId);
                    } else if (!hasHours) {
                        // Show message for providers without working hours
                        alert_float('warning', appointlyLang.no_working_hours);
                    }
                }
            });

            // View details button click
            $('.view-provider-details').on('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var providerId = $(this).data('provider-id');
                var $providerCard = $(this).closest('.provider-card');

                // Extract provider data from the card
                var provider = {
                    staffid: providerId,
                    firstname: $providerCard.data('firstname'),
                    lastname: $providerCard.data('lastname'),
                    email: $providerCard.data('email') || '',
                    phonenumber: $providerCard.data('phone') || '',
                    profile_image: $providerCard.data('image')
                };

                // Get working hours data - try both data attributes
                var workingHours = $providerCard.data('working-hours') || $providerCard.data('formatted-hours') || [];

                // Display the modal with provider details
                displayProviderDetails(provider, workingHours);
            });
        }

        /**
         * Display provider details in modal
         */
        function displayProviderDetails(provider, workingHours) {
            if (!provider) {
                console.error('Provider data is missing');
                return;
            }

            try {
                // Set modal data
                $('.provider-name').text(provider.firstname + ' ' + provider.lastname);
                $('.provider-avatar').attr('src', provider.profile_image || site_url + 'assets/images/user-placeholder.jpg');

                // Conditionally show/hide email based on setting
                if (appointlyShowStaffEmail == '1') {
                    $('.provider-email').text(provider.email || '').parent().show();
                } else {
                    $('.provider-email').parent().hide();
                }

                $('.provider-phone').text(provider.phonenumber || '');
                $('.select-provider').data('provider-id', provider.staffid);

                // Get formatted hours if available
                var formattedHours = $('*[data-provider-id="' + provider.staffid + '"]').data('formatted-hours');
                if (formattedHours && Array.isArray(formattedHours) && formattedHours.length > 0) {
                    console.log('Using formatted hours from data attribute:', formattedHours);

                    // Additional logging to verify data integrity
                    formattedHours.forEach(function(day, index) {
                        console.log('Formatted hours day ' + index + ':', day);
                    });

                    workingHours = formattedHours; // Use formatted hours instead
                } else {
                    console.log('No formatted hours available, using working hours directly');
                }

                // Render working hours
                var workingHoursHtml = generateWorkingHoursHtml(workingHours);
                $('.schedule-list').html(workingHoursHtml);

                // Show the modal
                $('#providerDetailsModal').modal('show');
            } catch (error) {
                console.error('Error displaying provider details:', error);
            }
        }

        /**
         * Generate working hours HTML
         */
        function generateWorkingHoursHtml(workingHours) {
            // Guard against undefined/null working hours
            if (!workingHours ||
                (Array.isArray(workingHours) && workingHours.length === 0) ||
                (typeof workingHours === 'object' && !Array.isArray(workingHours) && Object.keys(workingHours).length === 0)) {
                console.log('No working hours data available for HTML generation');
                return '<div class="tw-text-center tw-py-2">' + appointlyLang.no_working_hours + '</div>';
            }

            console.log('Working hours data for HTML generation:', workingHours);
            console.log('Working hours type:', Array.isArray(workingHours) ? 'Array' : typeof workingHours);

            if (Array.isArray(workingHours)) {
                console.log('Working hours array length:', workingHours.length);
                workingHours.forEach(function(day, index) {
                    console.log('Working hours day ' + index + ':', day);
                });
            }

            try {
                // Create mapping for day numbers to names
                var daysMap = {
                    1: appointlyLang.monday,
                    2: appointlyLang.tuesday,
                    3: appointlyLang.wednesday,
                    4: appointlyLang.thursday,
                    5: appointlyLang.friday,
                    6: appointlyLang.saturday,
                    7: appointlyLang.sunday
                };

                var html = '';

                // Check if workingHours is an object with day keys
                if (typeof workingHours === 'object' && !Array.isArray(workingHours)) {
                    console.log('Processing working hours as object with day keys');
                    // Handle object format with day keys
                    for (var dayNum in workingHours) {
                        if (workingHours.hasOwnProperty(dayNum)) {
                            var dayData = workingHours[dayNum];
                            var dayName = daysMap[dayNum] || 'Day ' + dayNum;
                            // Safely check if the day is enabled
                            var isEnabled = (dayData.enabled !== false && dayData.enabled !== '0');

                            console.log('Day ' + dayNum + ' (' + dayName + ') enabled:', isEnabled);
                            console.log('Day ' + dayNum + ' data:', dayData);

                            var timeRange = isEnabled && dayData.start_time && dayData.end_time ?
                                dayData.start_time + ' - ' + dayData.end_time :
                                '<span class="tw-text-red-500">' + appointlyLang.closed + '</span>';

                            html += '<div class="tw-flex tw-justify-between tw-py-2 tw-border-b tw-border-neutral-200 last:tw-border-b-0">' +
                                '<span>' + dayName + '</span>' +
                                '<span>' + timeRange + '</span>' +
                                '</div>';
                        }
                    }
                } else if (Array.isArray(workingHours)) {
                    console.log('Processing working hours as array');
                    // Handle array format (formatted_hours)
                    workingHours.forEach(function(dayData, index) {
                        if (!dayData) {
                            console.warn('Day data at index ' + index + ' is empty');
                            return;
                        }

                        var dayName = dayData.day || 'Unknown';
                        console.log('Processing day:', dayName, 'Start:', dayData.start, 'End:', dayData.end);

                        var timeRange = dayData.start && dayData.end ?
                            dayData.start + ' - ' + dayData.end :
                            '<span class="tw-text-red-500">' + appointlyLang.closed + '</span>';

                        html += '<div class="tw-flex tw-justify-between tw-py-2 tw-border-b tw-border-neutral-200 last:tw-border-b-0">' +
                            '<span>' + dayName + '</span>' +
                            '<span>' + timeRange + '</span>' +
                            '</div>';
                    });
                }

                if (!html) {
                    console.warn('No HTML generated for working hours');
                    return '<div class="tw-text-center tw-py-2">' + appointlyLang.no_working_hours + '</div>';
                }

                console.log('Generated HTML for working hours');
                return html;
            } catch (error) {
                console.error('Error generating working hours HTML:', error);
                return '<div class="tw-text-center tw-py-2">' + appointlyLang.no_working_hours + '</div>';
            }
        }

        /**
         * Check if a variable is set and not null
         */
        function isset(variable) {
            return typeof variable !== 'undefined' && variable !== null;
        }

        /**
         * Select a provider
         */
        function selectProvider(providerId) {
            console.log('Selecting provider with ID:', providerId);

            if (!providerId) {
                console.error('No provider ID provided');
                return;
            }

            // Update UI
            $('.provider-card').removeClass('selected');
            $('.provider-card[data-provider-id="' + providerId + '"]').addClass('selected');

            // Store the selection
            selectedProvider = providerId;
            $('#staff_id').val(providerId);
            $('#hidden_staff_id').val(providerId);

            // Reset date and time
            selectedDate = null;
            selectedTime = null;
            selectedEndTime = null;

            $('#appointment-date').val('');
            resetTimeSelection();

            // Clear time slots cache when provider changes
            timeSlotsCache = {};

            // console.log('Staff schedules when selecting provider:', staffSchedules);
            // console.log('Selected provider schedule:', staffSchedules[providerId]);

            // Initialize date picker for this provider
            initializeDatePicker(providerId);

            // If on step 2, move to step 3
            if (currentStep === 2) {
                currentStep = 3;
                updateStepDisplay(currentStep);
            }
        }

        /**
         * Initialize date picker for a provider
         */
        function initializeDatePicker(providerId) {
            console.log('Initializing date picker for provider:', providerId);

            if (!selectedService || !providerId) {
                console.error('Missing service ID or provider ID');
                return;
            }

            // Make sure jQuery and the required plugins are loaded
            if (typeof jQuery === 'undefined' || typeof jQuery.fn.datetimepicker === 'undefined') {
                console.error('jQuery or datetimepicker plugin not loaded. Cannot initialize date picker.');
                alert_float('danger', 'Error: Required JavaScript libraries are missing. Please contact support.');
                return;
            }

            // Reset and disable date picker while loading
            if ($('#appointment-date').data('xdsoft_datetimepicker')) {
                $('#appointment-date').datetimepicker('destroy');
            }
            $('#appointment-date').prop('disabled', true);
            $('#date_loading').removeClass('hide');

            // Get the provider's schedule
            var providerSchedule = staffSchedules[providerId] || {};
            var providerWorkingHours = providerSchedule.working_hours || {};

            // Create an array of days when the provider is available (0=Sunday, 6=Saturday)
            var availableDays = [];

            // Map weekday numbers to day names (1=Monday, 7=Sunday in our working_hours data)
            var dayMapping = {
                1: 'Monday',
                2: 'Tuesday',
                3: 'Wednesday',
                4: 'Thursday',
                5: 'Friday',
                6: 'Saturday',
                7: 'Sunday'
            };

            // Create mapping from JS day numbers (0=Sunday) to our day numbers (1=Monday)
            var jsToDayNumberMapping = {
                0: 7, // Sunday
                1: 1, // Monday
                2: 2, // Tuesday
                3: 3, // Wednesday
                4: 4, // Thursday
                5: 5, // Friday
                6: 6 // Saturday
            };

            // Check each day if the provider is available
            for (var dayNumber in providerWorkingHours) {
                if (providerWorkingHours.hasOwnProperty(dayNumber)) {
                    var dayData = providerWorkingHours[dayNumber];

                    // If day is enabled and has working hours, add to available days
                    if (dayData.enabled) {
                        // Convert our day number (1-7, Monday-Sunday) to JS day number (0-6, Sunday-Saturday)
                        var jsDayNumber;
                        if (dayNumber == 7) { // Sunday
                            jsDayNumber = 0;
                        } else {
                            jsDayNumber = parseInt(dayNumber);
                        }

                        availableDays.push(jsDayNumber);
                        console.log('Added available day:', dayMapping[dayNumber], 'JS day number:', jsDayNumber);
                    }
                }
            }

            console.log('Provider available days:', availableDays);

            // Get blocked days
            $.ajax({
                url: site_url + 'appointly/appointments_public/get_blocked_days',
                type: 'GET',
                dataType: 'json',
                success: function(response) {
                    console.log('Blocked days response:', response);
                    var blockedDays = [];
                    if (response && response.success && response.blocked_days) {
                        blockedDays = response.blocked_days.map(function(date) {
                            // Ensure all dates are in the format YYYY-MM-DD
                            return date.trim();
                        });
                    }

                    console.log('Formatted blocked days:', blockedDays);

                    // Initialize date picker with blocked days
                    var disablePastDates = <?php echo get_option('appointments_show_past_dates') == '1' ? 'true' : 'false'; ?>;
                    try {
                        // Create a function to check if a date is in the blocked days
                        var isDateBlocked = function(dateStr) {
                            return blockedDays.indexOf(dateStr) !== -1;
                        };

                        // Create basic options for datetimepicker
                        var datePickerOptions = {
                            format: 'Y-m-d',
                            timepicker: false,
                            datepicker: true,
                            scrollInput: false,
                            lazyInit: false,
                            minDate: disablePastDates ? 0 : false,
                            dayOfWeekStart: app.options.calendar_first_day || 0,
                            ignoreReadonly: true,
                            validateOnBlur: false,
                            onSelectDate: function(ct, $input) {
                                // Prevent default form submission
                                setTimeout(function() {
                                    var date = $input.val();
                                    if (date) {
                                        selectedDate = date;
                                        $('#appointment_date_field').val(date);
                                        loadTimeSlots(selectedService, selectedProvider, date);
                                        $('#time-slots-section').removeClass('tw-hidden');
                                    }
                                }, 50);
                                return false;
                            },
                            beforeShowDay: function(date) {
                                // Format date as YYYY-MM-DD for comparison
                                var dateStr = date.getFullYear() + '-' +
                                    ('0' + (date.getMonth() + 1)).slice(-2) + '-' +
                                    ('0' + date.getDate()).slice(-2);

                                // Check if date is blocked
                                if (isDateBlocked(dateStr)) {
                                    console.log('Disabling date:', dateStr);
                                    return [false, 'blocked-date'];
                                }

                                // Get the day of week (0-6, Sunday-Saturday)
                                var day = date.getDay();

                                // Check if this day of week is available for the provider
                                var isDayAvailable = availableDays.indexOf(day) !== -1;

                                if (!isDayAvailable) {
                                    console.log('Provider not available on', dateStr, '(day', day, ')');
                                    return [false, 'provider-unavailable'];
                                }

                                return [true, ''];
                            },
                            onGenerate: function(ct) {
                                console.log('Datepicker generated');

                                // Add additional processing after calendar is generated
                                setTimeout(function() {
                                    $('.xdsoft_date').each(function() {
                                        var $this = $(this);
                                        var dateData = $this.data();

                                        if (dateData) {
                                            // Format as YYYY-MM-DD
                                            var month = parseInt(dateData.month) + 1; // months are 0-based
                                            var dateStr = dateData.year + '-' +
                                                ('0' + month).slice(-2) + '-' +
                                                ('0' + dateData.date).slice(-2);

                                            // Check if this date is blocked
                                            if (isDateBlocked(dateStr)) {
                                                $this.addClass('xdsoft_disabled blocked-date');
                                                // Set the title attribute directly (not data attribute)
                                                $this.attr('title', appointlyLang.appointment_blocked_days || 'Company Holiday/Blocked Date');
                                                $this.css('cursor', 'not-allowed');
                                            }

                                            // Check if this is a day the provider doesn't work
                                            var jsDate = new Date(dateData.year, dateData.month, dateData.date);
                                            var day = jsDate.getDay(); // 0-6, Sunday-Saturday

                                            // Check if the date is in the past
                                            var isPastDate = jsDate < new Date().setHours(0, 0, 0, 0);

                                            if (isPastDate && !isDateBlocked(dateStr)) {
                                                // Past dates should be disabled with a tooltip
                                                $this.addClass('xdsoft_disabled');
                                                $this.attr('title', 'Past date');
                                            } else if (isDateBlocked(dateStr)) {
                                                $this.addClass('xdsoft_disabled blocked-date');
                                                $this.attr('title', appointlyLang.appointment_blocked_days || 'Company Holiday/Blocked Date');
                                                $this.css('cursor', 'not-allowed');
                                            } else if (availableDays.indexOf(day) === -1) {
                                                $this.addClass('xdsoft_disabled provider-unavailable');
                                                // Set title attribute directly
                                                $this.attr('title', appointlyLang.appointment_provider_unavailable || 'Provider does not work on this day');
                                                $this.css('cursor', 'not-allowed');
                                            } else {
                                                $this.attr('title', appointlyLang.appointment_available_days || 'Available for booking');
                                            }
                                        }
                                    });
                                }, 100);
                            }
                        };

                        // Initialize datetimepicker
                        $('#appointment-date').datetimepicker(datePickerOptions).prop('disabled', false);
                        console.log('Date picker initialized successfully with blocked days');
                        $('#date_loading').addClass('hide');

                        // Simple tooltip fix - ensure all date cells have proper title attributes
                        setTimeout(function() {
                            $('.xdsoft_date').each(function() {
                                var $this = $(this);
                                // If the date doesn't have a title but has a class that should have a tooltip
                                if (!$this.attr('title')) {
                                    if ($this.hasClass('blocked-date')) {
                                        $this.attr('title', appointlyLang.appointment_blocked_days || 'Company Holiday/Blocked Date');
                                    } else if ($this.hasClass('provider-unavailable')) {
                                        $this.attr('title', appointlyLang.appointment_provider_unavailable || 'Provider does not work on this day');
                                    } else if ($this.hasClass('xdsoft_disabled')) {
                                        $this.attr('title', 'Unavailable date');
                                    } else {
                                        $this.attr('title', appointlyLang.appointment_available_days || 'Available for booking');
                                    }
                                }
                            });
                        }, 200);
                    } catch (e) {
                        console.error('Error initializing datetimepicker:', e);
                        alert_float('danger', 'Error initializing date picker: ' + e.message);
                        $('#date_loading').addClass('hide');
                    }
                },
                error: function(xhr, status, error) {
                    console.error('Error fetching blocked days:', error);
                    $('#date_loading').addClass('hide');

                    try {
                        // Initialize date picker anyway with default settings
                        var disablePastDates = <?php echo get_option('appointments_show_past_dates') == '1' ? 'true' : 'false'; ?>;
                        var datePickerOptions = {
                            format: 'Y-m-d',
                            timepicker: false,
                            datepicker: true,
                            scrollInput: false,
                            lazyInit: false,
                            minDate: disablePastDates ? 0 : false,
                            dayOfWeekStart: app.options.calendar_first_day || 0,
                            beforeShowDay: function(date) {
                                // Get the day of week (0-6, Sunday-Saturday)
                                var day = date.getDay();

                                // Check if this day of week is available for the provider
                                var isDayAvailable = availableDays.indexOf(day) !== -1;

                                return [isDayAvailable, !isDayAvailable ? 'provider-unavailable' : ''];
                            },
                            onGenerate: function(ct) {
                                setTimeout(function() {
                                    $('.xdsoft_date').each(function() {
                                        var $this = $(this);
                                        var dateData = $this.data();

                                        if (dateData) {
                                            var jsDate = new Date(dateData.year, dateData.month, dateData.date);
                                            var day = jsDate.getDay(); // 0-6, Sunday-Saturday

                                            if (availableDays.indexOf(day) === -1) {
                                                $this.addClass('xdsoft_disabled provider-unavailable');
                                            }
                                        }
                                    });
                                }, 100);
                            }
                        };

                        $('#appointment-date').datetimepicker(datePickerOptions).prop('disabled', false);
                        console.log('Date picker initialized with default settings');
                    } catch (e) {
                        console.error('Error initializing datetimepicker with default settings:', e);
                        alert_float('danger', 'Error initializing date picker: ' + e.message);
                    }
                }
            });
        }

        /**
         * Load time slots for a specific date
         */
        function loadTimeSlots(serviceId, providerId, date) {
            console.log('Loading time slots for service', serviceId, 'provider', providerId, 'date', date);

            // Create cache key
            var cacheKey = serviceId + '_' + providerId + '_' + date;

            // Check if we already have cached data
            if (timeSlotsCache[cacheKey]) {
                console.log('Using cached time slots for:', cacheKey);
                renderTimeSlots(timeSlotsCache[cacheKey]);
                return;
            }

            // Prevent multiple simultaneous requests
            if (isLoadingTimeSlots) {
                console.log('Already loading time slots, skipping request');
                return;
            }

            isLoadingTimeSlots = true;

            // Show the time slots section
            $('#time-slots-section').removeClass('tw-hidden');

            // Show loading indicator only if container is empty
            if ($('#time-slots-container').html().trim() === '') {
                $('#slot-loading').removeClass('hidden');
                // Clear any existing time slots
                $('#time-slots-container').empty();
            }

            var timezone = $('#timezone').val() || Intl.DateTimeFormat().resolvedOptions().timeZone;

            // Prepare data for the request
            var ajaxData = {
                service_id: serviceId,
                provider_id: providerId, // Using provider_id as the key
                staff_id: providerId, // Also include staff_id for backward compatibility
                date: date,
                timezone: timezone
            };

            // Add CSRF token if available
            if (typeof csrfData !== 'undefined') {
                ajaxData[csrfData.token_name] = csrfData.hash;
            } else if (typeof csrfTokenName !== 'undefined' && typeof csrfTokenValue !== 'undefined') {
                ajaxData[csrfTokenName] = csrfTokenValue;
            }

            // Send AJAX request to get available time slots
            $.ajax({
                url: site_url + 'appointly/appointments_public/get_available_time_slots',
                type: 'POST',
                data: ajaxData,
                dataType: 'json',
                success: function(response) {
                    console.log('Time slots response:', response);

                    // Cache the response
                    timeSlotsCache[cacheKey] = response;

                    // Render the time slots
                    renderTimeSlots(response);

                    // Reset loading flag
                    isLoadingTimeSlots = false;
                },
                error: function(xhr, status, error) {
                    console.error('Error loading time slots:', error);

                    // Hide loading indicator
                    $('#slot-loading').addClass('hidden');

                    // Show error message
                    $('#time-slots-container').html(
                        '<div class="tw-col-span-full tw-text-center tw-py-6 tw-text-red-600">' +
                        appointlyLang.error_loading_slots +
                        '</div>'
                    );

                    $('.btn-next[data-step="3"]').prop('disabled', true);
                    alert_float('danger', appointlyLang.error_loading_slots);

                    // Reset loading flag
                    isLoadingTimeSlots = false;
                }
            });
        }

        /**
         * Render time slots from response data
         */
        function renderTimeSlots(response) {
            console.log('Rendering time slots:', response);

            // Hide loading indicator
            $('#slot-loading').addClass('hidden');

            // Get the time slots container
            var $timeSlotContainer = $('#time-slots-container');
            $timeSlotContainer.empty();

            if (response && response.success && response.time_slots && response.time_slots.length > 0) {
                // Track if we have available slots
                var hasAvailableSlots = false;

                // Add time slots as buttons
                response.time_slots.forEach(function(slot) {
                    if (slot.available !== false) {
                        hasAvailableSlots = true;

                        // Create button element for the time slot
                        var $timeSlotBtn = $('<button>', {
                            type: 'button',
                            class: 'time-slot-btn',
                            'data-start-time': slot.value,
                            'data-end-time': slot.end_time,
                            'data-text': slot.text,
                            html: '<span>' + slot.text + '</span>'
                        });

                        // Add event listener to select this time slot
                        $timeSlotBtn.on('click', function(e) {
                            // Prevent default form submission behavior
                            e.preventDefault();
                            e.stopPropagation();

                            console.log('Time slot clicked:', $(this).data('text'));

                            // Remove selected class from all buttons
                            $('.time-slot-btn').removeClass('selected');

                            // Add selected class to this button
                            $(this).addClass('selected');

                            // Store the selected time values
                            selectedTime = $(this).data('start-time');
                            selectedEndTime = $(this).data('end-time');

                            // Update hidden inputs
                            $('#start_hour').val(selectedTime);
                            $('#end_hour').val(selectedEndTime);

                            // Enable the next button
                            $('.btn-next[data-step="3"]').prop('disabled', false);

                            // Update appointment summary without regenerating datepicker
                            updateAppointmentSummary();

                            // Smooth scroll to next button with focus
                            setTimeout(function() {
                                var $nextButton = $('.btn-next[data-step="3"]');
                                if ($nextButton.length) {
                                    $nextButton.focus();
                                    $('html, body').animate({
                                        scrollTop: $nextButton.offset().top - 100
                                    }, 500, 'swing');
                                }
                            }, 100);

                            // Return false to prevent bubbling and form submission
                            return false;
                        });

                        $timeSlotContainer.append($timeSlotBtn);
                    }
                });

                // Show no slots message if no available slots
                if (!hasAvailableSlots) {
                    $timeSlotContainer.html(
                        '<div class="alert alert-warning tw-col-span-full tw-text-center tw-py-6 tw-text-neutral-500">' +
                        appointlyLang.no_slots_available +
                        '</div>'
                    );
                    $('.btn-next[data-step="3"]').prop('disabled', true);
                }
            } else {
                // No slots available
                var message = (response && response.message) ? response.message : appointlyLang.no_slots_available;

                $timeSlotContainer.html(
                    '<div class="alert alert-warning tw-col-span-full tw-text-center tw-py-6 tw-text-neutral-500">' +
                    message +
                    '</div>'
                );
                $('.btn-next[data-step="3"]').prop('disabled', true);
            }
        }

        /**
         * Reset time selection
         */
        function resetTimeSelection() {
            // Clear time slots container
            $('#time-slots-container').empty();

            // Hide the time slots section
            $('#time-slots-section').addClass('tw-hidden');

            // Clear hidden inputs
            $('#start_hour').val('');
            $('#end_hour').val('');

            // Disable next button
            $('.btn-next[data-step="3"]').prop('disabled', true);
        }

        /**
         * Update appointment summary
         */
        function updateAppointmentSummary() {
            console.log('Updating appointment summary');

            // Service info
            var serviceName = '';
            var serviceDuration = '';
            var servicePrice = '';

            $('.service-card').each(function() {
                if ($(this).data('service-id') == selectedService) {
                    serviceName = $(this).find('h5').text();
                    serviceDuration = $(this).data('duration') || '';
                    servicePrice = $(this).data('price') || '';
                }
            });

            // Provider info
            var providerName = '';

            $('.provider-card').each(function() {
                if ($(this).data('provider-id') == selectedProvider) {
                    providerName = $(this).find('h5').text();
                }
            });

            // Format date
            var formattedDate = selectedDate ? moment(selectedDate, 'YYYY-MM-DD').format('LL') : '';

            // Format time
            var formattedTime = '';
            if (selectedTime) {
                formattedTime = moment(selectedTime, 'HH:mm').format('LT');

                if (selectedEndTime) {
                    formattedTime += ' - ' + moment(selectedEndTime, 'HH:mm').format('LT');
                }
            }

            // Update step 3 summary fields
            $('#summary-service-name').text(serviceName || '-');
            $('#summary-provider-name').text(providerName || '-');

            // Update the final summary in step 4
            $('#final-service-name').text(serviceName || '-');
            $('#final-service-price').text(servicePrice || '-');
            $('#final-provider-name').text(providerName || '-');

            $('#final-date-time').text((formattedDate ? formattedDate + ', ' : '') + (formattedTime || '-'));

            // Prevent event propagation that might cause datepicker to regenerate
            return false;
        }

        /**
         * Reset form to initial state
         */
        function resetForm() {
            console.log('Resetting form');

            // Reset variables
            selectedService = null;
            selectedProvider = null;
            selectedDate = null;
            selectedTime = null;
            selectedEndTime = null;

            // Reset service selection
            $('.service-card').removeClass('selected');

            // Reset provider selection
            $('.provider-card').removeClass('selected');
            $('#providers-container').empty();

            // Reset date and time selection
            $('#appointment-date').val('').prop('disabled', true);
            resetTimeSelection();

            // Reset hidden inputs
            $('input[name="service_id"]').val('');
            $('input[name="staff_id"]').val('');
            $('input[name="start_hour"]').val('');
            $('input[name="end_hour"]').val('');

            // Reset contact form fields
            $('#appointment-form').find('input[type="text"], input[type="email"], textarea').val('');

            // Reset current step
            currentStep = 1;
            updateStepDisplay(currentStep);
        }
    });

    // Language Dropdown Handler
    $(document).ready(function() {
        $('#language-dropdown').on('change', function() {
            var selectedLanguage = $(this).val();
            var currentUrl = window.location.href;

            // Remove existing lang parameter if present
            var url = new URL(currentUrl);
            url.searchParams.set('lang', selectedLanguage);

            // Update hidden field
            $('#current_language').val(selectedLanguage);

            // Show loading state
            $(this).prop('disabled', true);

            // Redirect to the same page with new language parameter
            window.location.href = url.toString();
        });
    });
</script>