/* ===================================
   ADMIN DASHBOARD - JAVASCRIPT
   ==================================== */

let serviceReservationsRefreshTimer = null;
let reservationsRefreshTimer = null;
let offersRefreshTimer = null;

// Notification system
function showNotification(message, type = 'success', duration = 3000) {
    const notification = document.createElement('div');
    notification.className = `admin-notification admin-notification-${type}`;
    notification.innerHTML = `
        <div class="notification-content">
            <i class="fa fa-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-circle' : 'info-circle'}"></i>
            <span>${message}</span>
        </div>
    `;
    
    document.body.appendChild(notification);
    
    // Trigger animation
    setTimeout(() => notification.classList.add('show'), 10);
    
    // Remove after duration
    setTimeout(() => {
        notification.classList.remove('show');
        setTimeout(() => notification.remove(), 300);
    }, duration);
}

document.addEventListener('DOMContentLoaded', function () {
    const sidebarToggle = document.getElementById('sidebarToggle');
    const sidebarToggleMobile = document.getElementById('sidebarToggleMobile');
    const adminSidebar = document.getElementById('adminSidebar');

    if (sidebarToggle && adminSidebar) {
        sidebarToggle.addEventListener('click', function () {
            adminSidebar.classList.remove('active');
        });
    }

    if (sidebarToggleMobile && adminSidebar) {
        sidebarToggleMobile.addEventListener('click', function (e) {
            e.stopPropagation();
            adminSidebar.classList.toggle('active');
        });
    }

    const navItems = document.querySelectorAll('.nav-link');
    navItems.forEach(item => {
        item.addEventListener('click', function () {
            if (window.innerWidth <= 767 && adminSidebar) {
                adminSidebar.classList.remove('active');
            }
        });
    });

    // Close sidebar when clicking outside on mobile
    document.addEventListener('click', function (e) {
        if (
            window.innerWidth <= 767 &&
            adminSidebar &&
            sidebarToggleMobile &&
            !adminSidebar.contains(e.target) &&
            !sidebarToggleMobile.contains(e.target) &&
            adminSidebar.classList.contains('active')
        ) {
            adminSidebar.classList.remove('active');
        }
    });

    window.addEventListener('resize', function () {
        if (window.innerWidth > 767 && adminSidebar) {
            adminSidebar.classList.remove('active');
        }
        makeTableResponsive();
    });

    const searchInput = document.querySelector('.search-input');
    if (searchInput) {
        searchInput.addEventListener('input', debounce(function (e) {
            const content = document.querySelector('.admin-content');
            const section = content ? content.dataset.activeSection : '';
            const query = e.target.value || '';

            if (section === 'guests') {
                loadGuests(query);
                return;
            }

            console.log('Searching for:', query.toLowerCase());
        }, 300));
    }

    const filterSelects = document.querySelectorAll('.filter-select');
    filterSelects.forEach(select => {
        select.addEventListener('change', function () {
            const content = document.querySelector('.admin-content');
            const section = content ? content.dataset.activeSection : '';
            if (section === 'service-reservations') {
                loadServiceReservations(getServiceReservationFilters());
            }
        });
    });

    const actionLinks = document.querySelectorAll('.action-link');
    actionLinks.forEach(link => {
        link.addEventListener('click', function (e) {
            e.preventDefault();
            console.log('Action clicked');
        });
    });

    initGuestModal();
    initRevenueInvoiceModal();
    initServiceReservationModal();
    initReservationModal();
    initServiceCrud();
    initRoomCrud();
    initGalleryCrud();
    initNewsCrud();
    initOfferCrud();
    initHeroSliderActions();
    initServiceStatusActions();
    initServicePaymentActions();
    initReservationStatusActions();
    initReservationPaymentActions();
    initReservationFilters();
    initServiceReservationFilters();
    initNewsletterActions();
    makeTableResponsive();
    loadActiveSectionData();

    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function (e) {
            const href = String(this.getAttribute('href') || '').trim();
            if (href === '#' || href.length < 2) {
                e.preventDefault();
                return;
            }

            let target = null;
            try {
                target = document.querySelector(href);
            } catch (selectorError) {
                target = null;
            }

            if (target) {
                e.preventDefault();
                target.scrollIntoView({ behavior: 'smooth' });
            }
        });
    });

    observeElements('.stat-card', 'fadeInUp');
    observeElements('.content-section', 'fadeInUp');

    document.querySelectorAll('input[type="number"]').forEach(input => {
        input.addEventListener('change', function () {
            if (this.value < 0) {
                this.value = 0;
            }
        });
    });

    document.querySelectorAll('.btn-action').forEach(btn => {
        btn.addEventListener('click', function () {
            if (!this.classList.contains('toggle')) {
                const originalText = this.innerHTML;
                this.disabled = true;
                this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Loading...';
                setTimeout(() => {
                    this.disabled = false;
                    this.innerHTML = originalText;
                }, 800);
            }
        });
    });
});

function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

function observeElements(selector, animationClass) {
    const elements = document.querySelectorAll(selector);
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add(animationClass);
                observer.unobserve(entry.target);
            }
        });
    }, { threshold: 0.1 });

    elements.forEach(el => observer.observe(el));
}

function makeTableResponsive() {
    const tables = document.querySelectorAll('.admin-table');
    tables.forEach(table => {
        if (window.innerWidth <= 767) {
            table.classList.add('responsive');
            applyTableDataLabels(table);
        } else {
            table.classList.remove('responsive');
        }
    });
}

function applyTableDataLabels(table) {
    const rows = table.querySelectorAll('tbody tr');
    const headers = table.querySelectorAll('thead th');
    rows.forEach(row => {
        const cells = row.querySelectorAll('td');
        cells.forEach((cell, index) => {
            if (index < headers.length) {
                cell.setAttribute('data-label', headers[index].textContent.trim());
            }
        });
    });
}

async function fetchAdminData(action, params = {}, retryCount = 1) {
    const query = new URLSearchParams({ action, _ts: Date.now(), ...params });
    let response;
    try {
        response = await fetch(`api/get-admin-data.php?${query.toString()}`, {
            method: 'GET',
            cache: 'no-store',
            credentials: 'same-origin',
            headers: {
                Accept: 'application/json',
                'Cache-Control': 'no-cache'
            }
        });
    } catch (networkError) {
        if (retryCount > 0) {
            return fetchAdminData(action, params, retryCount - 1);
        }
        throw new Error('Network error while fetching data');
    }

    let result;
    try {
        result = await response.json();
    } catch (e) {
        if (retryCount > 0) {
            return fetchAdminData(action, params, retryCount - 1);
        }
        throw new Error('Invalid server response');
    }
    if (!response.ok || !result.success) {
        throw new Error(result.error || 'Failed to fetch admin data');
    }
    return result;
}

async function postAdminData(action, payload = {}, retryCount = 1) {
    const isFormData = payload instanceof FormData;
    const requestOptions = {
        method: 'POST',
        cache: 'no-store',
        credentials: 'same-origin',
        headers: {
            'Accept': 'application/json',
            'Cache-Control': 'no-cache'
        }
    };

    if (isFormData) {
        if (!payload.has('action')) {
            payload.append('action', action);
        }
        requestOptions.body = payload;
    } else {
        const normalizedPayload = { action, ...payload };
        requestOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
        requestOptions.body = new URLSearchParams(normalizedPayload).toString();
    }

    let response;
    try {
        response = await fetch(`api/get-admin-data.php?action=${encodeURIComponent(action)}&_ts=${Date.now()}`, {
            ...requestOptions
        });
    } catch (networkError) {
        if (retryCount > 0) {
            return postAdminData(action, payload, retryCount - 1);
        }
        throw new Error('Network error while updating data');
    }

    let result;
    try {
        result = await response.json();
    } catch (e) {
        if (retryCount > 0) {
            return postAdminData(action, payload, retryCount - 1);
        }
        throw new Error('Invalid server response');
    }
    if (!response.ok || !result.success) {
        throw new Error(result.error || 'Failed to update data');
    }
    return result;
}

function loadActiveSectionData() {
    const content = document.querySelector('.admin-content');
    if (!content) {
        return;
    }

    const section = content.dataset.activeSection || '';
    if (section === 'guests') {
        loadGuests('');
    }

    if (section === 'reservations') {
        loadReservations(getReservationFilters());
        startReservationsLiveRefresh();
    } else {
        stopReservationsLiveRefresh();
    }

    if (section === 'services') {
        loadServices();
    }

    if (section === 'rooms') {
        loadRooms();
    }

    if (section === 'gallery') {
        loadGallery();
    }

    if (section === 'news') {
        loadNews();
    }

    if (section === 'offers') {
        loadOffers();
        startOffersLiveRefresh();
    } else {
        stopOffersLiveRefresh();
    }

    if (section === 'hero-slider') {
        loadHeroSlides();
    }

    if (section === 'service-reservations') {
        loadServiceReservations(getServiceReservationFilters());
        startServiceReservationsLiveRefresh();
    } else {
        stopServiceReservationsLiveRefresh();
    }

    if (section === 'newsletter') {
        loadNewsletterSubscribers();
    }
}

function getReservationFilters() {
    const statusFilter = document.getElementById('reservationStatusFilter');
    const guestFilter = document.getElementById('reservationGuestFilter');
    const roomFilter = document.getElementById('reservationRoomFilter');
    return {
        status: statusFilter ? String(statusFilter.value || '').trim() : '',
        guest: guestFilter ? String(guestFilter.value || '').trim() : '',
        room: roomFilter ? String(roomFilter.value || '').trim() : ''
    };
}

function initReservationFilters() {
    const statusFilter = document.getElementById('reservationStatusFilter');
    const guestFilter = document.getElementById('reservationGuestFilter');
    const roomFilter = document.getElementById('reservationRoomFilter');
    const clearBtn = document.getElementById('reservationFilterClear');

    const triggerLoad = () => {
        const content = document.querySelector('.admin-content');
        if (!content || content.dataset.activeSection !== 'reservations') {
            return;
        }
        loadReservations(getReservationFilters());
    };
    const debouncedTriggerLoad = debounce(triggerLoad, 250);

    if (statusFilter) {
        statusFilter.addEventListener('change', triggerLoad);
    }
    if (guestFilter) {
        guestFilter.addEventListener('input', debouncedTriggerLoad);
    }
    if (roomFilter) {
        roomFilter.addEventListener('input', debouncedTriggerLoad);
    }
    if (clearBtn) {
        clearBtn.addEventListener('click', function () {
            if (statusFilter) statusFilter.value = '';
            if (guestFilter) guestFilter.value = '';
            if (roomFilter) roomFilter.value = '';
            triggerLoad();
        });
    }
}

function getServiceReservationFilters() {
    const statusFilter = document.getElementById('serviceReservationStatusFilter');
    const guestFilter = document.getElementById('serviceReservationGuestFilter');
    const serviceFilter = document.getElementById('serviceReservationServiceFilter');
    const dateFilter = document.getElementById('serviceReservationDateFilter');
    return {
        status: statusFilter ? String(statusFilter.value || '').trim() : '',
        guest: guestFilter ? String(guestFilter.value || '').trim() : '',
        service: serviceFilter ? String(serviceFilter.value || '').trim() : '',
        date: dateFilter ? String(dateFilter.value || '').trim() : ''
    };
}

function initServiceReservationFilters() {
    const statusFilter = document.getElementById('serviceReservationStatusFilter');
    const guestFilter = document.getElementById('serviceReservationGuestFilter');
    const serviceFilter = document.getElementById('serviceReservationServiceFilter');
    const dateFilter = document.getElementById('serviceReservationDateFilter');
    const clearBtn = document.getElementById('serviceReservationFilterClear');

    const triggerLoad = () => {
        const content = document.querySelector('.admin-content');
        if (!content || content.dataset.activeSection !== 'service-reservations') {
            return;
        }
        loadServiceReservations(getServiceReservationFilters());
    };
    const debouncedTriggerLoad = debounce(triggerLoad, 250);

    if (statusFilter) {
        statusFilter.addEventListener('change', triggerLoad);
    }
    if (guestFilter) {
        guestFilter.addEventListener('input', debouncedTriggerLoad);
    }
    if (serviceFilter) {
        serviceFilter.addEventListener('input', debouncedTriggerLoad);
    }
    if (dateFilter) {
        dateFilter.addEventListener('change', triggerLoad);
    }
    if (clearBtn) {
        clearBtn.addEventListener('click', function () {
            if (statusFilter) statusFilter.value = '';
            if (guestFilter) guestFilter.value = '';
            if (serviceFilter) serviceFilter.value = '';
            if (dateFilter) dateFilter.value = '';
            triggerLoad();
        });
    }
}

function initNewsletterActions() {
    const form = document.getElementById('newsletterForm');
    const subjectInput = document.getElementById('newsletterSubject');
    const messageInput = document.getElementById('newsletterMessage');
    const sendBtn = document.getElementById('newsletterSendBtn');
    const resetBtn = document.getElementById('newsletterResetBtn');

    if (!form || !subjectInput || !messageInput || !sendBtn || !resetBtn) {
        return;
    }

    resetBtn.addEventListener('click', function () {
        subjectInput.value = '';
        messageInput.value = '';
        subjectInput.focus();
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const subject = String(subjectInput.value || '').trim();
        const message = String(messageInput.value || '').trim();
        if (!subject || !message) {
            showNotification('Please fill subject and message before sending.', 'error', 3000);
            return;
        }

        sendBtn.disabled = true;
        sendBtn.classList.add('is-updating');

        try {
            const result = await postAdminData('send_newsletter', { subject, message });
            showNotification(result.message || 'Newsletter sent successfully.', 'success', 3500);
            messageInput.value = '';
            await loadNewsletterSubscribers();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to send newsletter right now.', 'error', 4000);
        } finally {
            sendBtn.disabled = false;
            sendBtn.classList.remove('is-updating');
        }
    });
}

async function loadNewsletterSubscribers() {
    const tbody = document.getElementById('newsletterSubscribersTableBody');
    const table = document.getElementById('newsletterSubscribersTable');
    const totalEl = document.getElementById('newsletterSubscriberCount');

    if (!tbody || !table || !totalEl) {
        return;
    }

    tbody.innerHTML = '<tr><td colspan="3" class="text-center">Loading subscribers...</td></tr>';

    try {
        const result = await fetchAdminData('get_newsletter_subscribers');
        const rows = Array.isArray(result.data) ? result.data : [];
        totalEl.textContent = String(result.total || rows.length || 0);

        if (!rows.length) {
            tbody.innerHTML = '<tr><td colspan="3" class="text-center">No subscribers found.</td></tr>';
            makeTableResponsive();
            return;
        }

        tbody.innerHTML = rows.slice(0, 80).map((row) => {
            const email = escapeHtml(row.email || '-');
            const name = escapeHtml((row.name || '').trim() || 'Subscriber');
            const source = escapeHtml(normalizeStatusLabel(row.source || 'website').replace(/\s+/g, ' '));
            return `
                <tr>
                    <td>${email}</td>
                    <td>${name}</td>
                    <td><span class="status-badge status-pending">${source}</span></td>
                </tr>
            `;
        }).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
    } catch (error) {
        console.error(error);
        totalEl.textContent = '0';
        tbody.innerHTML = '<tr><td colspan="3" class="text-center">Unable to load subscribers.</td></tr>';
    }
}

function initHeroSliderActions() {
    const layout = document.getElementById('heroSliderAdminLayout');
    const formCard = document.getElementById('heroSlideFormCard');
    const addBtn = document.getElementById('heroSlideAddBtn');
    const form = document.getElementById('heroSlideForm');
    const idField = document.getElementById('heroSlideId');
    const editorTitle = document.getElementById('heroSlideEditorTitle');
    const labelField = document.getElementById('heroSlideLabel');
    const titleField = document.getElementById('heroSlideTitle');
    const descriptionField = document.getElementById('heroSlideDescription');
    const buttonTextField = document.getElementById('heroSlideButtonText');
    const buttonUrlField = document.getElementById('heroSlideButtonUrl');
    const imageUrlField = document.getElementById('heroSlideImageUrl');
    const sortOrderField = document.getElementById('heroSlideSortOrder');
    const statusField = document.getElementById('heroSlideStatus');
    const labelColorField = document.getElementById('heroSlideLabelColor');
    const titleColorField = document.getElementById('heroSlideTitleColor');
    const descriptionColorField = document.getElementById('heroSlideDescriptionColor');
    const buttonTextColorField = document.getElementById('heroSlideButtonTextColor');
    const buttonBgColorField = document.getElementById('heroSlideButtonBgColor');
    const resetBtn = document.getElementById('heroSlideResetBtn');
    const closeBtn = document.getElementById('heroSlideCloseBtn');
    const headerCloseBtn = document.getElementById('heroSlideCancelBtn');
    const submitBtn = document.getElementById('heroSlideSubmitBtn');
    const previewBox = document.getElementById('heroSlideLivePreview');
    const previewLabel = document.getElementById('heroPreviewLabel');
    const previewTitle = document.getElementById('heroPreviewTitle');
    const previewDescription = document.getElementById('heroPreviewDescription');
    const previewButton = document.getElementById('heroPreviewButton');

    if (!form || !idField || !titleField || !imageUrlField || !submitBtn) {
        return;
    }

    const getFallbackImage = () => 'images/background/1.webp';
    const toPreviewColor = (value, fallback) => {
        const raw = String(value || '').trim();
        return /^#([a-f0-9]{3}|[a-f0-9]{6})$/i.test(raw) ? raw : fallback;
    };
    const updatePreview = () => {
        if (!previewBox) {
            return;
        }

        const labelText = String(labelField ? labelField.value : '').trim() || 'Featured';
        const titleText = String(titleField ? titleField.value : '').trim() || 'Your Slide Title';
        const descriptionText = String(descriptionField ? descriptionField.value : '').trim() || 'Your slide description will appear here.';
        const buttonText = String(buttonTextField ? buttonTextField.value : '').trim() || 'Explore';
        const imageUrl = String(imageUrlField ? imageUrlField.value : '').trim() || getFallbackImage();

        if (previewLabel) {
            previewLabel.textContent = labelText;
            previewLabel.style.color = toPreviewColor(labelColorField ? labelColorField.value : '', '#fcbf49');
        }
        if (previewTitle) {
            previewTitle.textContent = titleText;
            previewTitle.style.color = toPreviewColor(titleColorField ? titleColorField.value : '', '#ffffff');
        }
        if (previewDescription) {
            previewDescription.textContent = descriptionText;
            previewDescription.style.color = toPreviewColor(descriptionColorField ? descriptionColorField.value : '', '#e5e7eb');
        }
        if (previewButton) {
            previewButton.textContent = buttonText;
            previewButton.style.color = toPreviewColor(buttonTextColorField ? buttonTextColorField.value : '', '#10243d');
            previewButton.style.backgroundColor = toPreviewColor(buttonBgColorField ? buttonBgColorField.value : '', '#fcbf49');
        }

        previewBox.style.backgroundImage = `url('${imageUrl.replace(/'/g, "\\'")}')`;
    };

    const openEditor = (mode = 'edit') => {
        if (formCard) {
            formCard.classList.remove('is-collapsed');
            formCard.classList.add('is-open');
        }
        if (layout) {
            layout.classList.remove('form-collapsed');
            if (mode === 'add' || mode === 'edit') {
                layout.classList.add('form-editor-only');
            } else {
                layout.classList.remove('form-editor-only');
            }
        }
    };

    const closeEditor = () => {
        if (formCard) {
            formCard.classList.add('is-collapsed');
            formCard.classList.remove('is-open');
        }
        if (layout) {
            layout.classList.add('form-collapsed');
            layout.classList.remove('form-editor-only');
        }
    };

    const applyDefaults = () => {
        idField.value = '';
        if (labelField) labelField.value = '';
        titleField.value = '';
        if (descriptionField) descriptionField.value = '';
        if (buttonTextField) buttonTextField.value = 'Explore';
        if (buttonUrlField) buttonUrlField.value = 'rooms.php';
        imageUrlField.value = '';
        if (sortOrderField) sortOrderField.value = '1';
        if (statusField) statusField.value = '1';
        if (labelColorField) labelColorField.value = '#fcbf49';
        if (titleColorField) titleColorField.value = '#ffffff';
        if (descriptionColorField) descriptionColorField.value = '#e5e7eb';
        if (buttonTextColorField) buttonTextColorField.value = '#10243d';
        if (buttonBgColorField) buttonBgColorField.value = '#fcbf49';
        submitBtn.textContent = 'Save Slide';
        if (editorTitle) {
            editorTitle.textContent = 'Add Slide';
        }
        updatePreview();
    };

    const fillForEdit = (button) => {
        if (!button) return;
        idField.value = button.dataset.id || '';
        if (labelField) labelField.value = button.dataset.label || '';
        titleField.value = button.dataset.title || '';
        if (descriptionField) descriptionField.value = button.dataset.description || '';
        if (buttonTextField) buttonTextField.value = button.dataset.buttonText || 'Explore';
        if (buttonUrlField) buttonUrlField.value = button.dataset.buttonUrl || 'rooms.php';
        imageUrlField.value = button.dataset.imageUrl || '';
        if (sortOrderField) sortOrderField.value = button.dataset.sortOrder || '0';
        if (statusField) statusField.value = button.dataset.active === '0' ? '0' : '1';
        if (labelColorField) labelColorField.value = button.dataset.labelColor || '#fcbf49';
        if (titleColorField) titleColorField.value = button.dataset.titleColor || '#ffffff';
        if (descriptionColorField) descriptionColorField.value = button.dataset.descriptionColor || '#e5e7eb';
        if (buttonTextColorField) buttonTextColorField.value = button.dataset.buttonTextColor || '#10243d';
        if (buttonBgColorField) buttonBgColorField.value = button.dataset.buttonBgColor || '#fcbf49';
        submitBtn.textContent = 'Update Slide';
        if (editorTitle) {
            editorTitle.textContent = 'Edit Slide';
        }
        updatePreview();
        openEditor('edit');
        form.scrollIntoView({ behavior: 'smooth', block: 'start' });
    };

    if (addBtn) {
        addBtn.addEventListener('click', function () {
            applyDefaults();
            openEditor('add');
            titleField.focus();
        });
    }

    if (resetBtn) {
        resetBtn.addEventListener('click', function () {
            applyDefaults();
            if (titleField) {
                titleField.focus();
            }
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', function () {
            closeEditor();
        });
    }

    if (headerCloseBtn) {
        headerCloseBtn.addEventListener('click', function () {
            closeEditor();
        });
    }

    [
        labelField,
        titleField,
        descriptionField,
        buttonTextField,
        imageUrlField,
        labelColorField,
        titleColorField,
        descriptionColorField,
        buttonTextColorField,
        buttonBgColorField
    ].forEach((field) => {
        if (!field) {
            return;
        }
        field.addEventListener('input', updatePreview);
        field.addEventListener('change', updatePreview);
    });

    document.addEventListener('click', function (event) {
        const editBtn = event.target.closest('.hero-slide-edit-btn');
        if (editBtn) {
            event.preventDefault();
            fillForEdit(editBtn);
            return;
        }

        const deleteBtn = event.target.closest('.hero-slide-delete-btn');
        if (!deleteBtn) {
            return;
        }

        event.preventDefault();
        const id = String(deleteBtn.dataset.id || '').trim();
        if (!id) {
            return;
        }

        if (!confirm('Delete this hero slide?')) {
            return;
        }

        deleteBtn.classList.add('is-updating');
        postAdminData('delete_hero_slide', { id })
            .then(() => {
                showNotification('Hero slide deleted.', 'success', 2500);
                loadHeroSlides();
                if (idField.value === id) {
                    applyDefaults();
                    closeEditor();
                }
            })
            .catch((error) => {
                console.error(error);
                showNotification(error.message || 'Unable to delete hero slide.', 'error', 3500);
            })
            .finally(() => deleteBtn.classList.remove('is-updating'));
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const payload = {
            label: String(labelField ? labelField.value : '').trim(),
            title: String(titleField.value || '').trim(),
            description: String(descriptionField ? descriptionField.value : '').trim(),
            button_text: String(buttonTextField ? buttonTextField.value : '').trim() || 'Explore',
            button_url: String(buttonUrlField ? buttonUrlField.value : '').trim() || 'rooms.php',
            image_url: String(imageUrlField.value || '').trim(),
            sort_order: String(sortOrderField ? sortOrderField.value : '0').trim() || '0',
            is_active: statusField && statusField.value === '0' ? '0' : '1',
            label_color: labelColorField ? String(labelColorField.value || '#fcbf49').trim() : '#fcbf49',
            title_color: titleColorField ? String(titleColorField.value || '#ffffff').trim() : '#ffffff',
            description_color: descriptionColorField ? String(descriptionColorField.value || '#e5e7eb').trim() : '#e5e7eb',
            button_text_color: buttonTextColorField ? String(buttonTextColorField.value || '#10243d').trim() : '#10243d',
            button_bg_color: buttonBgColorField ? String(buttonBgColorField.value || '#fcbf49').trim() : '#fcbf49'
        };

        if (!payload.title || !payload.image_url) {
            showNotification('Title and image URL are required.', 'error', 3000);
            return;
        }

        const isEdit = String(idField.value || '').trim() !== '';
        if (isEdit) {
            payload.id = String(idField.value || '').trim();
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');
        try {
            const result = await postAdminData(isEdit ? 'update_hero_slide' : 'add_hero_slide', payload);
            showNotification(isEdit ? 'Hero slide updated.' : 'Hero slide added.', 'success', 3000);
            if (result && result.data) {
                upsertHeroSlideRow(result.data);
                setTimeout(() => {
                    loadHeroSlides();
                }, 250);
            } else {
                await loadHeroSlides();
            }
            applyDefaults();
            closeEditor();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save hero slide.', 'error', 3500);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });

    applyDefaults();
    closeEditor();
    updatePreview();
}

function renderHeroSlideRow(row) {
    const id = safeDataValue(row.id || '');
    const label = escapeHtml(row.label || 'Featured');
    const title = escapeHtml(row.title || 'Untitled');
    const imageUrl = escapeHtml(row.image_url || '');
    const sortOrder = escapeHtml(row.sort_order ?? 0);
    const isActive = Number(row.is_active) === 1 || row.is_active === true || row.is_active === '1';
    const statusClass = isActive ? 'confirmed' : 'cancelled';
    const statusText = isActive ? 'Active' : 'Inactive';
    const labelColor = String(row.label_color || '#FCBF49').toUpperCase();
    const titleColor = String(row.title_color || '#FFFFFF').toUpperCase();
    const descriptionColor = String(row.description_color || '#E5E7EB').toUpperCase();
    const buttonTextColor = String(row.button_text_color || '#10243D').toUpperCase();
    const buttonBgColor = String(row.button_bg_color || '#FCBF49').toUpperCase();

    return `
        <tr data-row-id="${id}">
            <td>${sortOrder}</td>
            <td>
                <strong>${title}</strong>
                <div class="hero-slide-row-meta">${label}</div>
                <div class="hero-slide-row-meta">${imageUrl}</div>
            </td>
            <td>
                <div class="hero-color-swatch-list">
                    <span class="hero-color-swatch" style="--swatch-color:${escapeHtml(labelColor)}" title="Label: ${escapeHtml(labelColor)}"></span>
                    <span class="hero-color-swatch" style="--swatch-color:${escapeHtml(titleColor)}" title="Title: ${escapeHtml(titleColor)}"></span>
                    <span class="hero-color-swatch" style="--swatch-color:${escapeHtml(descriptionColor)}" title="Description: ${escapeHtml(descriptionColor)}"></span>
                    <span class="hero-color-swatch" style="--swatch-color:${escapeHtml(buttonTextColor)}" title="Button Text: ${escapeHtml(buttonTextColor)}"></span>
                    <span class="hero-color-swatch" style="--swatch-color:${escapeHtml(buttonBgColor)}" title="Button BG: ${escapeHtml(buttonBgColor)}"></span>
                </div>
            </td>
            <td><span class="status-badge status-${statusClass}">${statusText}</span></td>
            <td>
                <div class="hero-slide-actions">
                    <a href="#"
                       class="action-link action-btn hero-slide-edit-btn"
                       title="Edit Slide"
                       data-id="${id}"
                       data-label="${safeDataValue(row.label || '')}"
                       data-title="${safeDataValue(row.title || '')}"
                       data-description="${safeDataValue(row.description || '')}"
                       data-button-text="${safeDataValue(row.button_text || '')}"
                       data-button-url="${safeDataValue(row.button_url || '')}"
                       data-image-url="${safeDataValue(row.image_url || '')}"
                       data-sort-order="${safeDataValue(row.sort_order ?? 0)}"
                       data-active="${isActive ? '1' : '0'}"
                       data-label-color="${safeDataValue(labelColor)}"
                       data-title-color="${safeDataValue(titleColor)}"
                       data-description-color="${safeDataValue(descriptionColor)}"
                       data-button-text-color="${safeDataValue(buttonTextColor)}"
                       data-button-bg-color="${safeDataValue(buttonBgColor)}">
                        <i class="fa fa-pencil"></i>
                    </a>
                    <a href="#"
                       class="action-link action-btn hero-slide-delete-btn"
                       title="Delete Slide"
                       data-id="${id}">
                        <i class="fa fa-trash"></i>
                    </a>
                </div>
            </td>
        </tr>
    `;
}

function upsertHeroSlideRow(row) {
    const tbody = document.getElementById('heroSlidesTableBody');
    const table = document.getElementById('heroSlidesTable');
    if (!tbody || !table || !row) {
        return;
    }

    const currentId = String(row.id || '').trim();
    if (!currentId) {
        return;
    }

    const placeholderRow = tbody.querySelector('tr td[colspan]');
    if (placeholderRow) {
        tbody.innerHTML = '';
    }

    const existing = tbody.querySelector(`tr[data-row-id="${currentId}"]`);
    const rowHtml = renderHeroSlideRow(row);
    if (existing) {
        existing.outerHTML = rowHtml;
    } else {
        tbody.insertAdjacentHTML('afterbegin', rowHtml);
    }

    makeTableResponsive();
    applyTableDataLabels(table);
}

async function loadHeroSlides() {
    const tbody = document.getElementById('heroSlidesTableBody');
    const table = document.getElementById('heroSlidesTable');
    if (!tbody || !table) {
        return false;
    }

    tbody.innerHTML = '<tr><td colspan="5" class="text-center">Loading hero slides...</td></tr>';

    try {
        const result = await fetchAdminData('get_hero_slides');
        const rows = Array.isArray(result.data) ? result.data : [];
        if (!rows.length) {
            tbody.innerHTML = '<tr><td colspan="5" class="text-center">No hero slides found.</td></tr>';
            makeTableResponsive();
            return true;
        }

        tbody.innerHTML = rows.map((row) => renderHeroSlideRow(row)).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
        return true;
    } catch (error) {
        console.error(error);
        tbody.innerHTML = '<tr><td colspan="5" class="text-center">Unable to load hero slides.</td></tr>';
        return false;
    }
}

function safeDataValue(value) {
    return String(value ?? '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

function initGuestModal() {
    const modal = document.getElementById('guestDetailsModal');
    const closeBtn = document.getElementById('guestModalClose');
    if (!modal) {
        return;
    }

    const setDetail = (id, value) => {
        const el = document.getElementById(id);
        if (el) {
            el.textContent = value || '-';
        }
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openModal = (button) => {
        setDetail('guestDetailName', button.dataset.name || '-');
        setDetail('guestDetailEmail', button.dataset.email || '-');
        setDetail('guestDetailPhone', button.dataset.phone || '-');
        setDetail('guestDetailReservations', button.dataset.reservations || '0');
        setDetail('guestDetailJoinDate', button.dataset.joinDate || '-');
        setDetail('guestDetailStatus', button.dataset.status || '-');
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
    };

    document.addEventListener('click', function (event) {
        const trigger = event.target.closest('.guest-view-btn');
        if (trigger) {
            event.preventDefault();
            openModal(trigger);
            return;
        }

        if (event.target === modal || event.target.closest('#guestModalClose')) {
            closeModal();
        }
    });

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });
}

function initRevenueInvoiceModal() {
    const modal = document.getElementById('revenueInvoiceModal');
    const openBtn = document.getElementById('revenueInvoiceViewBtn');
    const closeBtn = document.getElementById('revenueInvoiceModalClose');
    const table = document.getElementById('revenueInvoicesTable');
    const tbody = document.getElementById('revenueInvoicesTableBody');

    if (!modal || !openBtn || !closeBtn || !table || !tbody) {
        return;
    }

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openModal = async () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        await loadRevenueInvoices();
    };

    const loadRevenueInvoices = async () => {
        tbody.innerHTML = '<tr><td colspan="9" class="text-center">Loading invoices...</td></tr>';

        try {
            const result = await fetchAdminData('get_revenue_invoices', { limit: 200 });
            const rows = Array.isArray(result.data) ? result.data : [];

            if (rows.length === 0) {
                tbody.innerHTML = '<tr><td colspan="9" class="text-center">No invoices found.</td></tr>';
                makeTableResponsive();
                return;
            }

            tbody.innerHTML = rows.map(row => {
                const invoiceNo = escapeHtml(row.invoice_no || '-');
                const invoiceType = escapeHtml(row.invoice_type || 'Invoice');
                const invoiceCategory = escapeHtml(row.invoice_category || 'room');
                const guestName = escapeHtml((row.guest_name || '').trim() || 'N/A');
                const itemName = escapeHtml(row.item_name || 'N/A');
                const dates = escapeHtml(row.booking_dates || '-');
                const amount = `$${Number(row.amount || 0).toFixed(2)}`;
                const paymentValue = String(row.payment_status || 'unpaid');
                const paymentLabel = normalizeStatusLabel(paymentValue);
                const bookingStatus = String(row.status || 'pending');
                const bookingLabel = normalizeStatusLabel(bookingStatus);
                const created = escapeHtml(row.created_at || '-');

                return `
                    <tr>
                        <td>${invoiceNo}</td>
                        <td><span class="invoice-type-badge invoice-type-${invoiceCategory}">${invoiceType}</span></td>
                        <td>${guestName}</td>
                        <td>${itemName}</td>
                        <td>${dates}</td>
                        <td>${amount}</td>
                        <td><span class="status-badge payment-${escapeHtml(paymentValue)}">${escapeHtml(paymentLabel)}</span></td>
                        <td><span class="status-badge status-${escapeHtml(bookingStatus)}">${escapeHtml(bookingLabel)}</span></td>
                        <td>${created}</td>
                    </tr>
                `;
            }).join('');

            makeTableResponsive();
            applyTableDataLabels(table);
        } catch (error) {
            console.error(error);
            tbody.innerHTML = '<tr><td colspan="9" class="text-center">Unable to load invoices.</td></tr>';
        }
    };

    openBtn.addEventListener('click', function (event) {
        event.preventDefault();
        openModal();
    });

    closeBtn.addEventListener('click', closeModal);

    document.addEventListener('click', function (event) {
        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });
}

function initServiceReservationModal() {
    const modal = document.getElementById('serviceReservationDetailsModal');
    const closeBtn = document.getElementById('serviceReservationModalClose');
    if (!modal) {
        return;
    }

    const setDetail = (id, value) => {
        const el = document.getElementById(id);
        if (el) {
            el.textContent = value || '-';
        }
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openModal = (button) => {
        setDetail('serviceDetailId', button.dataset.id || '-');
        setDetail('serviceDetailGuest', button.dataset.guest || '-');
        setDetail('serviceDetailService', button.dataset.service || '-');
        setDetail('serviceDetailDates', button.dataset.dates || '-');
        setDetail('serviceDetailGuests', button.dataset.guests || '-');
        setDetail('serviceDetailAmount', button.dataset.amount || '-');
        setDetail('serviceDetailPayment', button.dataset.payment || '-');
        setDetail('serviceDetailStatus', button.dataset.status || '-');
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
    };

    document.addEventListener('click', function (event) {
        const trigger = event.target.closest('.service-res-view-btn');
        if (trigger) {
            event.preventDefault();
            openModal(trigger);
            return;
        }

        if (event.target === modal || event.target.closest('#serviceReservationModalClose')) {
            closeModal();
        }
    });

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });
}

function initReservationModal() {
    const modal = document.getElementById('reservationDetailsModal');
    const closeBtn = document.getElementById('reservationModalClose');
    if (!modal) {
        return;
    }

    const setDetail = (id, value) => {
        const el = document.getElementById(id);
        if (el) {
            el.textContent = value || '-';
        }
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openModal = (button) => {
        setDetail('reservationDetailId', button.dataset.id || '-');
        setDetail('reservationDetailGuest', button.dataset.guest || '-');
        setDetail('reservationDetailRoom', button.dataset.room || '-');
        setDetail('reservationDetailDates', button.dataset.dates || '-');
        setDetail('reservationDetailAmount', button.dataset.amount || '-');
        setDetail('reservationDetailStatus', button.dataset.status || '-');
        setDetail('reservationDetailPayment', button.dataset.payment || '-');
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
    };

    document.addEventListener('click', function (event) {
        const trigger = event.target.closest('.reservation-view-btn');
        if (trigger) {
            event.preventDefault();
            openModal(trigger);
            return;
        }

        if (event.target === modal || event.target.closest('#reservationModalClose')) {
            closeModal();
        }
    });

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });
}

function initServiceCrud() {
    const modal = document.getElementById('serviceCrudModal');
    const openBtn = document.getElementById('addServiceBtn');
    const closeBtn = document.getElementById('serviceCrudModalClose');
    const cancelBtn = document.getElementById('serviceFormCancel');
    const form = document.getElementById('serviceCrudForm');
    const title = document.getElementById('serviceCrudModalTitle');
    const submitBtn = document.getElementById('serviceFormSubmit');
    const idField = document.getElementById('serviceFormId');
    const nameField = document.getElementById('serviceFormName');
    const descField = document.getElementById('serviceFormDescription');
    const iconField = document.getElementById('serviceFormIcon');
    const imageField = document.getElementById('serviceFormImage');
    const imageFileField = document.getElementById('serviceFormImageFile');
    const imagePreview = document.getElementById('serviceImagePreview');
    const statusField = document.getElementById('serviceFormStatus');

    if (!modal || !form || !title || !submitBtn || !idField || !nameField || !descField || !iconField || !imageField || !statusField || !imageFileField || !imagePreview) {
        return;
    }

    const getImageSource = (path) => {
        const cleanPath = String(path || '').trim();
        if (!cleanPath) {
            return 'images/facilities/1.webp';
        }
        return cleanPath;
    };

    const resetForm = () => {
        idField.value = '';
        nameField.value = '';
        descField.value = '';
        iconField.value = '';
        imageField.value = '';
        imageFileField.value = '';
        imagePreview.src = 'images/facilities/1.webp';
        statusField.value = '1';
        title.textContent = 'Add Service';
        submitBtn.textContent = 'Save Service';
    };

    const openModal = () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        nameField.focus();
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openAdd = () => {
        resetForm();
        openModal();
    };

    const openEdit = (button) => {
        idField.value = button.dataset.id || '';
        nameField.value = button.dataset.name || '';
        descField.value = button.dataset.description || '';
        iconField.value = button.dataset.icon || '';
        imageField.value = button.dataset.image || '';
        imageFileField.value = '';
        imagePreview.src = getImageSource(button.dataset.image || '');
        statusField.value = button.dataset.active === '1' ? '1' : '0';
        title.textContent = 'Edit Service';
        submitBtn.textContent = 'Update Service';
        openModal();
    };

    if (openBtn) {
        openBtn.addEventListener('click', function (event) {
            event.preventDefault();
            openAdd();
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('click', function (event) {
        const editTrigger = event.target.closest('.service-edit-btn');
        if (editTrigger) {
            event.preventDefault();
            openEdit(editTrigger);
            return;
        }

        const deleteTrigger = event.target.closest('.service-delete-btn');
        if (deleteTrigger) {
            event.preventDefault();
            const serviceId = deleteTrigger.dataset.id || '';
            if (!serviceId) {
                return;
            }

            const confirmDelete = confirm('Delete this service?');
            if (!confirmDelete) {
                return;
            }

            deleteTrigger.classList.add('is-updating');
            postAdminData('delete_service', { id: serviceId })
                .then(() => loadServices())
                .catch((error) => {
                    console.error(error);
                    alert('Unable to delete service right now.');
                })
                .finally(() => deleteTrigger.classList.remove('is-updating'));
            return;
        }

        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });

    imageField.addEventListener('input', function () {
        if (!imageFileField.files || imageFileField.files.length === 0) {
            imagePreview.src = getImageSource(imageField.value);
        }
    });

    imageFileField.addEventListener('change', function () {
        const file = imageFileField.files && imageFileField.files[0];
        if (!file) {
            imagePreview.src = getImageSource(imageField.value);
            return;
        }

        const localPreviewUrl = URL.createObjectURL(file);
        imagePreview.src = localPreviewUrl;
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const payload = new FormData();
        payload.append('name', nameField.value.trim());
        payload.append('description', descField.value.trim());
        payload.append('icon', iconField.value.trim());
        payload.append('image_url', imageField.value.trim());
        payload.append('is_active', statusField.value === '0' ? '0' : '1');

        if (!nameField.value.trim()) {
            alert('Service name is required.');
            nameField.focus();
            return;
        }

        const isEdit = idField.value.trim() !== '';
        if (isEdit) {
            payload.append('id', idField.value.trim());
        }

        const imageFile = imageFileField.files && imageFileField.files[0];
        if (imageFile) {
            payload.append('image_file', imageFile);
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');

        try {
            await postAdminData(isEdit ? 'update_service' : 'add_service', payload);
            const successMsg = isEdit ? 'Service updated successfully!' : 'Service added successfully!';
            showNotification(successMsg, 'success', 3000);
            closeModal();
            await loadServices();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save service right now.', 'error', 4000);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });
}

function initRoomCrud() {
    const modal = document.getElementById('roomCrudModal');
    const openBtn = document.getElementById('addRoomBtn');
    const closeBtn = document.getElementById('roomCrudModalClose');
    const cancelBtn = document.getElementById('roomFormCancel');
    const form = document.getElementById('roomCrudForm');
    const title = document.getElementById('roomCrudModalTitle');
    const submitBtn = document.getElementById('roomFormSubmit');

    const idField = document.getElementById('roomFormId');
    const numberField = document.getElementById('roomFormNumber');
    const typeField = document.getElementById('roomFormType');
    const guestsField = document.getElementById('roomFormGuests');
    const priceField = document.getElementById('roomFormPrice');
    const floorField = document.getElementById('roomFormFloor');
    const viewField = document.getElementById('roomFormView');
    const imageField = document.getElementById('roomFormImage');
    const imageFileField = document.getElementById('roomFormImageFile');
    const imagePreview = document.getElementById('roomImagePreview');
    const descriptionField = document.getElementById('roomFormDescription');
    const availableField = document.getElementById('roomFormAvailable');

    if (!modal || !form || !title || !submitBtn || !idField || !numberField || !typeField || !guestsField || !priceField || !floorField || !viewField || !imageField || !imageFileField || !imagePreview || !descriptionField || !availableField) {
        return;
    }

    const getImageSource = (path) => {
        const cleanPath = String(path || '').trim();
        if (!cleanPath) {
            return 'images/room/1.webp';
        }
        return cleanPath;
    };

    const resetForm = () => {
        idField.value = '';
        numberField.value = '';
        typeField.value = '';
        guestsField.value = '';
        priceField.value = '';
        floorField.value = '';
        viewField.value = '';
        imageField.value = 'images/room/1.webp';
        imageFileField.value = '';
        imagePreview.src = 'images/room/1.webp';
        descriptionField.value = '';
        availableField.value = '1';
        title.textContent = 'Add Room';
        submitBtn.textContent = 'Save Room';
    };

    const openModal = () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        numberField.focus();
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openAdd = () => {
        resetForm();
        openModal();
    };

    const openEdit = (button) => {
        idField.value = button.dataset.id || '';
        numberField.value = button.dataset.roomNumber || '';
        typeField.value = button.dataset.roomType || '';
        guestsField.value = button.dataset.maxGuests || '';
        priceField.value = button.dataset.price || '';
        floorField.value = button.dataset.floor || '';
        viewField.value = button.dataset.view || '';
        imageField.value = button.dataset.image || 'images/room/1.webp';
        imageFileField.value = '';
        imagePreview.src = getImageSource(button.dataset.image || '');
        descriptionField.value = button.dataset.description || '';
        availableField.value = button.dataset.available === '1' ? '1' : '0';
        title.textContent = 'Edit Room';
        submitBtn.textContent = 'Update Room';
        openModal();
    };

    if (openBtn) {
        openBtn.addEventListener('click', function (event) {
            event.preventDefault();
            openAdd();
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('click', function (event) {
        const editTrigger = event.target.closest('.room-edit-btn');
        if (editTrigger) {
            event.preventDefault();
            openEdit(editTrigger);
            return;
        }

        const deleteTrigger = event.target.closest('.room-delete-btn');
        if (deleteTrigger) {
            event.preventDefault();
            const roomId = deleteTrigger.dataset.id || '';
            if (!roomId) {
                return;
            }

            const confirmed = confirm('Delete this room?');
            if (!confirmed) {
                return;
            }

            deleteTrigger.classList.add('is-updating');
            postAdminData('delete_room', { id: roomId })
                .then(() => loadRooms())
                .catch((error) => {
                    console.error(error);
                    alert('Unable to delete room right now.');
                })
                .finally(() => deleteTrigger.classList.remove('is-updating'));
            return;
        }

        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });

    imageField.addEventListener('input', function () {
        if (!imageFileField.files || imageFileField.files.length === 0) {
            imagePreview.src = getImageSource(imageField.value);
        }
    });

    imageFileField.addEventListener('change', function () {
        const file = imageFileField.files && imageFileField.files[0];
        if (!file) {
            imagePreview.src = getImageSource(imageField.value);
            return;
        }

        const localPreviewUrl = URL.createObjectURL(file);
        imagePreview.src = localPreviewUrl;
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const payload = new FormData();
        payload.append('room_number', numberField.value.trim());
        payload.append('room_type', typeField.value.trim());
        payload.append('description', descriptionField.value.trim());
        payload.append('max_guests', guestsField.value.trim());
        payload.append('price_per_night', priceField.value.trim());
        payload.append('floor_number', floorField.value.trim());
        payload.append('view_type', viewField.value.trim());
        payload.append('image_url', imageField.value.trim());
        payload.append('is_available', availableField.value === '0' ? '0' : '1');

        if (!numberField.value.trim() || !typeField.value.trim() || !guestsField.value.trim() || !priceField.value.trim()) {
            alert('Room number, type, max guests, and price are required.');
            return;
        }

        const isEdit = idField.value.trim() !== '';
        if (isEdit) {
            payload.append('id', idField.value.trim());
        }

        const imageFile = imageFileField.files && imageFileField.files[0];
        if (imageFile) {
            payload.append('image_file', imageFile);
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');

        try {
            await postAdminData(isEdit ? 'update_room' : 'add_room', payload);
            const successMsg = isEdit ? 'Room updated successfully!' : 'Room added successfully!';
            showNotification(successMsg, 'success', 3000);
            closeModal();
            await loadRooms();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save room right now.', 'error', 4000);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });
}

function initGalleryCrud() {
    const modal = document.getElementById('galleryCrudModal');
    const openBtn = document.getElementById('addGalleryBtn');
    const closeBtn = document.getElementById('galleryCrudModalClose');
    const cancelBtn = document.getElementById('galleryFormCancel');
    const form = document.getElementById('galleryCrudForm');
    const title = document.getElementById('galleryCrudModalTitle');
    const submitBtn = document.getElementById('galleryFormSubmit');

    const idField = document.getElementById('galleryFormId');
    const titleField = document.getElementById('galleryFormTitle');
    const categoryField = document.getElementById('galleryFormCategory');
    const descriptionField = document.getElementById('galleryFormDescription');
    const imageField = document.getElementById('galleryFormImage');
    const imageFileField = document.getElementById('galleryFormImageFile');
    const imagePreview = document.getElementById('galleryImagePreview');
    const sortField = document.getElementById('galleryFormSortOrder');
    const featuredField = document.getElementById('galleryFormFeatured');

    if (!modal || !form || !title || !submitBtn || !idField || !titleField || !categoryField || !descriptionField || !imageField || !imageFileField || !imagePreview || !sortField || !featuredField) {
        return;
    }

    const getImageSource = (path) => {
        const cleanPath = String(path || '').trim();
        return cleanPath || 'images/gallery/1.webp';
    };

    const resetForm = () => {
        idField.value = '';
        titleField.value = '';
        categoryField.value = '';
        descriptionField.value = '';
        imageField.value = 'images/gallery/1.webp';
        imageFileField.value = '';
        imagePreview.src = 'images/gallery/1.webp';
        sortField.value = '0';
        featuredField.value = '0';
        title.textContent = 'Add Gallery Image';
        submitBtn.textContent = 'Save Image';
    };

    const openModal = () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        titleField.focus();
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openAdd = () => {
        resetForm();
        openModal();
    };

    const openEdit = (button) => {
        idField.value = button.dataset.id || '';
        titleField.value = button.dataset.title || '';
        categoryField.value = button.dataset.category || '';
        descriptionField.value = button.dataset.description || '';
        imageField.value = button.dataset.image || 'images/gallery/1.webp';
        imageFileField.value = '';
        imagePreview.src = getImageSource(button.dataset.image || '');
        sortField.value = button.dataset.sortOrder || '0';
        featuredField.value = button.dataset.featured === '1' ? '1' : '0';
        title.textContent = 'Edit Gallery Image';
        submitBtn.textContent = 'Update Image';
        openModal();
    };

    if (openBtn) {
        openBtn.addEventListener('click', function (event) {
            event.preventDefault();
            openAdd();
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('click', function (event) {
        const editTrigger = event.target.closest('.gallery-edit-btn');
        if (editTrigger) {
            event.preventDefault();
            openEdit(editTrigger);
            return;
        }

        const deleteTrigger = event.target.closest('.gallery-delete-btn');
        if (deleteTrigger) {
            event.preventDefault();
            const galleryId = deleteTrigger.dataset.id || '';
            if (!galleryId) {
                return;
            }

            const confirmed = confirm('Delete this gallery item?');
            if (!confirmed) {
                return;
            }

            deleteTrigger.classList.add('is-updating');
            postAdminData('delete_gallery', { id: galleryId })
                .then(() => loadGallery())
                .catch((error) => {
                    console.error(error);
                    alert(error.message || 'Unable to delete gallery item right now.');
                })
                .finally(() => deleteTrigger.classList.remove('is-updating'));
            return;
        }

        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });

    imageField.addEventListener('input', function () {
        if (!imageFileField.files || imageFileField.files.length === 0) {
            imagePreview.src = getImageSource(imageField.value);
        }
    });

    imageFileField.addEventListener('change', function () {
        const file = imageFileField.files && imageFileField.files[0];
        if (!file) {
            imagePreview.src = getImageSource(imageField.value);
            return;
        }

        imagePreview.src = URL.createObjectURL(file);
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const payload = new FormData();
        payload.append('title', titleField.value.trim());
        payload.append('category', categoryField.value.trim());
        payload.append('description', descriptionField.value.trim());
        payload.append('image_url', imageField.value.trim());
        payload.append('sort_order', sortField.value.trim() || '0');
        payload.append('is_featured', featuredField.value === '1' ? '1' : '0');

        if (!titleField.value.trim()) {
            alert('Gallery title is required.');
            titleField.focus();
            return;
        }

        const isEdit = idField.value.trim() !== '';
        if (isEdit) {
            payload.append('id', idField.value.trim());
        }

        const imageFile = imageFileField.files && imageFileField.files[0];
        if (imageFile) {
            payload.append('image_file', imageFile);
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');

        try {
            await postAdminData(isEdit ? 'update_gallery' : 'add_gallery', payload);
            const successMsg = isEdit ? 'Gallery item updated successfully!' : 'Gallery item added successfully!';
            showNotification(successMsg, 'success', 3000);
            closeModal();
            await loadGallery();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save gallery item right now.', 'error', 4000);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });
}

function initNewsCrud() {
    const modal = document.getElementById('newsCrudModal');
    const openBtn = document.getElementById('addNewsBtn');
    const closeBtn = document.getElementById('newsCrudModalClose');
    const cancelBtn = document.getElementById('newsFormCancel');
    const form = document.getElementById('newsCrudForm');
    const titleEl = document.getElementById('newsCrudModalTitle');
    const submitBtn = document.getElementById('newsFormSubmit');

    const idField = document.getElementById('newsFormId');
    const titleField = document.getElementById('newsFormTitle');
    const summaryField = document.getElementById('newsFormSummary');
    const contentField = document.getElementById('newsFormContent');
    const imageField = document.getElementById('newsFormImage');
    const imageFileField = document.getElementById('newsFormImageFile');
    const imagePreview = document.getElementById('newsImagePreview');
    const statusField = document.getElementById('newsFormStatus');

    if (!modal || !form || !titleEl || !submitBtn || !idField || !titleField || !summaryField || !contentField || !imageField || !imageFileField || !imagePreview || !statusField) {
        return;
    }

    const getImageSource = (path) => {
        const cleanPath = String(path || '').trim();
        return cleanPath || 'images/news/1.webp';
    };

    const resetForm = () => {
        idField.value = '';
        titleField.value = '';
        summaryField.value = '';
        contentField.value = '';
        imageField.value = 'images/news/1.webp';
        imageFileField.value = '';
        imagePreview.src = 'images/news/1.webp';
        statusField.value = 'draft';
        titleEl.textContent = 'Add News';
        submitBtn.textContent = 'Save News';
    };

    const openModal = () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        titleField.focus();
    };

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const openAdd = () => {
        resetForm();
        openModal();
    };

    const openEdit = (button) => {
        idField.value = button.dataset.id || '';
        titleField.value = button.dataset.title || '';
        summaryField.value = button.dataset.summary || '';
        contentField.value = button.dataset.content || '';
        imageField.value = button.dataset.image || 'images/news/1.webp';
        imageFileField.value = '';
        imagePreview.src = getImageSource(button.dataset.image || '');
        statusField.value = button.dataset.status || 'draft';
        titleEl.textContent = 'Edit News';
        submitBtn.textContent = 'Update News';
        openModal();
    };

    if (openBtn) {
        openBtn.addEventListener('click', function (event) {
            event.preventDefault();
            openAdd();
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('click', function (event) {
        const editTrigger = event.target.closest('.news-edit-btn');
        if (editTrigger) {
            event.preventDefault();
            openEdit(editTrigger);
            return;
        }

        const deleteTrigger = event.target.closest('.news-delete-btn');
        if (deleteTrigger) {
            event.preventDefault();
            const newsId = deleteTrigger.dataset.id || '';
            if (!newsId) {
                return;
            }

            const confirmed = confirm('Delete this news item?');
            if (!confirmed) {
                return;
            }

            deleteTrigger.classList.add('is-updating');
            postAdminData('delete_news', { id: newsId })
                .then(() => loadNews())
                .catch((error) => {
                    console.error(error);
                    alert(error.message || 'Unable to delete news right now.');
                })
                .finally(() => deleteTrigger.classList.remove('is-updating'));
            return;
        }

        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });

    imageField.addEventListener('input', function () {
        if (!imageFileField.files || imageFileField.files.length === 0) {
            imagePreview.src = getImageSource(imageField.value);
        }
    });

    imageFileField.addEventListener('change', function () {
        const file = imageFileField.files && imageFileField.files[0];
        if (!file) {
            imagePreview.src = getImageSource(imageField.value);
            return;
        }
        imagePreview.src = URL.createObjectURL(file);
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const payload = new FormData();
        payload.append('title', titleField.value.trim());
        payload.append('summary', summaryField.value.trim());
        payload.append('content', contentField.value.trim());
        payload.append('featured_image', imageField.value.trim());
        payload.append('status', statusField.value || 'draft');

        if (!titleField.value.trim() || !contentField.value.trim()) {
            alert('Title and content are required.');
            return;
        }

        const isEdit = idField.value.trim() !== '';
        if (isEdit) {
            payload.append('id', idField.value.trim());
        }

        const imageFile = imageFileField.files && imageFileField.files[0];
        if (imageFile) {
            payload.append('image_file', imageFile);
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');

        try {
            await postAdminData(isEdit ? 'update_news' : 'add_news', payload);
            const successMsg = isEdit ? 'News updated successfully!' : 'News added successfully!';
            showNotification(successMsg, 'success', 3000);
            closeModal();
            await loadNews();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save news right now.', 'error', 4000);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });
}

function initOfferCrud() {
    const modal = document.getElementById('offerCrudModal');
    const openBtn = document.getElementById('addOfferBtn');
    const closeBtn = document.getElementById('offerCrudModalClose');
    const cancelBtn = document.getElementById('offerFormCancel');
    const form = document.getElementById('offerCrudForm');
    const titleEl = document.getElementById('offerCrudModalTitle');
    const submitBtn = document.getElementById('offerFormSubmit');

    const idField = document.getElementById('offerFormId');
    const titleField = document.getElementById('offerFormTitle');
    const descriptionField = document.getElementById('offerFormDescription');
    const discountTypeField = document.getElementById('offerFormDiscountType');
    const discountValueField = document.getElementById('offerFormDiscountValue');
    const startDateField = document.getElementById('offerFormStartDate');
    const endDateField = document.getElementById('offerFormEndDate');
    const statusField = document.getElementById('offerFormStatus');
    const maxRedemptionsField = document.getElementById('offerFormMaxRedemptions');

    if (!modal || !form || !titleEl || !submitBtn || !idField || !titleField || !descriptionField || !discountTypeField || !discountValueField || !startDateField || !endDateField || !statusField || !maxRedemptionsField) {
        return;
    }

    const closeModal = () => {
        modal.classList.remove('open');
        modal.setAttribute('aria-hidden', 'true');
    };

    const resetForm = () => {
        idField.value = '';
        titleField.value = '';
        descriptionField.value = '';
        discountTypeField.value = 'percentage';
        discountValueField.value = '';
        startDateField.value = '';
        endDateField.value = '';
        statusField.value = '1';
        maxRedemptionsField.value = '';
        titleEl.textContent = 'Add Offer';
        submitBtn.textContent = 'Save Offer';
    };

    const openModal = () => {
        modal.classList.add('open');
        modal.setAttribute('aria-hidden', 'false');
        titleField.focus();
    };

    const openAdd = () => {
        resetForm();
        openModal();
    };

    const openEdit = (button) => {
        idField.value = button.dataset.id || '';
        titleField.value = button.dataset.title || '';
        descriptionField.value = button.dataset.description || '';
        discountTypeField.value = button.dataset.discountType || 'percentage';
        discountValueField.value = button.dataset.discountValue || '';
        startDateField.value = button.dataset.startDate || '';
        endDateField.value = button.dataset.endDate || '';
        statusField.value = button.dataset.active === '1' ? '1' : '0';
        maxRedemptionsField.value = button.dataset.maxRedemptions || '';
        titleEl.textContent = 'Edit Offer';
        submitBtn.textContent = 'Update Offer';
        openModal();
    };

    if (openBtn) {
        openBtn.addEventListener('click', function (event) {
            event.preventDefault();
            openAdd();
        });
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeModal);
    }

    document.addEventListener('click', function (event) {
        const editTrigger = event.target.closest('.offer-edit-btn');
        if (editTrigger) {
            event.preventDefault();
            openEdit(editTrigger);
            return;
        }

        const deleteTrigger = event.target.closest('.offer-delete-btn');
        if (deleteTrigger) {
            event.preventDefault();
            const offerId = deleteTrigger.dataset.id || '';
            if (!offerId) {
                return;
            }

            const confirmed = confirm('Delete this offer?');
            if (!confirmed) {
                return;
            }

            deleteTrigger.classList.add('is-updating');
            postAdminData('delete_offer', { id: offerId })
                .then(() => loadOffers())
                .catch((error) => {
                    console.error(error);
                    alert(error.message || 'Unable to delete offer right now.');
                })
                .finally(() => deleteTrigger.classList.remove('is-updating'));
            return;
        }

        if (event.target === modal) {
            closeModal();
        }
    });

    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && modal.classList.contains('open')) {
            closeModal();
        }
    });

    form.addEventListener('submit', async function (event) {
        event.preventDefault();

        const title = titleField.value.trim();
        const description = descriptionField.value.trim();
        const discountType = discountTypeField.value;
        const discountValue = discountValueField.value.trim();
        const startDate = startDateField.value;
        const endDate = endDateField.value;
        const isActive = statusField.value === '1' ? '1' : '0';
        const maxRedemptions = maxRedemptionsField.value.trim();

        if (!title || !discountValue || !startDate || !endDate) {
            alert('Title, discount value, start date, and end date are required.');
            return;
        }

        if (startDate > endDate) {
            alert('End date must be on or after start date.');
            return;
        }

        const payload = {
            title,
            description,
            discount_type: discountType,
            discount_value: discountValue,
            start_date: startDate,
            end_date: endDate,
            is_active: isActive,
            max_redemptions: maxRedemptions
        };

        const isEdit = idField.value.trim() !== '';
        if (isEdit) {
            payload.id = idField.value.trim();
        }

        submitBtn.disabled = true;
        submitBtn.classList.add('is-updating');

        try {
            await postAdminData(isEdit ? 'update_offer' : 'add_offer', payload);
            const successMsg = isEdit ? 'Offer updated successfully!' : 'Offer added successfully!';
            showNotification(successMsg, 'success', 3000);
            closeModal();
            await loadOffers();
        } catch (error) {
            console.error(error);
            showNotification(error.message || 'Unable to save offer right now.', 'error', 4000);
        } finally {
            submitBtn.disabled = false;
            submitBtn.classList.remove('is-updating');
        }
    });
}

function initServiceStatusActions() {
    document.addEventListener('click', function (event) {
        const unlockBtn = event.target.closest('.service-status-unlock-btn');
        if (!unlockBtn) {
            return;
        }

        const wrap = unlockBtn.closest('.service-status-wrap');
        const select = wrap ? wrap.querySelector('.service-status-select') : null;
        if (!select) {
            return;
        }

        const currentStatus = String(select.dataset.current || '').toLowerCase();
        if (currentStatus !== 'completed') {
            unlockBtn.classList.add('is-hidden');
            select.dataset.allowCompletedChange = '0';
            return;
        }

        const isUnlocking = !unlockBtn.classList.contains('is-active');
        if (isUnlocking) {
            unlockBtn.classList.add('is-active');
            unlockBtn.textContent = 'Lock';
            unlockBtn.setAttribute('aria-pressed', 'true');
            select.dataset.allowCompletedChange = '1';
            select.disabled = false;
            showNotification('Completed status unlocked. Choose a new status to update.', 'info', 2500);
            return;
        }

        unlockBtn.classList.remove('is-active');
        unlockBtn.textContent = 'Change';
        unlockBtn.setAttribute('aria-pressed', 'false');
        select.dataset.allowCompletedChange = '0';
        select.value = 'completed';
        select.disabled = true;
    });

    document.addEventListener('change', async function (event) {
        const select = event.target.closest('.service-status-select');
        if (!select) {
            return;
        }

        const id = select.dataset.id;
        const newStatus = select.value;
        const previousStatus = select.dataset.current || '';
        const allowCompletedChange = select.dataset.allowCompletedChange === '1';
        const badge = select.closest('.service-status-wrap')?.querySelector('.service-status-badge');
        const unlockBtn = select.closest('.service-status-wrap')?.querySelector('.service-status-unlock-btn');

        if (!id || !newStatus || newStatus === previousStatus) {
            return;
        }

        if (previousStatus === 'completed' && newStatus !== 'completed' && !allowCompletedChange) {
            select.value = previousStatus;
            showNotification('Completed status is locked. Click Change first.', 'info', 2800);
            return;
        }

        select.disabled = true;
        select.classList.add('is-updating');

        try {
            const payload = { id, status: newStatus };
            if (previousStatus === 'completed' && newStatus !== 'completed') {
                payload.allow_completed_change = allowCompletedChange ? '1' : '0';
            }

            await postAdminData('update_service_reservation_status', payload);
            select.dataset.current = newStatus;
            select.dataset.allowCompletedChange = '0';
            if (badge) {
                badge.className = `status-badge service-status-badge status-${escapeHtml(newStatus)}`;
                badge.textContent = normalizeStatusLabel(newStatus);
            }

            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (newStatus === 'completed') {
                    unlockBtn.classList.remove('is-hidden');
                    unlockBtn.textContent = 'Change';
                } else {
                    unlockBtn.classList.add('is-hidden');
                    unlockBtn.textContent = 'Change';
                }
            }
        } catch (error) {
            console.error(error);
            select.value = previousStatus;
            select.dataset.allowCompletedChange = '0';
            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.textContent = 'Change';
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (previousStatus === 'completed') {
                    unlockBtn.classList.remove('is-hidden');
                }
            }
            showNotification(error.message || 'Unable to update service reservation status right now.', 'error', 3500);
        } finally {
            const shouldLock = String(select.dataset.current || '').toLowerCase() === 'completed'
                && select.dataset.allowCompletedChange !== '1';
            select.disabled = shouldLock;
            select.classList.remove('is-updating');
        }
    });
}

function initServicePaymentActions() {
    document.addEventListener('click', function (event) {
        const unlockBtn = event.target.closest('.service-payment-unlock-btn');
        if (!unlockBtn) {
            return;
        }

        const wrap = unlockBtn.closest('.payment-status-wrap');
        const select = wrap ? wrap.querySelector('.service-res-payment-select') : null;
        if (!select) {
            return;
        }

        const currentStatus = String(select.dataset.current || '').toLowerCase();
        if (currentStatus !== 'paid') {
            unlockBtn.classList.add('is-hidden');
            select.dataset.allowPaidChange = '0';
            return;
        }

        const isUnlocking = !unlockBtn.classList.contains('is-active');
        if (isUnlocking) {
            unlockBtn.classList.add('is-active');
            unlockBtn.textContent = 'Lock';
            unlockBtn.setAttribute('aria-pressed', 'true');
            select.dataset.allowPaidChange = '1';
            select.disabled = false;
            showNotification('Paid payment status unlocked. Choose a new payment status to update.', 'info', 2500);
            return;
        }

        unlockBtn.classList.remove('is-active');
        unlockBtn.textContent = 'Change';
        unlockBtn.setAttribute('aria-pressed', 'false');
        select.dataset.allowPaidChange = '0';
        select.value = 'paid';
        select.disabled = true;
    });

    document.addEventListener('change', async function (event) {
        const select = event.target.closest('.service-res-payment-select');
        if (!select) {
            return;
        }

        const id = select.dataset.id;
        const newStatus = select.value;
        const previousStatus = select.dataset.current || '';
        const allowPaidChange = select.dataset.allowPaidChange === '1';
        const badge = select.closest('.payment-status-wrap')?.querySelector('.service-payment-status-badge');
        const unlockBtn = select.closest('.payment-status-wrap')?.querySelector('.service-payment-unlock-btn');

        if (!id || !newStatus || newStatus === previousStatus) {
            return;
        }

        if (previousStatus === 'paid' && newStatus !== 'paid' && !allowPaidChange) {
            select.value = previousStatus;
            showNotification('Paid payment status is locked. Click Change first.', 'info', 2800);
            return;
        }

        select.disabled = true;
        select.classList.add('is-updating');

        try {
            const payload = { id, payment_status: newStatus };
            if (previousStatus === 'paid' && newStatus !== 'paid') {
                payload.allow_paid_change = allowPaidChange ? '1' : '0';
            }
            await postAdminData('update_service_reservation_payment_status', payload);
            select.dataset.current = newStatus;
            select.dataset.allowPaidChange = '0';
            if (badge) {
                badge.className = `status-badge service-payment-status-badge payment-${escapeHtml(newStatus)}`;
                badge.textContent = normalizeStatusLabel(newStatus);
            }

            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (newStatus === 'paid') {
                    unlockBtn.classList.remove('is-hidden');
                    unlockBtn.textContent = 'Change';
                } else {
                    unlockBtn.classList.add('is-hidden');
                    unlockBtn.textContent = 'Change';
                }
            }
        } catch (error) {
            console.error(error);
            select.value = previousStatus;
            select.dataset.allowPaidChange = '0';
            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.textContent = 'Change';
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (previousStatus === 'paid') {
                    unlockBtn.classList.remove('is-hidden');
                }
            }
            showNotification(error.message || 'Unable to update service payment status right now.', 'error', 3500);
        } finally {
            const shouldLock = String(select.dataset.current || '').toLowerCase() === 'paid'
                && select.dataset.allowPaidChange !== '1';
            select.disabled = shouldLock;
            select.classList.remove('is-updating');
        }
    });
}

function initReservationStatusActions() {
    document.addEventListener('click', function (event) {
        const unlockBtn = event.target.closest('.reservation-status-unlock-btn');
        if (!unlockBtn) {
            return;
        }

        const wrap = unlockBtn.closest('.booking-status-wrap');
        const select = wrap ? wrap.querySelector('.reservation-status-select') : null;
        if (!select) {
            return;
        }

        const currentStatus = String(select.dataset.current || '').toLowerCase();
        if (currentStatus !== 'checked_out') {
            unlockBtn.classList.add('is-hidden');
            select.dataset.allowCheckoutChange = '0';
            return;
        }

        const isUnlocking = !unlockBtn.classList.contains('is-active');
        if (isUnlocking) {
            unlockBtn.classList.add('is-active');
            unlockBtn.textContent = 'Lock';
            unlockBtn.setAttribute('aria-pressed', 'true');
            select.dataset.allowCheckoutChange = '1';
            select.disabled = false;
            showNotification('Checked Out status unlocked. Choose a new status to update.', 'info', 2500);
            return;
        }

        unlockBtn.classList.remove('is-active');
        unlockBtn.textContent = 'Change';
        unlockBtn.setAttribute('aria-pressed', 'false');
        select.dataset.allowCheckoutChange = '0';
        select.value = 'checked_out';
        select.disabled = true;
    });

    document.addEventListener('change', async function (event) {
        const select = event.target.closest('.reservation-status-select');
        if (!select) {
            return;
        }

        const id = select.dataset.id;
        const newStatus = select.value;
        const previousStatus = select.dataset.current || '';
        const allowCheckoutChange = select.dataset.allowCheckoutChange === '1';
        const badge = select.closest('.booking-status-wrap')?.querySelector('.booking-status-badge');
        const unlockBtn = select.closest('.booking-status-wrap')?.querySelector('.reservation-status-unlock-btn');

        if (!id || !newStatus || newStatus === previousStatus) {
            return;
        }

        if (previousStatus === 'checked_out' && newStatus !== 'checked_out' && !allowCheckoutChange) {
            select.value = previousStatus;
            showNotification('Checked Out status is locked. Click Change first.', 'info', 2800);
            return;
        }

        select.disabled = true;
        select.classList.add('is-updating');

        try {
            const payload = { id, status: newStatus };
            if (previousStatus === 'checked_out' && newStatus !== 'checked_out') {
                payload.allow_checkout_change = allowCheckoutChange ? '1' : '0';
            }

            await postAdminData('update_reservation_status', payload);
            select.dataset.current = newStatus;
            select.dataset.allowCheckoutChange = '0';
            if (badge) {
                badge.className = `status-badge booking-status-badge status-${escapeHtml(newStatus)}`;
                badge.textContent = normalizeStatusLabel(newStatus);
            }

            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (newStatus === 'checked_out') {
                    unlockBtn.classList.remove('is-hidden');
                    unlockBtn.textContent = 'Change';
                } else {
                    unlockBtn.classList.add('is-hidden');
                    unlockBtn.textContent = 'Change';
                }
            }
        } catch (error) {
            console.error(error);
            select.value = previousStatus;
            select.dataset.allowCheckoutChange = '0';
            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.textContent = 'Change';
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (previousStatus === 'checked_out') {
                    unlockBtn.classList.remove('is-hidden');
                }
            }
            showNotification(error.message || 'Unable to update reservation status right now.', 'error', 3500);
        } finally {
            const shouldLock = String(select.dataset.current || '').toLowerCase() === 'checked_out'
                && select.dataset.allowCheckoutChange !== '1';
            select.disabled = shouldLock;
            select.classList.remove('is-updating');
        }
    });
}

function initReservationPaymentActions() {
    document.addEventListener('click', function (event) {
        const unlockBtn = event.target.closest('.reservation-payment-unlock-btn');
        if (!unlockBtn) {
            return;
        }

        const wrap = unlockBtn.closest('.payment-status-wrap');
        const select = wrap ? wrap.querySelector('.reservation-payment-select') : null;
        if (!select) {
            return;
        }

        const currentStatus = String(select.dataset.current || '').toLowerCase();
        if (currentStatus !== 'paid') {
            unlockBtn.classList.add('is-hidden');
            select.dataset.allowPaidChange = '0';
            return;
        }

        const isUnlocking = !unlockBtn.classList.contains('is-active');
        if (isUnlocking) {
            unlockBtn.classList.add('is-active');
            unlockBtn.textContent = 'Lock';
            unlockBtn.setAttribute('aria-pressed', 'true');
            select.dataset.allowPaidChange = '1';
            select.disabled = false;
            showNotification('Paid payment status unlocked. Choose a new payment status to update.', 'info', 2500);
            return;
        }

        unlockBtn.classList.remove('is-active');
        unlockBtn.textContent = 'Change';
        unlockBtn.setAttribute('aria-pressed', 'false');
        select.dataset.allowPaidChange = '0';
        select.value = 'paid';
        select.disabled = true;
    });

    document.addEventListener('change', async function (event) {
        const select = event.target.closest('.reservation-payment-select');
        if (!select) {
            return;
        }

        const id = select.dataset.id;
        const newStatus = select.value;
        const previousStatus = select.dataset.current || '';
        const allowPaidChange = select.dataset.allowPaidChange === '1';
        const badge = select.closest('.payment-status-wrap')?.querySelector('.payment-status-badge');
        const unlockBtn = select.closest('.payment-status-wrap')?.querySelector('.reservation-payment-unlock-btn');

        if (!id || !newStatus || newStatus === previousStatus) {
            return;
        }

        if (previousStatus === 'paid' && newStatus !== 'paid' && !allowPaidChange) {
            select.value = previousStatus;
            showNotification('Paid payment status is locked. Click Change first.', 'info', 2800);
            return;
        }

        select.disabled = true;
        select.classList.add('is-updating');

        try {
            const payload = { id, payment_status: newStatus };
            if (previousStatus === 'paid' && newStatus !== 'paid') {
                payload.allow_paid_change = allowPaidChange ? '1' : '0';
            }
            await postAdminData('update_reservation_payment_status', payload);
            select.dataset.current = newStatus;
            select.dataset.allowPaidChange = '0';
            if (badge) {
                badge.className = `status-badge payment-status-badge payment-${escapeHtml(newStatus)}`;
                badge.textContent = normalizeStatusLabel(newStatus);
            }

            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (newStatus === 'paid') {
                    unlockBtn.classList.remove('is-hidden');
                    unlockBtn.textContent = 'Change';
                } else {
                    unlockBtn.classList.add('is-hidden');
                    unlockBtn.textContent = 'Change';
                }
            }
        } catch (error) {
            console.error(error);
            select.value = previousStatus;
            select.dataset.allowPaidChange = '0';
            if (unlockBtn) {
                unlockBtn.classList.remove('is-active');
                unlockBtn.textContent = 'Change';
                unlockBtn.setAttribute('aria-pressed', 'false');
                if (previousStatus === 'paid') {
                    unlockBtn.classList.remove('is-hidden');
                }
            }
            showNotification(error.message || 'Unable to update payment status right now.', 'error', 3500);
        } finally {
            const shouldLock = String(select.dataset.current || '').toLowerCase() === 'paid'
                && select.dataset.allowPaidChange !== '1';
            select.disabled = shouldLock;
            select.classList.remove('is-updating');
        }
    });
}

function startServiceReservationsLiveRefresh() {
    stopServiceReservationsLiveRefresh();
    serviceReservationsRefreshTimer = setInterval(() => {
        const content = document.querySelector('.admin-content');
        if (!content || content.dataset.activeSection !== 'service-reservations') {
            stopServiceReservationsLiveRefresh();
            return;
        }

        const hasUpdatingRow = document.querySelector('.service-status-select.is-updating, .service-res-payment-select.is-updating');
        if (!hasUpdatingRow) {
            loadServiceReservations(getServiceReservationFilters());
        }
    }, 15000);
}

function stopServiceReservationsLiveRefresh() {
    if (serviceReservationsRefreshTimer) {
        clearInterval(serviceReservationsRefreshTimer);
        serviceReservationsRefreshTimer = null;
    }
}

function startReservationsLiveRefresh() {
    stopReservationsLiveRefresh();
    reservationsRefreshTimer = setInterval(() => {
        const content = document.querySelector('.admin-content');
        if (!content || content.dataset.activeSection !== 'reservations') {
            stopReservationsLiveRefresh();
            return;
        }

        const hasUpdatingRow = document.querySelector('.reservation-status-select.is-updating');
        if (!hasUpdatingRow) {
            loadReservations(getReservationFilters());
        }
    }, 15000);
}

function stopReservationsLiveRefresh() {
    if (reservationsRefreshTimer) {
        clearInterval(reservationsRefreshTimer);
        reservationsRefreshTimer = null;
    }
}

function startOffersLiveRefresh() {
    stopOffersLiveRefresh();
    offersRefreshTimer = setInterval(() => {
        const content = document.querySelector('.admin-content');
        if (!content || content.dataset.activeSection !== 'offers') {
            stopOffersLiveRefresh();
            return;
        }

        if (!document.querySelector('#offerCrudModal.open')) {
            loadOffers();
        }
    }, 15000);
}

function stopOffersLiveRefresh() {
    if (offersRefreshTimer) {
        clearInterval(offersRefreshTimer);
        offersRefreshTimer = null;
    }
}

async function loadGuests(search = '') {
    const tbody = document.getElementById('guestsTableBody');
    const table = document.getElementById('guestsTable');
    if (!tbody || !table) {
        return;
    }

    tbody.innerHTML = '<tr><td colspan="7" class="text-center">Loading guest data...</td></tr>';

    try {
        const params = search ? { search } : {};
        const result = await fetchAdminData('get_guests', params);
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            tbody.innerHTML = '<tr><td colspan="7" class="text-center">No guests found.</td></tr>';
            makeTableResponsive();
            return;
        }

        tbody.innerHTML = rows.map(row => {
            const name = `${escapeHtml(row.first_name || '')} ${escapeHtml(row.last_name || '')}`.trim() || 'N/A';
            const email = escapeHtml(row.email || 'N/A');
            const phone = escapeHtml(row.phone || 'N/A');
            const reservationCount = Number(row.reservation_count || 0);
            const joinDate = escapeHtml(row.created_at ? String(row.created_at).split(' ')[0] : '-');
            const isActive = Number(row.is_active) === 1 || row.is_active === true || row.is_active === '1';
            const statusText = isActive ? 'Active' : 'Inactive';
            const statusClass = isActive ? 'confirmed' : 'cancelled';

            return `
                <tr>
                    <td>${name}</td>
                    <td>${email}</td>
                    <td>${phone}</td>
                    <td>${reservationCount}</td>
                    <td>${joinDate}</td>
                    <td><span class="status-badge status-${statusClass}">${statusText}</span></td>
                    <td>
                        <a href="#"
                           class="action-link action-btn guest-view-btn"
                           title="View Details"
                           data-name="${safeDataValue(name)}"
                           data-email="${safeDataValue(email)}"
                           data-phone="${safeDataValue(phone)}"
                           data-reservations="${safeDataValue(reservationCount)}"
                           data-join-date="${safeDataValue(joinDate)}"
                           data-status="${safeDataValue(statusText)}">
                            <i class="fa fa-eye"></i>
                        </a>
                    </td>
                </tr>
            `;
        }).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
    } catch (error) {
        console.error(error);
        tbody.innerHTML = '<tr><td colspan="7" class="text-center">Unable to load guest data.</td></tr>';
    }
}

function escapeHtml(value) {
    return String(value ?? '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

function normalizeStatusLabel(status) {
    return String(status || '')
        .replace(/_/g, ' ')
        .replace(/\b\w/g, c => c.toUpperCase());
}

async function loadReservations(filters = {}) {
    const tbody = document.getElementById('reservationsTableBody');
    const table = document.getElementById('reservationsTable');
    if (!tbody || !table) {
        return;
    }

    tbody.innerHTML = '<tr><td colspan="8" class="text-center">Loading reservation data...</td></tr>';

    try {
        const resolvedFilters = typeof filters === 'string'
            ? { status: filters }
            : (filters && typeof filters === 'object' ? filters : {});
        const params = {};
        if (resolvedFilters.status) params.status = resolvedFilters.status;
        if (resolvedFilters.guest) params.guest = resolvedFilters.guest;
        if (resolvedFilters.room) params.room = resolvedFilters.room;
        const result = await fetchAdminData('get_reservations', params);
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            tbody.innerHTML = '<tr><td colspan="8" class="text-center">No reservations found.</td></tr>';
            makeTableResponsive();
            return;
        }

        tbody.innerHTML = rows.map(row => {
            const id = row.id ? `#${escapeHtml(row.id)}` : '-';
            const guestName = `${escapeHtml(row.first_name || '')} ${escapeHtml(row.last_name || '')}`.trim() || escapeHtml(row.email || 'N/A');
            const room = row.room_number
                ? `${escapeHtml(row.room_number)} (${escapeHtml(String(row.room_type || '').toUpperCase())})`
                : 'N/A';
            const dates = `${escapeHtml(row.check_in_date || '-')} to ${escapeHtml(row.check_out_date || '-')}`;
            const amount = row.total_price !== null && typeof row.total_price !== 'undefined'
                ? `$${Number(row.total_price).toFixed(2)}`
                : '$0.00';
            const statusValue = String(row.status || 'pending');
            const statusLabel = normalizeStatusLabel(statusValue);
            const isCheckedOutLocked = statusValue === 'checked_out';
            const statusOptions = ['pending', 'confirmed', 'checked_in', 'checked_out', 'cancelled']
                .map(status => `<option value="${status}" ${status === statusValue ? 'selected' : ''}>${normalizeStatusLabel(status)}</option>`)
                .join('');
            const paymentValue = String(row.payment_status || 'unpaid');
            const paymentLabel = normalizeStatusLabel(paymentValue);
            const isPaidLocked = paymentValue === 'paid';
            const paymentOptions = ['unpaid', 'partial', 'paid']
                .map(pay => `<option value="${pay}" ${pay === paymentValue ? 'selected' : ''}>${normalizeStatusLabel(pay)}</option>`)
                .join('');

            return `
                <tr>
                    <td>${id}</td>
                    <td>${guestName}</td>
                    <td>${room}</td>
                    <td>${dates}</td>
                    <td>${amount}</td>
                    <td>
                        <div class="payment-status-wrap ${isPaidLocked ? 'is-locked' : ''}">
                            <div class="reservation-payment-control-row">
                            <select class="reservation-payment-select"
                                    data-id="${safeDataValue(row.id || '')}"
                                    data-current="${safeDataValue(paymentValue)}"
                                    data-allow-paid-change="0"
                                    ${isPaidLocked ? 'disabled' : ''}
                                    aria-label="Update payment status">
                                ${paymentOptions}
                            </select>
                            <button type="button"
                                    class="reservation-payment-unlock-btn ${isPaidLocked ? '' : 'is-hidden'}"
                                    aria-pressed="false"
                                    title="Unlock paid status to change">
                                Change
                            </button>
                            </div>
                            <span class="status-badge payment-status-badge payment-${escapeHtml(paymentValue)}">${escapeHtml(paymentLabel)}</span>
                        </div>
                    </td>
                    <td>
                        <div class="booking-status-wrap ${isCheckedOutLocked ? 'is-locked' : ''}">
                            <div class="booking-status-control-row">
                            <select class="reservation-status-select"
                                    data-id="${safeDataValue(row.id || '')}"
                                    data-current="${safeDataValue(statusValue)}"
                                    data-allow-checkout-change="0"
                                    ${isCheckedOutLocked ? 'disabled' : ''}
                                    aria-label="Update room reservation status">
                                ${statusOptions}
                            </select>
                            <button type="button"
                                    class="reservation-status-unlock-btn ${isCheckedOutLocked ? '' : 'is-hidden'}"
                                    aria-pressed="false"
                                    title="Unlock checked out status to change">
                                Change
                            </button>
                            </div>
                            <span class="status-badge booking-status-badge status-${escapeHtml(statusValue)}">${escapeHtml(statusLabel)}</span>
                        </div>
                    </td>
                    <td>
                        <a href="#"
                           class="action-link action-btn reservation-view-btn"
                           title="View Details"
                           data-id="${safeDataValue(id)}"
                           data-guest="${safeDataValue(guestName)}"
                           data-room="${safeDataValue(room)}"
                           data-dates="${safeDataValue(dates)}"
                           data-amount="${safeDataValue(amount)}"
                           data-status="${safeDataValue(statusLabel)}"
                           data-payment="${safeDataValue(paymentLabel)}">
                            <i class="fa fa-eye"></i>
                        </a>
                    </td>
                </tr>
            `;
        }).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
    } catch (error) {
        console.error(error);
        tbody.innerHTML = '<tr><td colspan="8" class="text-center">Unable to load reservation data.</td></tr>';
    }
}

async function loadRooms() {
    const grid = document.getElementById('roomsGrid');
    if (!grid) {
        return;
    }

    grid.innerHTML = `
        <div class="room-card">
            <div class="room-info">
                <h4>Loading rooms...</h4>
                <p class="room-number">Please wait</p>
            </div>
        </div>
    `;

    try {
        const result = await fetchAdminData('get_rooms');
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            grid.innerHTML = `
                <div class="room-card">
                    <div class="room-info">
                        <h4>No rooms found</h4>
                        <p class="room-number">Add your first room to get started.</p>
                    </div>
                </div>
            `;
            return;
        }

        grid.innerHTML = rows.map(row => {
            const roomId = safeDataValue(row.id || '');
            const roomType = escapeHtml(row.room_type || 'Room');
            const roomNumber = escapeHtml(row.room_number || 'N/A');
            const maxGuests = Number(row.max_guests || 0);
            const viewType = escapeHtml(row.view_type || 'Standard View');
            const description = escapeHtml(row.description || 'Comfortable room with essential amenities.');
            const image = escapeHtml(row.image_url || 'images/misc/1.jpg');
            const price = row.price_per_night !== null && typeof row.price_per_night !== 'undefined'
                ? `$${Number(row.price_per_night).toFixed(2)}/night`
                : '$0.00/night';
            const priceRaw = row.price_per_night !== null && typeof row.price_per_night !== 'undefined'
                ? Number(row.price_per_night).toFixed(2)
                : '0.00';
            const floorRaw = row.floor_number !== null && typeof row.floor_number !== 'undefined'
                ? String(row.floor_number)
                : '';
            const viewRaw = row.view_type || '';
            const imageRaw = row.image_url || '';
            const descRaw = row.description || '';

            let isAvailable = true;
            if (typeof row.is_available !== 'undefined' && row.is_available !== null) {
                isAvailable = Number(row.is_available) === 1 || row.is_available === true || row.is_available === '1';
            } else if (typeof row.status !== 'undefined') {
                isAvailable = String(row.status).toLowerCase() === 'available';
            }

            const statusClass = isAvailable ? 'available' : 'occupied';
            const statusText = isAvailable ? 'Available' : 'Unavailable';
            const availableRaw = isAvailable ? '1' : '0';

            return `
                <div class="room-card">
                    <div class="room-preview">
                        <img src="${image}" alt="${roomType}">
                    </div>
                    <div class="room-info">
                        <h4>${roomType}</h4>
                        <p class="room-number">Room #${roomNumber}</p>
                        <div class="room-details">
                            <span class="detail"><i class="fa fa-users"></i> ${maxGuests || 0} Guests</span>
                            <span class="detail"><i class="fa fa-window-maximize"></i> ${viewType}</span>
                        </div>
                        <p class="room-description">${description}</p>
                        <p class="room-price">${price}</p>
                        <div class="room-status-row">
                            <div class="room-status ${statusClass}">${statusText}</div>
                            <div class="room-action-group">
                                <a href="#"
                                   class="action-link action-btn room-edit-btn"
                                   title="Edit Room"
                                   data-id="${roomId}"
                                   data-room-number="${safeDataValue(row.room_number || '')}"
                                   data-room-type="${safeDataValue(row.room_type || '')}"
                                   data-max-guests="${safeDataValue(maxGuests)}"
                                   data-price="${safeDataValue(priceRaw)}"
                                   data-floor="${safeDataValue(floorRaw)}"
                                   data-view="${safeDataValue(viewRaw)}"
                                   data-image="${safeDataValue(imageRaw)}"
                                   data-description="${safeDataValue(descRaw)}"
                                   data-available="${availableRaw}">
                                    <i class="fa fa-pencil"></i>
                                </a>
                                <a href="#"
                                   class="action-link action-btn room-delete-btn"
                                   title="Delete Room"
                                   data-id="${roomId}">
                                    <i class="fa fa-trash"></i>
                                </a>
                            </div>
                        </div>
                    </div>
                </div>
            `;
        }).join('');
    } catch (error) {
        console.error(error);
        grid.innerHTML = `
            <div class="room-card">
                <div class="room-info">
                    <h4>Unable to load rooms</h4>
                    <p class="room-number">Please try again.</p>
                </div>
            </div>
        `;
    }
}

async function loadGallery() {
    const grid = document.getElementById('galleryGrid');
    if (!grid) {
        return;
    }

    grid.innerHTML = `
        <div class="gallery-admin-card">
            <div class="gallery-admin-body">
                <h4>Loading gallery...</h4>
                <p>Please wait</p>
            </div>
        </div>
    `;

    try {
        const result = await fetchAdminData('get_gallery');
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            grid.innerHTML = `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-body">
                        <h4>No gallery items found</h4>
                        <p>Add your first gallery image.</p>
                    </div>
                </div>
            `;
            return;
        }

        grid.innerHTML = rows.map(row => {
            const id = safeDataValue(row.id || '');
            const title = escapeHtml(row.title || 'Gallery Image');
            const description = escapeHtml(row.description || 'No description.');
            const category = escapeHtml(row.category || 'General');
            const image = escapeHtml(row.image_url || 'images/gallery/1.webp');
            const sortOrder = safeDataValue(row.sort_order ?? 0);
            const isFeatured = Number(row.is_featured || 0) === 1;
            const featuredText = isFeatured ? 'Featured' : 'Standard';
            const featuredClass = isFeatured ? 'featured' : 'standard';
            const featuredRaw = isFeatured ? '1' : '0';

            return `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-media">
                        <img src="${image}" alt="${title}">
                        <span class="gallery-admin-badge ${featuredClass}">${featuredText}</span>
                    </div>
                    <div class="gallery-admin-body">
                        <h4>${title}</h4>
                        <p class="gallery-admin-meta">${category} • Sort: ${sortOrder}</p>
                        <p class="gallery-admin-desc">${description}</p>
                        <div class="gallery-admin-actions">
                            <a href="#"
                               class="action-link action-btn gallery-edit-btn"
                               title="Edit Gallery Item"
                               data-id="${id}"
                               data-title="${safeDataValue(row.title || '')}"
                               data-description="${safeDataValue(row.description || '')}"
                               data-image="${safeDataValue(row.image_url || '')}"
                               data-category="${safeDataValue(row.category || '')}"
                               data-sort-order="${sortOrder}"
                               data-featured="${featuredRaw}">
                                <i class="fa fa-pencil"></i>
                            </a>
                            <a href="#"
                               class="action-link action-btn gallery-delete-btn"
                               title="Delete Gallery Item"
                               data-id="${id}">
                                <i class="fa fa-trash"></i>
                            </a>
                        </div>
                    </div>
                </div>
            `;
        }).join('');
    } catch (error) {
        console.error(error);
        grid.innerHTML = `
            <div class="gallery-admin-card">
                <div class="gallery-admin-body">
                    <h4>Unable to load gallery</h4>
                    <p>Please try again.</p>
                </div>
            </div>
        `;
    }
}

async function loadNews() {
    const grid = document.getElementById('newsGrid');
    if (!grid) {
        return;
    }

    grid.innerHTML = `
        <div class="gallery-admin-card">
            <div class="gallery-admin-body">
                <h4>Loading news...</h4>
                <p>Please wait</p>
            </div>
        </div>
    `;

    try {
        const result = await fetchAdminData('get_news');
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            grid.innerHTML = `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-body">
                        <h4>No news found</h4>
                        <p>Add your first news post.</p>
                    </div>
                </div>
            `;
            return;
        }

        grid.innerHTML = rows.map(row => {
            const id = safeDataValue(row.id || '');
            const title = escapeHtml(row.title || 'Untitled');
            const summary = escapeHtml(row.summary || 'No summary.');
            const content = escapeHtml(row.content || '');
            const image = escapeHtml(row.featured_image || 'images/news/1.webp');
            const status = String(row.status || 'draft');
            const statusLabel = normalizeStatusLabel(status);
            const statusClass = status === 'published' ? 'confirmed' : (status === 'archived' ? 'cancelled' : 'pending');
            const createdAt = escapeHtml(row.created_at ? String(row.created_at).split(' ')[0] : '-');

            return `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-media">
                        <img src="${image}" alt="${title}">
                        <span class="gallery-admin-badge ${status === 'published' ? 'featured' : 'standard'}">${statusLabel}</span>
                    </div>
                    <div class="gallery-admin-body">
                        <h4>${title}</h4>
                        <p class="gallery-admin-meta">${createdAt}</p>
                        <p class="gallery-admin-desc">${summary}</p>
                        <div class="gallery-admin-actions">
                            <a href="#"
                               class="action-link action-btn news-edit-btn"
                               title="Edit News"
                               data-id="${id}"
                               data-title="${safeDataValue(row.title || '')}"
                               data-summary="${safeDataValue(row.summary || '')}"
                               data-content="${safeDataValue(row.content || '')}"
                               data-image="${safeDataValue(row.featured_image || '')}"
                               data-status="${safeDataValue(status)}">
                                <i class="fa fa-pencil"></i>
                            </a>
                            <a href="#"
                               class="action-link action-btn news-delete-btn"
                               title="Delete News"
                               data-id="${id}">
                                <i class="fa fa-trash"></i>
                            </a>
                        </div>
                    </div>
                </div>
            `;
        }).join('');
    } catch (error) {
        console.error(error);
        grid.innerHTML = `
            <div class="gallery-admin-card">
                <div class="gallery-admin-body">
                    <h4>Unable to load news</h4>
                    <p>${escapeHtml(error.message || 'Please try again.')}</p>
                </div>
            </div>
        `;
    }
}

async function loadOffers() {
    const grid = document.getElementById('offersGrid');
    if (!grid) {
        return;
    }

    grid.innerHTML = `
        <div class="gallery-admin-card">
            <div class="gallery-admin-body">
                <h4>Loading offers...</h4>
                <p>Please wait</p>
            </div>
        </div>
    `;

    try {
        const result = await fetchAdminData('get_offers');
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            grid.innerHTML = `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-body">
                        <h4>No offers found</h4>
                        <p>Add your first special offer.</p>
                    </div>
                </div>
            `;
            return;
        }

        grid.innerHTML = rows.map(row => {
            const id = safeDataValue(row.id || '');
            const title = escapeHtml(row.title || 'Offer');
            const description = escapeHtml(row.description || 'No description.');
            const discountType = String(row.discount_type || 'percentage');
            const discountValueRaw = Number(row.discount_value || 0);
            const discountValue = discountType === 'fixed_amount'
                ? `$${discountValueRaw.toFixed(2)}`
                : `${discountValueRaw}%`;
            const startDate = escapeHtml(row.start_date || '-');
            const endDate = escapeHtml(row.end_date || '-');
            const isActive = Number(row.is_active) === 1 || row.is_active === true || row.is_active === '1';
            const statusText = isActive ? 'Active' : 'Inactive';
            const statusClass = isActive ? 'confirmed' : 'cancelled';
            const maxRedemptions = row.max_redemptions === null || typeof row.max_redemptions === 'undefined'
                ? 'Unlimited'
                : escapeHtml(row.max_redemptions);

            return `
                <div class="gallery-admin-card">
                    <div class="gallery-admin-body">
                        <h4>${title}</h4>
                        <p class="gallery-admin-meta">Discount: ${escapeHtml(discountValue)} - ${startDate} to ${endDate}</p>
                        <p class="gallery-admin-desc">${description}</p>
                        <p class="gallery-admin-meta">Max Redemptions: ${maxRedemptions}</p>
                        <div class="gallery-admin-actions">
                            <span class="status-badge status-${statusClass}">${statusText}</span>
                            <a href="#"
                               class="action-link action-btn offer-edit-btn"
                               title="Edit Offer"
                               data-id="${id}"
                               data-title="${safeDataValue(row.title || '')}"
                               data-description="${safeDataValue(row.description || '')}"
                               data-discount-type="${safeDataValue(discountType)}"
                               data-discount-value="${safeDataValue(row.discount_value ?? 0)}"
                               data-start-date="${safeDataValue(row.start_date || '')}"
                               data-end-date="${safeDataValue(row.end_date || '')}"
                               data-max-redemptions="${safeDataValue(row.max_redemptions ?? '')}"
                               data-active="${isActive ? '1' : '0'}">
                                <i class="fa fa-pencil"></i>
                            </a>
                            <a href="#"
                               class="action-link action-btn offer-delete-btn"
                               title="Delete Offer"
                               data-id="${id}">
                                <i class="fa fa-trash"></i>
                            </a>
                        </div>
                    </div>
                </div>
            `;
        }).join('');
    } catch (error) {
        console.error(error);
        grid.innerHTML = `
            <div class="gallery-admin-card">
                <div class="gallery-admin-body">
                    <h4>Unable to load offers</h4>
                    <p>${escapeHtml(error.message || 'Please try again.')}</p>
                </div>
            </div>
        `;
    }
}

async function loadServices() {
    const tbody = document.getElementById('servicesTableBody');
    const table = document.getElementById('servicesTable');
    if (!tbody || !table) {
        return;
    }

    tbody.innerHTML = '<tr><td colspan="7" class="text-center">Loading services data...</td></tr>';

    try {
        const result = await fetchAdminData('get_services');
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            tbody.innerHTML = '<tr><td colspan="7" class="text-center">No services found.</td></tr>';
            makeTableResponsive();
            return;
        }

        tbody.innerHTML = rows.map(row => {
            const isActive = Number(row.is_active) === 1 || row.is_active === true || row.is_active === '1';
            const availability = isActive ? 'Available' : 'Unavailable';
            const statusText = isActive ? 'Active' : 'Inactive';
            const statusClass = isActive ? 'confirmed' : 'cancelled';
            const rawImageValue = String(row.image_url || '').trim();
            const rawIconValue = String(row.icon || '').trim();
            const looksLikeIconClass = (value) => /^icofont-/.test(value) || /^fa[\s-]/.test(value);
            const looksLikeIconImage = (value) => /\.(svg)(\?.*)?$/i.test(value) || /\/svg\//i.test(value) || /icon/i.test(value);
            const looksLikePhoto = (value) => /\.(webp|png|jpe?g|gif)(\?.*)?$/i.test(value) && !/\/svg\//i.test(value);
            const normalizeIconImagePath = (value) => {
                const clean = String(value || '').trim().replace(/\\/g, '/');
                if (!clean) {
                    return 'images/svg/cleaning-service-svgrepo-com.svg';
                }
                if (/^(https?:)?\/\//i.test(clean) || clean.startsWith('/') || clean.startsWith('images/')) {
                    return clean;
                }
                if (/\.svg(\?.*)?$/i.test(clean)) {
                    return `images/svg/${clean}`;
                }
                return 'images/svg/cleaning-service-svgrepo-com.svg';
            };

            let normalizedImage = rawImageValue;
            let normalizedIcon = rawIconValue;

            // Auto-correct old/swapped rows where image/icon were stored in opposite columns.
            const shouldSwap =
                (looksLikeIconClass(rawImageValue) && (looksLikePhoto(rawIconValue) || looksLikeIconImage(rawIconValue))) ||
                (looksLikeIconImage(rawImageValue) && looksLikePhoto(rawIconValue));
            if (shouldSwap) {
                normalizedImage = rawIconValue;
                normalizedIcon = rawImageValue;
            }

            // Strong fallback selection: always prefer a photo for image column.
            if (!looksLikePhoto(normalizedImage) && looksLikePhoto(rawIconValue)) {
                normalizedImage = rawIconValue;
            }
            if (!looksLikePhoto(normalizedImage)) {
                normalizedImage = 'images/facilities/1.webp';
            }

            const hasIconClass = looksLikeIconClass(normalizedIcon);
            if (!normalizedIcon && (looksLikeIconClass(rawImageValue) || looksLikeIconImage(rawImageValue))) {
                normalizedIcon = rawImageValue;
            }
            const iconImage = escapeHtml(normalizeIconImagePath(normalizedIcon));
            const imageUrl = escapeHtml(normalizedImage);
            const name = escapeHtml(row.name || 'Service');
            const description = escapeHtml(row.description || 'N/A');
            const serviceId = safeDataValue(row.id || '');
            const activeFlag = isActive ? '1' : '0';
            const iconMarkup = hasIconClass
                ? `<i class="${escapeHtml(normalizedIcon)}" aria-hidden="true"></i>`
                : `<img src="${iconImage}" alt="${name} icon">`;

            return `
                <tr>
                    <td>${name}</td>
                    <td>
                        <img class="service-thumb" src="${imageUrl}" alt="${name}">
                    </td>
                    <td>
                        <span class="service-icon-chip">${iconMarkup}</span>
                    </td>
                    <td>${description}</td>
                    <td>${availability}</td>
                    <td><span class="status-badge status-${statusClass}">${statusText}</span></td>
                    <td>
                        <div class="service-action-group">
                            <a href="#"
                               class="action-link action-btn service-edit-btn"
                               title="Edit Service"
                               data-id="${serviceId}"
                               data-name="${safeDataValue(row.name || '')}"
                               data-description="${safeDataValue(row.description || '')}"
                               data-icon="${safeDataValue(normalizedIcon)}"
                               data-image="${safeDataValue(normalizedImage)}"
                               data-active="${activeFlag}">
                                <i class="fa fa-pencil"></i>
                            </a>
                            <a href="#"
                               class="action-link action-btn service-delete-btn"
                               title="Delete Service"
                               data-id="${serviceId}">
                                <i class="fa fa-trash"></i>
                            </a>
                        </div>
                    </td>
                </tr>
            `;
        }).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
    } catch (error) {
        console.error(error);
        tbody.innerHTML = '<tr><td colspan="7" class="text-center">Unable to load services data.</td></tr>';
    }
}

async function loadServiceReservations(filters = {}) {
    const tbody = document.getElementById('serviceReservationsTableBody');
    const table = document.getElementById('serviceReservationsTable');
    if (!tbody || !table) {
        return;
    }

    tbody.innerHTML = '<tr><td colspan="9" class="text-center">Loading service reservation data...</td></tr>';

    try {
        const resolvedFilters = typeof filters === 'string'
            ? { status: filters }
            : (filters && typeof filters === 'object' ? filters : {});
        const params = {};
        if (resolvedFilters.status) params.status = resolvedFilters.status;
        if (resolvedFilters.guest) params.guest = resolvedFilters.guest;
        if (resolvedFilters.service) params.service = resolvedFilters.service;
        if (resolvedFilters.date) params.date = resolvedFilters.date;
        const result = await fetchAdminData('get_service_reservations', params);
        const rows = Array.isArray(result.data) ? result.data : [];

        if (rows.length === 0) {
            tbody.innerHTML = '<tr><td colspan="9" class="text-center">No service reservations found.</td></tr>';
            makeTableResponsive();
            return;
        }

        tbody.innerHTML = rows.map(row => {
            const id = row.id ? `#${escapeHtml(row.id)}` : '-';
            const guestName = `${escapeHtml(row.first_name || '')} ${escapeHtml(row.last_name || '')}`.trim() || escapeHtml(row.email || 'N/A');
            const serviceName = escapeHtml(row.service_name || 'Service');
            const dates = `${escapeHtml(row.service_start_date || '-')} to ${escapeHtml(row.service_end_date || '-')}`;
            const guestsCount = escapeHtml(row.number_of_guests || 1);
            const amount = row.total_price !== null && typeof row.total_price !== 'undefined'
                ? `$${Number(row.total_price).toFixed(2)}`
                : '$0.00';
            const statusValue = String(row.status || 'pending');
            const statusLabel = normalizeStatusLabel(statusValue);
            const isCompletedLocked = statusValue === 'completed';
            const statusOptions = ['pending', 'confirmed', 'completed', 'cancelled']
                .map(status => `<option value="${status}" ${status === statusValue ? 'selected' : ''}>${normalizeStatusLabel(status)}</option>`)
                .join('');
            const paymentValue = String(row.payment_status || 'unpaid');
            const paymentLabel = normalizeStatusLabel(paymentValue);
            const isPaidLocked = paymentValue === 'paid';
            const paymentOptions = ['unpaid', 'partial', 'paid']
                .map(pay => `<option value="${pay}" ${pay === paymentValue ? 'selected' : ''}>${normalizeStatusLabel(pay)}</option>`)
                .join('');

            return `
                <tr>
                    <td>${id}</td>
                    <td>${guestName}</td>
                    <td>${serviceName}</td>
                    <td>${dates}</td>
                    <td>${guestsCount}</td>
                    <td>${amount}</td>
                    <td>
                        <div class="payment-status-wrap ${isPaidLocked ? 'is-locked' : ''}">
                            <div class="service-payment-control-row">
                            <select class="service-res-payment-select"
                                    data-id="${safeDataValue(row.id || '')}"
                                    data-current="${safeDataValue(paymentValue)}"
                                    data-allow-paid-change="0"
                                    ${isPaidLocked ? 'disabled' : ''}
                                    aria-label="Update service payment status">
                                ${paymentOptions}
                            </select>
                            <button type="button"
                                    class="service-payment-unlock-btn ${isPaidLocked ? '' : 'is-hidden'}"
                                    aria-pressed="false"
                                    title="Unlock paid status to change">
                                Change
                            </button>
                            </div>
                            <span class="status-badge service-payment-status-badge payment-${escapeHtml(paymentValue)}">${escapeHtml(paymentLabel)}</span>
                        </div>
                    </td>
                    <td>
                        <div class="service-status-wrap ${isCompletedLocked ? 'is-locked' : ''}">
                            <div class="service-status-control-row">
                            <select class="service-status-select"
                                    data-id="${safeDataValue(row.id || '')}"
                                    data-current="${safeDataValue(statusValue)}"
                                    data-allow-completed-change="0"
                                    ${isCompletedLocked ? 'disabled' : ''}
                                    aria-label="Update service reservation status">
                                ${statusOptions}
                            </select>
                            <button type="button"
                                    class="service-status-unlock-btn ${isCompletedLocked ? '' : 'is-hidden'}"
                                    aria-pressed="false"
                                    title="Unlock completed status to change">
                                Change
                            </button>
                            </div>
                            <span class="status-badge service-status-badge status-${escapeHtml(statusValue)}">${escapeHtml(statusLabel)}</span>
                        </div>
                    </td>
                    <td>
                        <a href="#"
                           class="action-link action-btn service-res-view-btn"
                           title="View Details"
                           data-id="${safeDataValue(id)}"
                           data-guest="${safeDataValue(guestName)}"
                           data-service="${safeDataValue(serviceName)}"
                           data-dates="${safeDataValue(dates)}"
                           data-guests="${safeDataValue(guestsCount)}"
                           data-amount="${safeDataValue(amount)}"
                           data-payment="${safeDataValue(paymentLabel)}"
                           data-status="${safeDataValue(statusLabel)}">
                             <i class="fa fa-eye"></i>
                        </a>
                    </td>
                </tr>
            `;
        }).join('');

        makeTableResponsive();
        applyTableDataLabels(table);
    } catch (error) {
        console.error(error);
        tbody.innerHTML = '<tr><td colspan="9" class="text-center">Unable to load service reservation data.</td></tr>';
    }
}

function autoRefreshData(intervalMs = 30000) {
    setInterval(() => {
        console.log('Auto-refreshing dashboard data...');
    }, intervalMs);
}

function updateDashboard(data) {
    const statCards = document.querySelectorAll('.stat-card');

    statCards.forEach(card => {
        const label = card.querySelector('.stat-label').textContent;
        const value = card.querySelector('.stat-value');

        switch (label) {
            case 'Total Guests':
                value.textContent = data.total_guests || 0;
                break;
            case 'Total Reservations':
                value.textContent = data.total_reservations || 0;
                break;
            case 'Active Reservations':
                value.textContent = data.active_reservations || 0;
                break;
            case 'Total Revenue':
                value.textContent = '$' + (data.total_revenue || 0).toFixed(2);
                break;
            case 'Total Rooms':
                value.textContent = data.total_rooms || 0;
                break;
            case 'Available Rooms':
                value.textContent = data.available_rooms || 0;
                break;
        }
    });
}

const animationStyles = document.createElement('style');
animationStyles.textContent = `
    @keyframes fadeInUp {
        from {
            opacity: 0;
            transform: translateY(20px);
        }
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    .fadeInUp {
        animation: fadeInUp 0.6s ease-out;
    }

    @media (max-width: 767px) {
        .admin-table.responsive {
            display: block;
            overflow: visible;
        }

        .admin-table.responsive thead {
            display: none;
        }

        .admin-table.responsive tbody {
            display: block;
        }

        .admin-table.responsive tr {
            display: block;
            border: 1px solid #E0E0E0;
            margin-bottom: 15px;
            border-radius: 8px;
            overflow: hidden;
            background: #fff;
        }

        .admin-table.responsive td {
            display: block;
            text-align: right;
            padding: 10px;
            position: relative;
            padding-left: 50%;
            border: none;
            border-bottom: 1px solid #F0F0F0;
            min-height: 38px;
        }

        .admin-table.responsive td:before {
            content: attr(data-label);
            position: absolute;
            left: 10px;
            font-weight: 600;
            text-align: left;
            color: #333;
            max-width: 45%;
        }

        .admin-table.responsive td:last-child {
            border-bottom: none;
        }
    }
`;
document.head.appendChild(animationStyles);

window.adminDashboard = {
    updateDashboard,
    autoRefreshData,
    debounce
};
