document.addEventListener('DOMContentLoaded', () => {
    const i18n = window.CCW_I18N || {};
    const t = (value) => i18n[value] || value;
    const interpolate = (template, replacements = {}) => Object.entries(replacements).reduce((carry, [key, value]) => {
        return carry.split(`:${key}`).join(String(value));
    }, template);
    const monthNames = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December',
    ].map((month) => t(month));

    const formatYearMonthLabel = (value) => {
        if (!/^\d{4}-\d{2}$/.test(String(value))) {
            return value || '';
        }

        const [year, month] = String(value).split('-');
        const monthIndex = Number(month) - 1;
        const monthName = monthNames[monthIndex] || month;

        return `${monthName} ${year}`;
    };

    const closeAllMonthPickers = () => {
        document.querySelectorAll('[data-month-picker].is-open').forEach((openPicker) => {
            openPicker.classList.remove('is-open');
            const openPanel = openPicker.querySelector('[data-month-picker-panel]');
            if (openPanel) {
                openPanel.hidden = true;
            }
        });
    };

    document.querySelectorAll('[data-month-picker]').forEach((picker) => {
        const nativeInput = picker.querySelector('[data-month-picker-native]');
        const button = picker.querySelector('[data-month-picker-button]');
        const label = picker.querySelector('[data-month-picker-label]');
        const panel = picker.querySelector('[data-month-picker-panel]');
        const yearLabel = picker.querySelector('[data-month-picker-year-label]');
        const prevYearButton = picker.querySelector('[data-month-picker-prev-year]');
        const nextYearButton = picker.querySelector('[data-month-picker-next-year]');
        const monthButtons = Array.from(picker.querySelectorAll('[data-month-picker-month]'));

        if (!nativeInput || !button || !label || !panel || !yearLabel || !prevYearButton || !nextYearButton || monthButtons.length === 0) {
            return;
        }

        let viewYear = Number.parseInt(picker.dataset.monthPickerYear || nativeInput.value.slice(0, 4), 10);

        if (!Number.isFinite(viewYear)) {
            viewYear = new Date().getFullYear();
        }

        const syncLabel = () => {
            label.textContent = formatYearMonthLabel(nativeInput.value);
        };

        const syncPanel = () => {
            yearLabel.textContent = String(viewYear);

            monthButtons.forEach((monthButton) => {
                const monthValue = monthButton.dataset.monthPickerMonth || monthButton.getAttribute('data-month-picker-month') || '';
                const optionValue = `${viewYear}-${monthValue}`;
                const isSelected = nativeInput.value === optionValue;

                monthButton.classList.toggle('is-selected', isSelected);
                monthButton.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
            });
        };

        const openPicker = () => {
            closeAllMonthPickers();
            picker.classList.add('is-open');
            panel.hidden = false;
            syncPanel();
        };

        const closePicker = () => {
            picker.classList.remove('is-open');
            panel.hidden = true;
        };

        button.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();

            if (picker.classList.contains('is-open')) {
                closePicker();
                return;
            }

            openPicker();
        });

        prevYearButton.addEventListener('click', (event) => {
            event.preventDefault();
            viewYear -= 1;
            syncPanel();
        });

        nextYearButton.addEventListener('click', (event) => {
            event.preventDefault();
            viewYear += 1;
            syncPanel();
        });

        monthButtons.forEach((monthButton) => {
            monthButton.addEventListener('click', (event) => {
                event.preventDefault();
                event.stopPropagation();
                const monthValue = monthButton.dataset.monthPickerMonth || monthButton.getAttribute('data-month-picker-month') || '';

                if (!/^\d{2}$/.test(monthValue)) {
                    return;
                }

                nativeInput.value = `${viewYear}-${monthValue}`;
                nativeInput.dispatchEvent(new Event('change', { bubbles: true }));
                syncLabel();
                syncPanel();
                closePicker();
            });
        });

        nativeInput.addEventListener('change', () => {
            const matched = /^(\d{4})-(\d{2})$/.exec(nativeInput.value);
            if (matched) {
                viewYear = Number.parseInt(matched[1], 10);
            }

            syncLabel();
            syncPanel();
        });

        syncLabel();
        syncPanel();

        document.addEventListener('click', (event) => {
            if (!picker.contains(event.target)) {
                closePicker();
            }
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                closePicker();
            }
        });
    });

    document.querySelectorAll('[data-nav-report-group]').forEach((group) => {
        const toggle = group.querySelector('[data-nav-report-toggle]');
        const menu = group.querySelector('[data-nav-report-menu]');

        if (!toggle || !menu) {
            return;
        }

        if (document.body.classList.contains('display-app')) {
            document.body.appendChild(menu);
        }

        const setOpen = (isOpen) => {
            group.classList.toggle('is-open', isOpen);
            menu.classList.toggle('is-open', isOpen);
            toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
        };

        toggle.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();
            setOpen(!group.classList.contains('is-open'));
        });

        menu.querySelectorAll('a').forEach((link) => {
            link.addEventListener('click', () => setOpen(false));
        });

        document.addEventListener('click', (event) => {
            if (!group.contains(event.target) && !menu.contains(event.target)) {
                setOpen(false);
                toggle.blur();
            }
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                setOpen(false);
                toggle.blur();
            }
        });
    });

    const appNotificationDock = document.querySelector('[data-app-notification-dock]');

    document.querySelectorAll('[data-notification-center]').forEach((center) => {
        const toggle = center.querySelector('[data-notification-toggle]');
        const panel = center.querySelector('[data-notification-panel]');

        if (!toggle || !panel) {
            return;
        }

        // Keep notification behavior in app mode consistent with web mode:
        // show the panel as a floating popup instead of docking it into content.
        const shouldDockInApp = () => false;

        const undockPanel = () => {
            if (panel.parentElement !== center) {
                center.appendChild(panel);
            }

            center.classList.remove('is-docked');

            if (appNotificationDock && !appNotificationDock.querySelector('[data-notification-panel]:not([hidden])')) {
                appNotificationDock.hidden = true;
            }
        };

        const dockPanel = () => {
            if (!shouldDockInApp()) {
                return;
            }

            if (appNotificationDock && panel.parentElement !== appNotificationDock) {
                appNotificationDock.hidden = false;
                appNotificationDock.appendChild(panel);
            }

            center.classList.add('is-docked');
        };

        const setOpen = (isOpen) => {
            if (isOpen) {
                dockPanel();
            } else {
                undockPanel();
            }

            center.classList.toggle('is-open', isOpen);
            panel.hidden = !isOpen;
            toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
        };

        toggle.addEventListener('click', (event) => {
            event.preventDefault();
            event.stopPropagation();

            document.querySelectorAll('[data-notification-center].is-open').forEach((openCenter) => {
                if (openCenter !== center) {
                    const openToggle = openCenter.querySelector('[data-notification-toggle]');
                    const openPanel = openCenter.querySelector('[data-notification-panel]');
                    openCenter.classList.remove('is-open');
                    if (openPanel) {
                        openPanel.hidden = true;
                        if (openPanel.parentElement !== openCenter) {
                            openCenter.appendChild(openPanel);
                        }
                    }
                    if (openToggle) {
                        openToggle.setAttribute('aria-expanded', 'false');
                    }
                    openCenter.classList.remove('is-docked');
                }
            });

            setOpen(!center.classList.contains('is-open'));
        });

        panel.querySelectorAll('a').forEach((link) => {
            link.addEventListener('click', () => setOpen(false));
        });

        document.addEventListener('click', (event) => {
            if (!center.contains(event.target) && !panel.contains(event.target)) {
                setOpen(false);
            }
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                setOpen(false);
            }
        });
    });

    const appMenuToggle = document.querySelector('[data-app-menu-toggle]');
    const appMenuPanel = document.querySelector('[data-app-menu-panel]');
    const appMenuBackdrop = document.querySelector('[data-app-menu-backdrop]');
    const appMenuClose = document.querySelector('[data-app-menu-close]');

    if (appMenuToggle && appMenuPanel && appMenuBackdrop) {
        const setAppMenuOpen = (isOpen) => {
            appMenuPanel.hidden = !isOpen;
            appMenuBackdrop.hidden = !isOpen;
            appMenuPanel.setAttribute('aria-hidden', isOpen ? 'false' : 'true');
            appMenuToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
            document.body.classList.toggle('app-menu-open', isOpen);

            if (isOpen && appMenuClose) {
                appMenuClose.focus({ preventScroll: true });
            } else if (!isOpen) {
                appMenuToggle.blur();
            }
        };

        appMenuToggle.addEventListener('click', () => {
            setAppMenuOpen(appMenuPanel.hidden);
        });

        appMenuBackdrop.addEventListener('click', () => setAppMenuOpen(false));

        if (appMenuClose) {
            appMenuClose.addEventListener('click', () => setAppMenuOpen(false));
        }

        appMenuPanel.querySelectorAll('a').forEach((link) => {
            link.addEventListener('click', () => setAppMenuOpen(false));
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape' && !appMenuPanel.hidden) {
                setAppMenuOpen(false);
            }
        });
    }

    const dashboardConsole = document.querySelector('[data-dashboard-console]');
    const dashboardSidebarToggle = document.querySelector('[data-dashboard-sidebar-toggle]');
    const dashboardSidebarClose = document.querySelector('[data-dashboard-sidebar-close]');
    const dashboardSidebarBackdrop = document.querySelector('[data-dashboard-sidebar-backdrop]');

    if (dashboardConsole && dashboardSidebarToggle) {
        const desktopSidebarQuery = window.matchMedia('(min-width: 901px)');
        const storageKey = 'ccw_dashboard_sidebar_collapsed';

        const setDesktopCollapsed = (isCollapsed) => {
            dashboardConsole.classList.toggle('is-collapsed', isCollapsed);
            dashboardSidebarToggle.setAttribute('aria-expanded', isCollapsed ? 'false' : 'true');

            try {
                window.localStorage.setItem(storageKey, isCollapsed ? '1' : '0');
            } catch (error) {
                // Ignore storage errors in private mode or restricted browsers.
            }
        };

        const setMobileOpen = (isOpen) => {
            dashboardConsole.classList.toggle('is-sidebar-open', isOpen);
            if (dashboardSidebarBackdrop) {
                dashboardSidebarBackdrop.hidden = !isOpen;
            }
            dashboardSidebarToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
            document.body.classList.toggle('dashboard-sidebar-open', isOpen);
        };

        const syncDashboardSidebarMode = () => {
            if (desktopSidebarQuery.matches) {
                setMobileOpen(false);

                let isCollapsed = false;
                try {
                    isCollapsed = window.localStorage.getItem(storageKey) === '1';
                } catch (error) {
                    isCollapsed = false;
                }
                dashboardConsole.classList.toggle('is-collapsed', isCollapsed);
                dashboardSidebarToggle.setAttribute('aria-expanded', isCollapsed ? 'false' : 'true');
                return;
            }

            dashboardConsole.classList.remove('is-collapsed');
            dashboardSidebarToggle.setAttribute(
                'aria-expanded',
                dashboardConsole.classList.contains('is-sidebar-open') ? 'true' : 'false'
            );
        };

        dashboardSidebarToggle.addEventListener('click', () => {
            if (desktopSidebarQuery.matches) {
                setDesktopCollapsed(!dashboardConsole.classList.contains('is-collapsed'));
                return;
            }

            setMobileOpen(!dashboardConsole.classList.contains('is-sidebar-open'));
        });

        if (dashboardSidebarClose) {
            dashboardSidebarClose.addEventListener('click', () => setMobileOpen(false));
        }

        if (dashboardSidebarBackdrop) {
            dashboardSidebarBackdrop.addEventListener('click', () => setMobileOpen(false));
        }

        desktopSidebarQuery.addEventListener('change', () => {
            syncDashboardSidebarMode();
        });

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape' && dashboardConsole.classList.contains('is-sidebar-open')) {
                setMobileOpen(false);
            }
        });

        syncDashboardSidebarMode();
    }

    const syncLinkedGroupPanels = (form) => {
        form.querySelectorAll('[data-main-service-flow]').forEach((flow) => {
            const mainServiceCheckbox = flow.querySelector('summary [data-service-option]');
            const groupInputs = Array.from(flow.querySelectorAll('[data-main-service-group]'));
            const groupPanels = Array.from(flow.querySelectorAll('[data-group-sub-services]'));

            if (groupInputs.length === 0 || groupPanels.length === 0) {
                return;
            }

            const mainServiceChecked = !!mainServiceCheckbox?.checked;

            if (!mainServiceChecked) {
                groupInputs.forEach((input) => {
                    input.checked = false;
                });
            }

            const selectedGroup = mainServiceChecked
                ? (groupInputs.find((input) => input.checked)?.value || '')
                : '';

            groupPanels.forEach((panel) => {
                const isMatch = panel.dataset.groupId === selectedGroup;
                panel.hidden = !isMatch;

                if (isMatch) {
                    return;
                }

                panel.querySelectorAll('[data-service-option]').forEach((checkbox) => {
                    checkbox.checked = false;
                });

                panel.querySelectorAll('[data-package-usage]').forEach((select) => {
                    select.value = '';
                    select.disabled = true;
                });

                panel.querySelectorAll('[data-film-input]').forEach((input) => {
                    input.value = '';
                    input.disabled = true;

                    if (input.matches('[data-film-search]')) {
                        input.setCustomValidity('');
                    }
                });
            });
        });
    };

    const syncMainServiceFlows = (form) => {
        form.querySelectorAll('[data-main-service-flow]').forEach((flow) => {
            const mainServiceCheckbox = flow.querySelector('summary [data-service-option]');
            const selectedGroupInput = flow.querySelector('[data-main-service-group]:checked');
            const hasCheckedChild = Array.from(flow.querySelectorAll('[data-service-option]')).some((input) => input !== mainServiceCheckbox && input.checked);
            const shouldOpen = !!mainServiceCheckbox?.checked || !!selectedGroupInput || hasCheckedChild;

            flow.open = shouldOpen;
        });
    };

    const syncWindowFilmPanels = (form) => {
        let activePanel = null;

        form.querySelectorAll('[data-main-service-flow]').forEach((flow) => {
            const mainServiceCheckbox = flow.querySelector('summary [data-service-option]');
            const selectedGroupInput = Array.from(flow.querySelectorAll('[data-main-service-group]')).find((input) => input.checked);
            const selectedGroupId = selectedGroupInput?.value || '';
            const shouldShowPanel = !!selectedGroupInput
                && selectedGroupInput.dataset.showWindowFilmDetails === '1'
                && !!mainServiceCheckbox?.checked;

            flow.querySelectorAll('[data-film-options-panel]').forEach((panel) => {
                const isMatch = shouldShowPanel && activePanel === null && panel.dataset.groupId === selectedGroupId;
                panel.hidden = !isMatch;

                panel.querySelectorAll('[data-film-input]').forEach((input) => {
                    input.disabled = !isMatch;

                    if (isMatch) {
                        return;
                    }

                    const tagName = input.tagName;
                    if (tagName === 'SELECT' || tagName === 'INPUT' || tagName === 'TEXTAREA') {
                        input.value = '';
                    }

                    if (input.matches('[data-film-search]')) {
                        input.setCustomValidity('');
                    }
                });

                if (isMatch) {
                    activePanel = panel;
                }
            });
        });
    };

    const syncSelectOptionsByCategory = (select, categoryId) => {
        if (!select) {
            return;
        }

        const currentValue = select.value;

        Array.from(select.options).forEach((option, index) => {
            if (index === 0) {
                option.hidden = false;
                option.disabled = false;
                return;
            }

            const optionCategoryId = option.dataset.categoryId || '';
            const isVisible = categoryId === '' || optionCategoryId === categoryId;
            option.hidden = !isVisible;
            option.disabled = !isVisible;
        });

        if (currentValue !== '' && !Array.from(select.options).some((option) => option.value === currentValue && !option.disabled)) {
            select.value = '';
        }
    };

    const syncGroupOptions = (select, categoryId, mainServiceId) => {
        if (!select) {
            return;
        }

        const currentValue = select.value;

        Array.from(select.options).forEach((option, index) => {
            if (index === 0) {
                option.hidden = false;
                option.disabled = false;
                return;
            }

            const optionCategoryId = option.dataset.categoryId || '';
            const optionMainServiceId = option.dataset.mainServiceId || '';
            const categoryMatches = categoryId === '' || optionCategoryId === categoryId;
            const mainMatches = mainServiceId === '' || optionMainServiceId === mainServiceId;
            const isVisible = categoryMatches && mainMatches;

            option.hidden = !isVisible;
            option.disabled = !isVisible;
        });

        if (currentValue !== '' && !Array.from(select.options).some((option) => option.value === currentValue && !option.disabled)) {
            select.value = '';
        }
    };

    const syncServiceStructureForm = (form) => {
        const typeSelect = form.querySelector('[data-service-type-select]');
        const categorySelect = form.querySelector('[data-service-category-select]');
        const mainServiceField = form.querySelector('[data-main-service-field]');
        const mainServiceSelect = form.querySelector('[data-service-main-select]');
        const groupField = form.querySelector('[data-group-field]');
        const groupSelect = form.querySelector('[data-service-group-select]');
        const packageBuilder = form.querySelector('[data-package-builder]');
        const quickServiceField = form.querySelector('[data-quick-service-field]');
        const quickServiceInput = quickServiceField ? quickServiceField.querySelector('input[name="is_quick_service"]') : null;

        if (!typeSelect || !categorySelect) {
            return;
        }

        const selectedCategoryId = categorySelect.value;
        const isSubService = typeSelect.value === 'sub_service';
        const isPackage = typeSelect.value === 'package';

        syncSelectOptionsByCategory(mainServiceSelect, selectedCategoryId);
        syncGroupOptions(groupSelect, selectedCategoryId, mainServiceSelect ? mainServiceSelect.value : '');

        if (mainServiceField) {
            mainServiceField.hidden = !isSubService;
        }

        if (mainServiceSelect) {
            mainServiceSelect.disabled = !isSubService;
            mainServiceSelect.required = isSubService;

            if (!isSubService) {
                mainServiceSelect.value = '';
            }
        }

        if (groupField) {
            groupField.hidden = !isSubService;
        }

        if (groupSelect) {
            groupSelect.disabled = !isSubService;

            if (!isSubService) {
                groupSelect.value = '';
            }
        }

        if (packageBuilder) {
            packageBuilder.hidden = !isPackage;
            packageBuilder.querySelectorAll('input, select').forEach((input) => {
                input.disabled = !isPackage;
            });
        }

        if (quickServiceField) {
            quickServiceField.hidden = isPackage;
        }

        if (quickServiceInput) {
            quickServiceInput.disabled = isPackage;

            if (isPackage) {
                quickServiceInput.checked = false;
            }
        }
    };

    const syncServiceGroupForm = (form) => {
        const categorySelect = form.querySelector('[data-service-category-select]');
        const mainServiceSelect = form.querySelector('[data-service-main-select]');

        if (!categorySelect || !mainServiceSelect) {
            return;
        }

        syncSelectOptionsByCategory(mainServiceSelect, categorySelect.value);
    };

    document.querySelectorAll('[data-service-note]').forEach((input) => {
        ['click', 'mousedown', 'touchstart'].forEach((eventName) => {
            input.addEventListener(eventName, (event) => {
                event.stopPropagation();
            });
        });
    });

    const normalizeFilmSearchText = (value) => String(value ?? '').trim().toLocaleLowerCase();
    const syncFilmSearchInput = (input, allowSingleMatch = false) => {
        if (!(input instanceof HTMLInputElement)) {
            return true;
        }

        const targetId = input.dataset.filmTarget || '';
        const targetInput = targetId ? document.getElementById(targetId) : null;

        if (!(targetInput instanceof HTMLInputElement)) {
            return true;
        }

        if (input.disabled) {
            targetInput.value = '';
            input.setCustomValidity('');
            return true;
        }

        const query = input.value.trim();
        const normalizedQuery = normalizeFilmSearchText(query);

        if (query === '') {
            targetInput.value = '';
            input.setCustomValidity('');
            return true;
        }

        const list = input.list;
        const options = list ? Array.from(list.options) : [];
        let matchedOption = options.find((option) => normalizeFilmSearchText(option.value) === normalizedQuery);

        if (!matchedOption && allowSingleMatch) {
            const looseMatches = options.filter((option) => normalizeFilmSearchText(option.value).includes(normalizedQuery));

            if (looseMatches.length === 1) {
                matchedOption = looseMatches[0];
                input.value = matchedOption.value;
            }
        }

        const matchedServiceId = matchedOption?.dataset.serviceId || '';
        targetInput.value = matchedServiceId;
        input.setCustomValidity(matchedServiceId !== '' ? '' : (input.dataset.filmInvalidMessage || t('Choose a service from the suggestions.')));

        return matchedServiceId !== '';
    };
    const syncFilmSearchInputs = (root, allowSingleMatch = false) => Array
        .from(root.querySelectorAll('[data-film-search]'))
        .reduce((isValid, input) => syncFilmSearchInput(input, allowSingleMatch) && isValid, true);

    document.querySelectorAll('[data-film-search]').forEach((input) => {
        input.addEventListener('input', () => syncFilmSearchInput(input));
        input.addEventListener('change', () => syncFilmSearchInput(input, true));
        input.addEventListener('blur', () => syncFilmSearchInput(input, true));
    });

    const bookingForm = document.querySelector('[data-booking-form]');

    if (bookingForm) {
        const isQuickServiceForm = bookingForm.dataset.quickServiceForm === '1';
        const checkboxes = Array.from(bookingForm.querySelectorAll('[data-service-option]'));
        const countNode = bookingForm.querySelector('[data-selected-count]');
        const totalNode = bookingForm.querySelector('[data-selected-total]');
        const packageDiscountNode = bookingForm.querySelector('[data-selected-package-discount]');
        const totalPriceInput = bookingForm.querySelector('[data-total-price-input]');
        const packageUsageContainers = Array.from(bookingForm.querySelectorAll('[data-package-usage-container]'));
        const packageUsageSelects = Array.from(bookingForm.querySelectorAll('[data-package-usage]'));
        const mainServiceGroupInputs = Array.from(bookingForm.querySelectorAll('[data-main-service-group]'));
        const packageSummaryCard = bookingForm.querySelector('[data-package-summary-card]');
        const packageSummary = bookingForm.querySelector('[data-package-summary]');
        const lookupButton = bookingForm.querySelector('[data-customer-lookup]');
        const newCustomerButton = bookingForm.querySelector('[data-new-customer-trigger]');
        const lookupFeedback = bookingForm.querySelector('[data-lookup-feedback]');
        const lookupResults = bookingForm.querySelector('[data-lookup-results]');
        const bookingFlow = bookingForm.querySelector('[data-booking-flow]');
        const bookingLookupCard = bookingForm.querySelector('.booking-lookup-card');
        const lookupPhoneField = bookingForm.querySelector('#lookup_phone');
        const paymentMethodSelect = bookingForm.querySelector('#payment_method');
        const receivedAmountInput = bookingForm.querySelector('[data-received-amount-input]');
        const paidBeforeNode = bookingForm.querySelector('[data-paid-before]');
        const balanceDueNode = bookingForm.querySelector('[data-balance-due]');
        const balanceDueCard = bookingForm.querySelector('[data-balance-due-card]');
        const recognizedPaymentNode = bookingForm.querySelector('[data-recognized-payment]');
        const changeDueNode = bookingForm.querySelector('[data-change-due]');
        const changeField = bookingForm.querySelector('[data-change-field]');
        const paySubmitButton = bookingForm.querySelector('[data-pay-submit]');
        const paymentValidationMessage = bookingForm.querySelector('[data-payment-validation-message]');
        const bookingTotalValidationMessage = bookingForm.querySelector('[data-booking-total-validation-message]');
        const qrPanel = bookingForm.querySelector('[data-quick-qr-panel]');
        const qrImage = bookingForm.querySelector('[data-quick-qr-image]');
        const qrHint = bookingForm.querySelector('[data-quick-qr-hint]');
        const qrDownload = bookingForm.querySelector('[data-quick-qr-download]');
        const slipField = bookingForm.querySelector('[data-payment-slip-field]');
        const slipInput = bookingForm.querySelector('[data-payment-slip-input]');
        const branchNameInput = bookingForm.querySelector('#branch_name');
        const qrScope = bookingForm.dataset.qrScope || 'quick_service';
        const positiveTotalMessage = bookingForm.dataset.positiveTotalMessage || t('Booking total must be greater than 0 before opening the bill.');
        const depositSlipGroups = Array.from(bookingForm.querySelectorAll('[data-deposit-slip-group]')).map((group) => {
            const key = group.dataset.depositSlipGroup || '';
            return {
                key,
                group,
                amountInput: bookingForm.querySelector(`#${key}_deposit_amount`),
                methodSelect: bookingForm.querySelector(`[data-deposit-method-select][data-deposit-slip-target="${key}"]`),
                slipInput: group.querySelector('[data-deposit-slip-input]'),
            };
        });
        const depositQrGroups = ['admin', 'branch'].map((key) => ({
            key,
            panel: bookingForm.querySelector(`[data-deposit-qr-panel="${key}"]`),
            hint: bookingForm.querySelector(`[data-deposit-qr-hint="${key}"]`),
            image: bookingForm.querySelector(`[data-deposit-qr-image="${key}"]`),
            download: bookingForm.querySelector(`[data-deposit-qr-download="${key}"]`),
            amountInput: bookingForm.querySelector(`#${key}_deposit_amount`),
            methodSelect: bookingForm.querySelector(`[data-deposit-method-select][data-deposit-slip-target="${key}"]`),
            scope: key === 'admin' ? 'booking_deposit_admin' : 'booking_deposit_branch',
        }));
        const qrAvailable = bookingForm.dataset.qrAvailable === '1';
        const qrEndpoint = bookingForm.dataset.qrEndpoint || '';
        const supportsHoldAction = !!bookingForm.querySelector('[name="submit_action"][value="hold"]');
        const quickGuestExtraFields = Array.from(bookingForm.querySelectorAll('[data-quick-guest-extra]'));
        const fields = {
            customerId: bookingForm.querySelector('#customer_id'),
            carId: bookingForm.querySelector('#car_id'),
            customerMode: bookingForm.querySelector('#customer_mode'),
            customerName: bookingForm.querySelector('#customer_name'),
            phone: bookingForm.querySelector('#phone'),
            plate: bookingForm.querySelector('#plate_number'),
            province: bookingForm.querySelector('#province'),
            vehicleType: bookingForm.querySelector('#vehicle_type'),
            brand: bookingForm.querySelector('#brand'),
            model: bookingForm.querySelector('#model'),
            color: bookingForm.querySelector('#color'),
        };
        const defaultProvinceValue = fields.province?.dataset.defaultValue || '';
        let totalPriceEdited = totalPriceInput
            ? (isQuickServiceForm ? totalPriceInput.dataset.manual === '1' : totalPriceInput.value.trim() !== '')
            : false;

        const formatMoney = (value) => Number(value || 0).toLocaleString('en-US', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
        });

        const moneyToCents = (value) => {
            const numericValue = typeof value === 'number'
                ? value
                : Number(String(value ?? '').replace(/,/g, '').trim() || 0);

            if (!Number.isFinite(numericValue)) {
                return 0;
            }

            return Math.max(0, Math.round(numericValue * 100));
        };

        const centsToMoney = (value) => Math.max(0, Number(value || 0)) / 100;
        const quickServicePaidBeforeCents = moneyToCents(bookingForm.dataset.paidBefore || 0);
        const quickServicePaidBefore = centsToMoney(quickServicePaidBeforeCents);
        const methodsWithSlipSupport = ['transfer', 'qr', 'card'];
        const getActiveQrBranch = () => {
            if (branchNameInput instanceof HTMLInputElement || branchNameInput instanceof HTMLSelectElement) {
                return branchNameInput.value.trim();
            }

            return (bookingForm.dataset.qrBranch || '').trim();
        };
        const buildQrQueryString = (amount, scope) => {
            const params = new URLSearchParams();

            if (Number.isFinite(amount) && amount > 0) {
                params.set('amount', amount.toFixed(2));
            }

            if (scope) {
                params.set('scope', scope);
            }

            const activeBranch = getActiveQrBranch();
            if (activeBranch !== '') {
                params.set('branch', activeBranch);
            }

            return params.toString();
        };

        const normalizeMoneyInput = (input) => {
            if (!(input instanceof HTMLInputElement)) {
                return;
            }

            const trimmedValue = input.value.trim();
            if (trimmedValue === '') {
                return;
            }

            input.value = centsToMoney(moneyToCents(trimmedValue)).toFixed(2);
        };

        const protectNumberInputFromWheel = (input) => {
            if (!(input instanceof HTMLInputElement) || input.type !== 'number') {
                return;
            }

            input.addEventListener('wheel', (event) => {
                if (document.activeElement !== input) {
                    return;
                }

                event.preventDefault();
                input.blur();
            }, { passive: false });
        };

        const quickServicePaymentState = () => {
            const billTotalCents = moneyToCents(totalPriceInput ? totalPriceInput.value || 0 : 0);
            const balanceDueCents = Math.max(0, billTotalCents - quickServicePaidBeforeCents);
            const receivedAmountCents = moneyToCents(receivedAmountInput ? receivedAmountInput.value || 0 : 0);
            const billTotal = centsToMoney(billTotalCents);
            const balanceDue = centsToMoney(balanceDueCents);
            const receivedAmount = centsToMoney(receivedAmountCents);
            const isCashPayment = !!paymentMethodSelect && paymentMethodSelect.value === 'cash';
            const isUnderpaid = balanceDueCents > 0 && receivedAmountCents < balanceDueCents;
            const isOverpaid = receivedAmountCents > balanceDueCents;
            const recognizedPaymentCents = Math.min(receivedAmountCents, balanceDueCents);
            const recognizedPayment = centsToMoney(recognizedPaymentCents);
            const changeDue = isCashPayment
                ? centsToMoney(Math.max(0, receivedAmountCents - balanceDueCents))
                : 0;
            const hasPaymentInput = receivedAmountCents > 0;
            const allowPayment = balanceDueCents <= 0 || (hasPaymentInput && (!isOverpaid || isCashPayment));
            const willCloseBill = balanceDueCents <= 0 || receivedAmountCents >= balanceDueCents;

            return {
                billTotal,
                balanceDue,
                receivedAmount,
                isCashPayment,
                isUnderpaid,
                isOverpaid,
                recognizedPayment,
                changeDue,
                hasPaymentInput,
                allowPayment,
                willCloseBill,
            };
        };

        const validateBookingTotal = () => {
            if (isQuickServiceForm || !totalPriceInput) {
                return true;
            }

            const totalCents = moneyToCents(totalPriceInput.value || 0);
            const isValid = totalCents > 0;

            totalPriceInput.setCustomValidity(isValid ? '' : positiveTotalMessage);
            totalPriceInput.classList.toggle('is-danger', !isValid);

            if (bookingTotalValidationMessage) {
                bookingTotalValidationMessage.hidden = isValid;
                bookingTotalValidationMessage.textContent = isValid ? '' : positiveTotalMessage;
                bookingTotalValidationMessage.classList.toggle('is-danger', !isValid);
            }

            return isValid;
        };

        const updatePaymentSlipField = () => {
            if (!slipField || !paymentMethodSelect) {
                return;
            }

            const supportsSlip = methodsWithSlipSupport.includes(paymentMethodSelect.value);
            slipField.hidden = !supportsSlip;

            if (!supportsSlip && slipInput instanceof HTMLInputElement) {
                slipInput.value = '';
            }
        };

        const updateDepositSlipFields = () => {
            if (depositSlipGroups.length === 0) {
                return;
            }

            depositSlipGroups.forEach((item) => {
                if (!item.group || !item.methodSelect) {
                    return;
                }

                const amountValue = item.amountInput instanceof HTMLInputElement
                    ? Number(String(item.amountInput.value || '').replace(/,/g, '').trim() || 0)
                    : 0;
                const hasAmount = Number.isFinite(amountValue) && amountValue > 0;
                const supportsSlip = methodsWithSlipSupport.includes(item.methodSelect.value);
                const shouldShow = hasAmount && supportsSlip;

                item.group.hidden = !shouldShow;

                if (!shouldShow && item.slipInput instanceof HTMLInputElement) {
                    item.slipInput.value = '';
                }
            });
        };

        const updateDepositQrPanels = () => {
            if (depositQrGroups.length === 0) {
                return;
            }

            depositQrGroups.forEach((item) => {
                if (!item.panel || !item.methodSelect || !item.image || !item.hint) {
                    return;
                }

                const amountValue = item.amountInput instanceof HTMLInputElement
                    ? Number(String(item.amountInput.value || '').replace(/,/g, '').trim() || 0)
                    : 0;
                const shouldShow = item.methodSelect.value === 'qr' && Number.isFinite(amountValue) && amountValue > 0;

                item.panel.hidden = !shouldShow;

                if (!shouldShow) {
                    item.image.removeAttribute('src');
                    item.hint.textContent = t('Scan to receive payment.');
                    if (item.download) {
                        item.download.hidden = true;
                        item.download.removeAttribute('href');
                    }
                    return;
                }

                const qrAmount = amountValue;
                const queryString = buildQrQueryString(qrAmount, item.scope);

                if (qrEndpoint !== '') {
                    const qrUrl = `${qrEndpoint}?${queryString}`;
                    item.image.src = qrUrl;
                    if (item.download) {
                        item.download.href = `${qrEndpoint}?${queryString}&download=1`;
                        item.download.hidden = !qrAvailable;
                    }
                } else {
                    item.image.removeAttribute('src');
                    if (item.download) {
                        item.download.hidden = true;
                        item.download.removeAttribute('href');
                    }
                }

                if (!qrAvailable) {
                    item.hint.textContent = t('QR preview placeholder: set PromptPay ID or QR image in config to show the real code.');
                    if (item.download) {
                        item.download.hidden = true;
                    }
                    return;
                }

                item.hint.textContent = interpolate(t('Scan QR for :amount THB.'), { amount: formatMoney(qrAmount) });
            });
        };

        const updateQuickServiceQrPreview = (balanceDue, receivedAmount) => {
            if (!isQuickServiceForm || !qrPanel || !qrImage || !qrHint || !paymentMethodSelect) {
                return;
            }

            const shouldShowQr = paymentMethodSelect.value === 'qr';
            qrPanel.hidden = !shouldShowQr;

            if (!shouldShowQr) {
                qrImage.removeAttribute('src');
                qrHint.textContent = t('Scan to receive payment.');
                if (qrDownload) {
                    qrDownload.hidden = true;
                    qrDownload.removeAttribute('href');
                }
                return;
            }

            const qrAmount = receivedAmount > 0
                ? Math.min(receivedAmount, balanceDue > 0 ? balanceDue : receivedAmount)
                : balanceDue;
            const queryString = buildQrQueryString(qrAmount, qrScope);

            if (qrEndpoint !== '') {
                const qrUrl = queryString !== '' ? `${qrEndpoint}?${queryString}` : qrEndpoint;
                qrImage.src = qrUrl;
                if (qrDownload) {
                    qrDownload.href = queryString !== ''
                        ? `${qrEndpoint}?${queryString}&download=1`
                        : `${qrEndpoint}?download=1`;
                    qrDownload.hidden = false;
                }
            } else {
                qrImage.removeAttribute('src');
                if (qrDownload) {
                    qrDownload.hidden = true;
                    qrDownload.removeAttribute('href');
                }
            }

            if (!qrAvailable) {
                if (qrDownload) {
                    qrDownload.hidden = true;
                    qrDownload.removeAttribute('href');
                }
                qrHint.textContent = t('QR preview placeholder: set PromptPay ID or QR image in config to show the real code.');
                return;
            }

            qrHint.textContent = qrAmount > 0
                ? interpolate(t('Scan QR for :amount THB.'), { amount: formatMoney(qrAmount) })
                : t('Scan QR to receive payment.');
        };

        const setLookupFeedback = (message, state = '') => {
            if (!lookupFeedback) {
                return;
            }

            lookupFeedback.textContent = message;
            lookupFeedback.dataset.state = state;
        };

        const clearLookupResults = () => {
            if (!lookupResults) {
                return;
            }

            lookupResults.innerHTML = '';
            lookupResults.hidden = true;
        };

        const setBookingFlowVisibility = (visible) => {
            if (!bookingFlow) {
                return;
            }

            bookingFlow.hidden = !visible;

            if (!isQuickServiceForm && bookingLookupCard) {
                bookingLookupCard.hidden = visible;
                bookingLookupCard.querySelectorAll('input, select, textarea, button, a').forEach((element) => {
                    if (element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement || element instanceof HTMLButtonElement) {
                        element.disabled = visible;
                    }

                    if (element instanceof HTMLAnchorElement) {
                        if (visible) {
                            element.setAttribute('aria-hidden', 'true');
                            element.tabIndex = -1;
                        } else {
                            element.removeAttribute('aria-hidden');
                            element.removeAttribute('tabindex');
                        }
                    }
                });
            }
        };

        const setInputValue = (field, value) => {
            if (!field || value === undefined || value === null) {
                return;
            }

            field.value = String(value);
        };

        const setSelectValue = (field, value) => {
            if (!field || value === undefined || value === null) {
                return;
            }

            if (!('options' in field)) {
                field.value = String(value);
                return;
            }

            const nextValue = String(value);
            const optionLabel = field.id === 'province' ? t(nextValue) : nextValue;

            if (nextValue !== '' && !Array.from(field.options).some((option) => option.value === nextValue)) {
                const option = document.createElement('option');
                option.value = nextValue;
                option.textContent = optionLabel;
                field.append(option);
            }

            field.value = nextValue;
        };

        const syncQuickServiceCustomerFields = () => {
            if (!isQuickServiceForm) {
                return;
            }

            const mode = fields.customerMode?.value || '';
            const isGuest = mode === 'guest';
            const hasSelection = mode !== '';

            quickGuestExtraFields.forEach((wrapper) => {
                wrapper.hidden = isGuest;
                wrapper.querySelectorAll('input, select, textarea').forEach((input) => {
                    input.disabled = isGuest;
                });
            });

            [fields.phone, fields.province, fields.brand, fields.model, fields.color]
                .filter(Boolean)
                .forEach((field) => {
                    field.readOnly = true;
                });

            if (fields.customerName) {
                fields.customerName.readOnly = !isGuest;
            }

            if (fields.plate) {
                fields.plate.readOnly = mode === 'matched';
                fields.plate.required = hasSelection;
            }
        };

        const resetCustomerRecord = () => {
            setInputValue(fields.customerId, '');
            setInputValue(fields.carId, '');
            setInputValue(fields.customerMode, '');
            setInputValue(fields.customerName, '');
            setInputValue(fields.phone, '');
            setInputValue(fields.plate, '');
            setSelectValue(fields.province, defaultProvinceValue);
            setSelectValue(fields.vehicleType, '');
            setSelectValue(fields.brand, '');
            setInputValue(fields.model, '');
            setInputValue(fields.color, '');
            syncQuickServiceCustomerFields();
            renderPackageData([], false);
            updateSummary();
        };

        const startNewCustomerRegistration = (event) => {
            if (event) {
                event.preventDefault();
            }

            clearLookupResults();
            resetCustomerRecord();

            if (isQuickServiceForm) {
                const lookupQuery = lookupPhoneField?.value.trim() || '';
                const lookupKind = lookupQuery === ''
                    ? ''
                    : (/^[\d\s\-\+\(\)]+$/.test(lookupQuery) && lookupQuery.replace(/\D+/g, '').length >= 8 ? 'phone' : 'plate');
                setInputValue(fields.customerMode, 'guest');
                setInputValue(fields.customerName, t('Guest'));
                if (lookupKind === 'plate') {
                    setInputValue(fields.plate, lookupQuery);
                }
                setBookingFlowVisibility(true);
                setLookupFeedback(t('Enter the plate number for the guest customer to continue.'), 'warning');
                syncQuickServiceCustomerFields();
                if (lookupKind === 'plate') {
                    fields.customerName?.focus();
                } else {
                    fields.plate?.focus();
                }
                updateSummary();
                return;
            }

            setBookingFlowVisibility(true);
            setLookupFeedback(t('Enter the new customer and vehicle details below.'), '');
            fields.customerName?.focus();
        };

        const renderPackageData = (packageRows, hasCustomer = false) => {
            const packageScopeNote = (row) => {
                if ((row.vehicle_scope || 'member') !== 'car') {
                    return t('All member vehicles');
                }

                return row.plate_number
                    ? interpolate(t('Only vehicle :plate'), { plate: row.plate_number })
                    : t('Only purchasing vehicle');
            };

            const groupedRows = new Map();

            packageRows.forEach((row) => {
                const serviceId = Number(row.sub_service_id || 0);

                if (!serviceId) {
                    return;
                }

                if (!groupedRows.has(serviceId)) {
                    groupedRows.set(serviceId, []);
                }

                groupedRows.get(serviceId).push(row);
            });

            packageUsageContainers.forEach((container) => {
                const serviceId = Number(container.dataset.serviceId || 0);
                const select = container.querySelector('[data-package-usage]');
                const previousValue = select ? select.value : '';
                const rows = groupedRows.get(serviceId) || [];

                if (!select) {
                    return;
                }

                select.innerHTML = '';

                const defaultOption = document.createElement('option');
                defaultOption.value = '';
                defaultOption.textContent = t('Charge normal price');
                select.append(defaultOption);

                rows.forEach((row) => {
                    const option = document.createElement('option');
                    option.value = String(row.customer_package_item_id || '');
                    option.textContent = `${row.package_name_snapshot || t('Package')} / ${packageScopeNote(row)} / ${interpolate(t(':count left'), { count: Number(row.remaining_uses || 0) })}`;
                    select.append(option);
                });

                if (rows.length === 0) {
                    container.hidden = true;
                    select.disabled = true;
                    select.value = '';
                    return;
                }

                container.hidden = false;
                if (Array.from(select.options).some((option) => option.value === previousValue)) {
                    select.value = previousValue;
                }

                const relatedCheckbox = checkboxes.find((checkbox) => Number(checkbox.value) === serviceId);
                select.disabled = !(relatedCheckbox && relatedCheckbox.checked);
            });

            if (!packageSummaryCard || !packageSummary) {
                return;
            }

            if (!hasCustomer) {
                packageSummaryCard.hidden = true;
                packageSummary.innerHTML = '';
                return;
            }

            packageSummaryCard.hidden = false;
            packageSummary.innerHTML = '';

            if (packageRows.length === 0) {
                const helper = document.createElement('p');
                helper.className = 'helper';
                helper.textContent = t('No active package balance found for this customer.');
                packageSummary.append(helper);
                return;
            }

            const list = document.createElement('div');
            list.className = 'member-summary-list';

            packageRows.forEach((row) => {
                const item = document.createElement('div');
                const label = document.createElement('span');
                const name = document.createTextNode(String(row.service_name_snapshot || ''));
                const br = document.createElement('br');
                const meta = document.createElement('small');
                const remaining = document.createElement('strong');

                meta.className = 'muted';
                meta.textContent = `${String(row.package_name_snapshot || '')} / ${packageScopeNote(row)}`;
                label.append(name, br, meta);
                remaining.textContent = interpolate(t(':count left'), { count: Number(row.remaining_uses || 0) });
                item.append(label, remaining);
                list.append(item);
            });

            packageSummary.append(list);
        };

        const applyCustomerRecord = (record) => {
            setInputValue(fields.customerId, record.customerId || '');
            setInputValue(fields.carId, record.carId || '');
            setInputValue(fields.customerMode, 'matched');
            setInputValue(lookupPhoneField, record.phone || lookupPhoneField?.value || '');
            setInputValue(fields.customerName, record.customerName || fields.customerName?.value || '');
            setInputValue(fields.phone, record.phone || fields.phone?.value || '');
            setInputValue(fields.plate, record.plateNumber || fields.plate?.value || '');
            setSelectValue(fields.province, record.province || fields.province?.value || '');
            setSelectValue(fields.vehicleType, record.vehicleType || fields.vehicleType?.value || '');
            setSelectValue(fields.brand, record.brand || fields.brand?.value || '');
            setInputValue(fields.model, record.model || fields.model?.value || '');
            setInputValue(fields.color, record.color || fields.color?.value || '');
            renderPackageData(Array.isArray(record.availablePackages) ? record.availablePackages : [], true);
            clearLookupResults();
            setBookingFlowVisibility(true);
            setLookupFeedback(t('Customer data loaded.'), 'success');
            syncQuickServiceCustomerFields();
            updateSummary();
        };

        const renderLookupResults = (matches) => {
            if (!lookupResults) {
                return;
            }

            lookupResults.innerHTML = '';

            matches.forEach((match) => {
                const button = document.createElement('button');
                const title = document.createElement('strong');
                const meta = document.createElement('span');
                const vehicle = [match.brand, match.model].filter(Boolean).join(' ');
                const plate = match.plateNumber || t('No plate');

                button.type = 'button';
                button.className = 'lookup-result';
                title.textContent = match.customerName || t('Unnamed customer');
                meta.textContent = [match.phone, plate, vehicle].filter(Boolean).join(' / ');
                button.append(title, meta);
                button.addEventListener('click', () => applyCustomerRecord(match));
                lookupResults.append(button);
            });

            lookupResults.hidden = matches.length === 0;
        };

        const searchCustomer = async (event) => {
            if (event) {
                event.preventDefault();
            }

            const lookupQuery = lookupPhoneField?.value.trim() || '';

            if (lookupQuery === '') {
                clearLookupResults();
                renderPackageData([], false);
                setBookingFlowVisibility(false);
                setLookupFeedback(t('Enter the exact customer phone number or plate number to search.'), 'warning');
                updateSummary();
                return;
            }

            const params = new URLSearchParams();
            params.set('q', lookupQuery);

            lookupButton.disabled = true;
            setLookupFeedback(t('Searching...'), '');
            clearLookupResults();
            renderPackageData([], false);
            updateSummary();

            try {
                const response = await fetch(`../process/search_customer.php?${params.toString()}`, {
                    headers: {
                        Accept: 'application/json',
                    },
                });
                const data = await response.json();

                if (!response.ok || !data.success) {
                    throw new Error(data.message || t('Customer lookup failed.'));
                }

                const matches = Array.isArray(data.matches) ? data.matches : [];

                if (matches.length === 0) {
                    resetCustomerRecord();
                    if (isQuickServiceForm) {
                        setBookingFlowVisibility(false);
                        setLookupFeedback(t('No matching customer found. Use Guest to continue with a plate number.'), 'warning');
                        return;
                    }
                    setBookingFlowVisibility(true);
                    setLookupFeedback(t('No matching customer found. Register the new customer below.'), 'warning');
                    return;
                }

                if (matches.length === 1) {
                    applyCustomerRecord(matches[0]);
                    return;
                }

                resetCustomerRecord();
                setBookingFlowVisibility(false);
                renderLookupResults(matches);
                setLookupFeedback(interpolate(t('Found :count matches.'), { count: matches.length }), 'success');
            } catch (error) {
                setLookupFeedback(error.message || t('Customer lookup failed.'), 'error');
            } finally {
                lookupButton.disabled = false;
            }
        };

        const updateSummary = () => {
            let count = 0;
            let total = 0;
            let packageDiscount = 0;

            syncLinkedGroupPanels(bookingForm);
            syncMainServiceFlows(bookingForm);
            syncWindowFilmPanels(bookingForm);

            checkboxes.forEach((checkbox) => {
                const packageSelect = bookingForm.querySelector(`[name="package_usage[${checkbox.value}]"]`);
                const serviceNoteInput = bookingForm.querySelector(`[name="service_notes[${checkbox.value}]"]`);

                if (packageSelect) {
                    const container = packageSelect.closest('[data-package-usage-container]');
                    packageSelect.disabled = !checkbox.checked || !!container?.hidden;
                }

                if (serviceNoteInput) {
                    serviceNoteInput.disabled = !checkbox.checked;
                }

                if (!checkbox.checked) {
                    return;
                }

                count += 1;
                total += Number(checkbox.dataset.price || 0);

                if (packageSelect && packageSelect.value !== '') {
                    packageDiscount += Number(checkbox.dataset.price || 0);
                }
            });

            if (countNode) {
                countNode.textContent = String(count);
            }

            if (totalNode) {
                totalNode.textContent = formatMoney(Math.max(0, total - packageDiscount));
            }

            if (packageDiscountNode) {
                packageDiscountNode.textContent = formatMoney(packageDiscount);
            }

            if (totalPriceInput && !totalPriceEdited) {
                totalPriceInput.value = Math.max(0, total - packageDiscount).toFixed(2);
            }

            if (isQuickServiceForm) {
                const {
                    balanceDue,
                    receivedAmount,
                    isCashPayment,
                    isUnderpaid,
                    isOverpaid,
                    recognizedPayment,
                    changeDue,
                    hasPaymentInput,
                    allowPayment,
                    willCloseBill,
                } = quickServicePaymentState();
                let paymentMessage = t('Payment can be recorded more than once. The bill will close automatically only when the total paid reaches the amount due.');
                let paymentMessageState = '';

                if (paidBeforeNode) {
                    paidBeforeNode.textContent = formatMoney(quickServicePaidBefore);
                }

                if (balanceDueNode) {
                    balanceDueNode.textContent = formatMoney(balanceDue);
                }

                if (balanceDueCard) {
                    balanceDueCard.classList.toggle('is-danger', isUnderpaid);
                }

                if (recognizedPaymentNode) {
                    recognizedPaymentNode.textContent = formatMoney(recognizedPayment);
                }

                if (changeDueNode) {
                    changeDueNode.textContent = formatMoney(changeDue);
                }

                if (changeField) {
                    changeField.hidden = changeDue <= 0;
                }

                if (!hasPaymentInput && balanceDue > 0) {
                    paymentMessage = supportsHoldAction
                        ? t('Enter the amount received, or use Hold bill to keep this bill open without adding a payment.')
                        : t('Enter the amount received to continue.');
                } else if (isUnderpaid) {
                    paymentMessage = interpolate(t('Outstanding :amount THB. Payment can be recorded, but the bill will stay open until fully paid.'), {
                        amount: formatMoney(balanceDue - recognizedPayment),
                    });
                    paymentMessageState = 'is-danger';
                } else if (isOverpaid && !isCashPayment) {
                    paymentMessage = t('Received amount is higher than the amount due. Adjust Received now to match before closing the bill.');
                    paymentMessageState = 'is-danger';
                } else if (changeDue > 0) {
                    paymentMessage = interpolate(t('Change due :amount THB. Cash payment can close the bill.'), {
                        amount: formatMoney(changeDue),
                    });
                    paymentMessageState = 'is-success';
                } else if (hasPaymentInput && willCloseBill) {
                    paymentMessage = t('Payment is enough to close the bill.');
                    paymentMessageState = 'is-success';
                }

                if (paymentValidationMessage) {
                    paymentValidationMessage.textContent = paymentMessage;
                    paymentValidationMessage.classList.remove('is-danger', 'is-success');

                    if (paymentMessageState !== '') {
                        paymentValidationMessage.classList.add(paymentMessageState);
                    }
                }

                if (receivedAmountInput) {
                    receivedAmountInput.classList.toggle('is-danger', isUnderpaid || (isOverpaid && !isCashPayment));
                }

                if (paySubmitButton) {
                    paySubmitButton.disabled = !allowPayment;
                }

                updateQuickServiceQrPreview(balanceDue, receivedAmount);
                updatePaymentSlipField();
                updateDepositSlipFields();
                updateDepositQrPanels();
            }

            validateBookingTotal();
        };

        if (totalPriceInput) {
            totalPriceInput.addEventListener('input', () => {
                totalPriceEdited = true;
                validateBookingTotal();
            });
            totalPriceInput.addEventListener('blur', () => {
                normalizeMoneyInput(totalPriceInput);
                updateSummary();
            });
            protectNumberInputFromWheel(totalPriceInput);
        }

        if (receivedAmountInput) {
            receivedAmountInput.addEventListener('input', updateSummary);
            receivedAmountInput.addEventListener('blur', () => {
                normalizeMoneyInput(receivedAmountInput);
                updateSummary();
            });
            protectNumberInputFromWheel(receivedAmountInput);
        }

        if (paymentMethodSelect) {
            paymentMethodSelect.addEventListener('change', updateSummary);
        }

        if (branchNameInput) {
            branchNameInput.addEventListener('change', () => {
                updateDepositQrPanels();
                updateSummary();
            });
        }

        depositSlipGroups.forEach((item) => {
            if (item.amountInput instanceof HTMLInputElement) {
                item.amountInput.addEventListener('input', updateDepositSlipFields);
                item.amountInput.addEventListener('input', updateDepositQrPanels);
                item.amountInput.addEventListener('blur', () => {
                    updateDepositSlipFields();
                    updateDepositQrPanels();
                });
            }

            if (item.methodSelect instanceof HTMLSelectElement) {
                item.methodSelect.addEventListener('change', () => {
                    updateDepositSlipFields();
                    updateDepositQrPanels();
                });
            }
        });

        if (isQuickServiceForm) {
            bookingForm.addEventListener('keydown', (event) => {
                if (event.key !== 'Enter') {
                    return;
                }

                const target = event.target;
                if (!(target instanceof HTMLElement)) {
                    return;
                }

                const tagName = target.tagName;
                const inputType = target instanceof HTMLInputElement ? target.type : '';
                const isSubmitControl = tagName === 'BUTTON' || inputType === 'submit' || inputType === 'button';

                if (tagName !== 'TEXTAREA' && !isSubmitControl) {
                    event.preventDefault();
                }
            });

            bookingForm.addEventListener('submit', (event) => {
                const submitter = event.submitter;
                const submitAction = submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement
                    ? submitter.value
                    : '';

                if (!['hold', 'pay'].includes(submitAction)) {
                    event.preventDefault();

                    if (paymentValidationMessage) {
                        paymentValidationMessage.textContent = supportsHoldAction
                            ? t('Use the Hold bill or Payment button to continue.')
                            : t('Use the Payment button to continue.');
                        paymentValidationMessage.classList.remove('is-success');
                        paymentValidationMessage.classList.add('is-danger');
                    }

                    return;
                }

                if (submitAction === 'pay') {
                    const state = quickServicePaymentState();

                    if (!state.allowPayment) {
                        event.preventDefault();
                        updateSummary();
                    }
                }
            });
        }

        if (!isQuickServiceForm) {
            bookingForm.addEventListener('submit', (event) => {
                const submitter = event.submitter;
                const usesAlternateSubmitFlow = submitter instanceof HTMLElement
                    && (submitter.hasAttribute('formnovalidate') || (submitter.getAttribute('formmethod') || '').toUpperCase() === 'GET');

                if (usesAlternateSubmitFlow) {
                    return;
                }

                if (!syncFilmSearchInputs(bookingForm, true)) {
                    event.preventDefault();
                    bookingForm.querySelector('[data-film-search]:invalid')?.reportValidity();
                    return;
                }

                if (!validateBookingTotal()) {
                    event.preventDefault();
                    totalPriceInput?.reportValidity();
                }
            });
        }

        if (lookupButton) {
            lookupButton.addEventListener('click', searchCustomer);
        }

        if (newCustomerButton) {
            newCustomerButton.addEventListener('click', startNewCustomerRegistration);
        }

        [lookupPhoneField].filter(Boolean).forEach((field) => {
            field.addEventListener('keydown', (event) => {
                if (event.key === 'Enter') {
                    searchCustomer(event);
                }
            });
        });

        checkboxes.forEach((checkbox) => checkbox.addEventListener('change', updateSummary));
        packageUsageSelects.forEach((select) => select.addEventListener('change', updateSummary));
        mainServiceGroupInputs.forEach((input) => input.addEventListener('change', updateSummary));
        syncQuickServiceCustomerFields();
        updateSummary();
        updateDepositSlipFields();
        updateDepositQrPanels();
    }

    const appPhotoModal = document.querySelector('[data-app-photo-modal]');
    const appPhotoModalImage = appPhotoModal?.querySelector('[data-app-photo-modal-image]');
    const appPhotoModalTitle = appPhotoModal?.querySelector('[data-app-photo-modal-title]');
    const appPhotoModalCloseButtons = appPhotoModal
        ? Array.from(appPhotoModal.querySelectorAll('[data-app-photo-modal-close]'))
        : [];
    const appPhotoModalDefaultTitle = appPhotoModalTitle instanceof HTMLElement
        ? appPhotoModalTitle.textContent.trim()
        : t('Vehicle profile photo');
    const appPhotoZoomHint = t('Click photo to view a larger image');
    let appPhotoModalCloseTimer = 0;
    let appPhotoModalReturnFocus = null;
    let appPhotoModalZoomed = false;
    let appPhotoModalLastTapAt = 0;
    let appPhotoModalSwipeStartX = 0;
    let appPhotoModalSwipeStartY = 0;
    let appPhotoModalSwipeStartAt = 0;
    let appPhotoModalSwipeActive = false;

    const clampAppPhotoPercentage = (value) => Math.max(0, Math.min(100, value));

    const readAppPhotoPayload = (element) => {
        if (!(element instanceof HTMLElement)) {
            return null;
        }

        const srcFromData = String(element.dataset.photoSrc || '').trim();
        const srcFromImage = element instanceof HTMLImageElement
            ? String(element.getAttribute('src') || '').trim()
            : '';
        const src = srcFromData !== '' ? srcFromData : srcFromImage;
        if (src === '') {
            return null;
        }

        const altFromData = String(element.dataset.photoAlt || '').trim();
        const altFromImage = element instanceof HTMLImageElement
            ? String(element.getAttribute('alt') || '').trim()
            : '';

        return {
            src,
            alt: altFromData !== '' ? altFromData : altFromImage,
            title: String(element.dataset.photoTitle || '').trim(),
        };
    };

    const setAppPhotoModalZoom = (zoomed, originX = 50, originY = 50) => {
        if (!(appPhotoModalImage instanceof HTMLImageElement)) {
            return;
        }

        appPhotoModalZoomed = !!zoomed;
        appPhotoModalImage.classList.toggle('is-zoomed', appPhotoModalZoomed);
        appPhotoModalImage.style.transformOrigin = appPhotoModalZoomed
            ? `${clampAppPhotoPercentage(originX)}% ${clampAppPhotoPercentage(originY)}%`
            : '50% 50%';
    };

    const toggleAppPhotoModalZoomFromPoint = (clientX, clientY) => {
        if (!(appPhotoModalImage instanceof HTMLImageElement)) {
            return;
        }

        if (appPhotoModalZoomed) {
            setAppPhotoModalZoom(false);
            return;
        }

        const bounds = appPhotoModalImage.getBoundingClientRect();
        if (bounds.width <= 0 || bounds.height <= 0) {
            setAppPhotoModalZoom(true, 50, 50);
            return;
        }

        const originX = ((clientX - bounds.left) / bounds.width) * 100;
        const originY = ((clientY - bounds.top) / bounds.height) * 100;
        setAppPhotoModalZoom(true, originX, originY);
    };

    const closeAppPhotoModal = () => {
        if (!(appPhotoModal instanceof HTMLElement)) {
            return;
        }

        if (appPhotoModalCloseTimer) {
            window.clearTimeout(appPhotoModalCloseTimer);
            appPhotoModalCloseTimer = 0;
        }

        const finalizeClose = () => {
            if (!(appPhotoModal instanceof HTMLElement)) {
                return;
            }

            appPhotoModal.hidden = true;
            appPhotoModal.setAttribute('aria-hidden', 'true');
            appPhotoModal.classList.remove('is-open');
            document.body.classList.remove('app-photo-modal-open');
            setAppPhotoModalZoom(false);
            appPhotoModalLastTapAt = 0;
            appPhotoModalSwipeActive = false;

            if (appPhotoModalImage instanceof HTMLImageElement) {
                appPhotoModalImage.removeAttribute('src');
                appPhotoModalImage.alt = '';
            }

            if (appPhotoModalTitle instanceof HTMLElement) {
                appPhotoModalTitle.textContent = appPhotoModalDefaultTitle;
            }

            if (appPhotoModalReturnFocus instanceof HTMLElement) {
                appPhotoModalReturnFocus.focus();
            }
            appPhotoModalReturnFocus = null;
        };

        if (appPhotoModal.hidden) {
            finalizeClose();
            return;
        }

        appPhotoModal.classList.remove('is-open');
        appPhotoModal.setAttribute('aria-hidden', 'true');
        document.body.classList.remove('app-photo-modal-open');
        appPhotoModalCloseTimer = window.setTimeout(finalizeClose, 180);
    };

    const openAppPhotoModal = (payload, trigger = null) => {
        if (
            !(appPhotoModal instanceof HTMLElement)
            || !(appPhotoModalImage instanceof HTMLImageElement)
            || !payload
        ) {
            return;
        }

        const nextSrc = String(payload.src || '').trim();
        if (nextSrc === '') {
            return;
        }

        if (appPhotoModalCloseTimer) {
            window.clearTimeout(appPhotoModalCloseTimer);
            appPhotoModalCloseTimer = 0;
        }

        const nextTitle = String(payload.title || '').trim() || appPhotoModalDefaultTitle;

        setAppPhotoModalZoom(false);
        appPhotoModalLastTapAt = 0;
        appPhotoModalSwipeActive = false;
        appPhotoModalImage.src = nextSrc;
        appPhotoModalImage.alt = String(payload.alt || '').trim();

        if (appPhotoModalTitle instanceof HTMLElement) {
            appPhotoModalTitle.textContent = nextTitle;
        }

        appPhotoModalReturnFocus = trigger instanceof HTMLElement ? trigger : null;
        appPhotoModal.hidden = false;
        appPhotoModal.setAttribute('aria-hidden', 'false');
        document.body.classList.add('app-photo-modal-open');
        window.requestAnimationFrame(() => {
            appPhotoModal.classList.add('is-open');
        });

        const closeButton = appPhotoModal.querySelector('[data-app-photo-modal-close-button]');
        if (closeButton instanceof HTMLElement) {
            closeButton.focus();
        }
    };

    const hydrateProfilePhotoTriggers = (root = document) => {
        if (!root || typeof root.querySelectorAll !== 'function') {
            return;
        }

        root.querySelectorAll('img.vehicle-profile-photo, img[data-profile-photo-expand]').forEach((node) => {
            if (!(node instanceof HTMLImageElement)) {
                return;
            }

            const src = String(node.getAttribute('src') || '').trim();
            if (src === '') {
                return;
            }

            if (!node.hasAttribute('data-profile-photo-expand')) {
                node.setAttribute('data-profile-photo-expand', '');
            }

            node.dataset.photoSrc = src;
            node.dataset.photoAlt = String(node.getAttribute('alt') || '').trim();

            if (!node.dataset.photoTitle || node.dataset.photoTitle.trim() === '') {
                node.dataset.photoTitle = appPhotoModalDefaultTitle;
            }

            if (!node.hasAttribute('tabindex')) {
                node.setAttribute('tabindex', '0');
            }

            if (!node.hasAttribute('role')) {
                node.setAttribute('role', 'button');
            }

            if (!node.hasAttribute('aria-label')) {
                node.setAttribute('aria-label', appPhotoZoomHint);
            }
        });
    };

    hydrateProfilePhotoTriggers(document);

    if (typeof MutationObserver !== 'undefined' && document.body) {
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (!(node instanceof Element)) {
                        return;
                    }

                    if (node.matches('img.vehicle-profile-photo, img[data-profile-photo-expand]')) {
                        hydrateProfilePhotoTriggers(node);
                        return;
                    }

                    if (node.querySelector('img.vehicle-profile-photo, img[data-profile-photo-expand]')) {
                        hydrateProfilePhotoTriggers(node);
                    }
                });
            });
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true,
        });
    }

    if (appPhotoModalImage instanceof HTMLImageElement) {
        appPhotoModalImage.addEventListener('dblclick', (event) => {
            if (appPhotoModal instanceof HTMLElement && !appPhotoModal.hidden) {
                event.preventDefault();
                toggleAppPhotoModalZoomFromPoint(event.clientX, event.clientY);
            }
        });

        appPhotoModalImage.addEventListener('click', (event) => {
            if (appPhotoModal instanceof HTMLElement && !appPhotoModal.hidden && appPhotoModalZoomed) {
                event.preventDefault();
                setAppPhotoModalZoom(false);
            }
        });

        appPhotoModalImage.addEventListener('touchend', (event) => {
            if (!(appPhotoModal instanceof HTMLElement) || appPhotoModal.hidden) {
                return;
            }

            if (!event.changedTouches || event.changedTouches.length === 0) {
                return;
            }

            const now = Date.now();
            const touch = event.changedTouches[0];

            if (now - appPhotoModalLastTapAt <= 280) {
                event.preventDefault();
                toggleAppPhotoModalZoomFromPoint(touch.clientX, touch.clientY);
                appPhotoModalLastTapAt = 0;
                return;
            }

            appPhotoModalLastTapAt = now;
        }, { passive: false });
    }

    if (appPhotoModal instanceof HTMLElement) {
        appPhotoModal.addEventListener('touchstart', (event) => {
            if (appPhotoModal.hidden || !event.touches || event.touches.length !== 1) {
                appPhotoModalSwipeActive = false;
                return;
            }

            const touch = event.touches[0];
            appPhotoModalSwipeStartX = touch.clientX;
            appPhotoModalSwipeStartY = touch.clientY;
            appPhotoModalSwipeStartAt = Date.now();
            appPhotoModalSwipeActive = true;
        }, { passive: true });

        appPhotoModal.addEventListener('touchend', (event) => {
            if (!appPhotoModalSwipeActive || appPhotoModalZoomed) {
                appPhotoModalSwipeActive = false;
                return;
            }

            appPhotoModalSwipeActive = false;
            if (!event.changedTouches || event.changedTouches.length === 0) {
                return;
            }

            const touch = event.changedTouches[0];
            const deltaX = touch.clientX - appPhotoModalSwipeStartX;
            const deltaY = touch.clientY - appPhotoModalSwipeStartY;
            const duration = Date.now() - appPhotoModalSwipeStartAt;

            if (
                duration <= 700
                && deltaY > 92
                && Math.abs(deltaY) > (Math.abs(deltaX) * 1.2)
            ) {
                closeAppPhotoModal();
            }
        }, { passive: true });
    }

    appPhotoModalCloseButtons.forEach((button) => {
        button.addEventListener('click', (event) => {
            event.preventDefault();
            closeAppPhotoModal();
        });
    });

    document.addEventListener('click', (event) => {
        const target = event.target;
        if (!(target instanceof Element)) {
            return;
        }

        // Keep Open Bill custom photo modal behavior isolated.
        if (target.closest('[data-open-bill-photo-expand]')) {
            return;
        }

        const trigger = target.closest('[data-profile-photo-expand]');
        if (trigger instanceof HTMLElement) {
            const payload = readAppPhotoPayload(trigger);
            if (!payload) {
                return;
            }

            event.preventDefault();
            event.stopPropagation();
            openAppPhotoModal(payload, trigger);
            return;
        }

        const closeTrigger = target.closest('[data-app-photo-modal-close]');
        if (closeTrigger instanceof HTMLElement) {
            event.preventDefault();
            closeAppPhotoModal();
        }
    });

    document.addEventListener('keydown', (event) => {
        const keyboardTarget = event.target;

        if (
            (event.key === 'Enter' || event.key === ' ')
            && keyboardTarget instanceof Element
            && !keyboardTarget.closest('[data-open-bill-photo-expand]')
        ) {
            const trigger = keyboardTarget.closest('[data-profile-photo-expand]');
            if (trigger instanceof HTMLElement) {
                const payload = readAppPhotoPayload(trigger);
                if (payload) {
                    event.preventDefault();
                    event.stopPropagation();
                    openAppPhotoModal(payload, trigger);
                    return;
                }
            }
        }

        if (
            event.key === 'Escape'
            && appPhotoModal instanceof HTMLElement
            && !appPhotoModal.hidden
        ) {
            event.preventDefault();
            closeAppPhotoModal();
        }
    });

    const openBillRoot = document.querySelector('[data-open-bill-root]');

    if (openBillRoot) {
        const searchForm = openBillRoot.querySelector('[data-open-bill-search-form]');
        const searchInput = openBillRoot.querySelector('[data-open-bill-search-input]');
        const searchButton = openBillRoot.querySelector('[data-open-bill-search-button]');
        const feedback = openBillRoot.querySelector('[data-open-bill-feedback]');
        const liveResults = openBillRoot.querySelector('[data-open-bill-live-results]');
        const newCustomerLink = openBillRoot.querySelector('[data-open-bill-new-customer]');
        const textNode = openBillRoot.querySelector('[data-open-bill-text]');
        const serverSections = Array.from(document.querySelectorAll('[data-open-bill-server-section]'));
        const selectedContextRoot = document.querySelector('[data-open-bill-selected-context-root]');
        const newFormSection = document.querySelector('[data-open-bill-new-form]');
        const newForm = newFormSection?.querySelector('[data-open-bill-new-form-fields]');
        const saveButton = newFormSection?.querySelector('[data-open-bill-save-button]') || newForm?.querySelector('button[type="submit"]');
        const resetLink = newFormSection?.querySelector('[data-open-bill-reset-link]');
        const lookupQueryField = document.querySelector('[data-open-bill-lookup-query]');
        const newCustomerNameField = document.querySelector('[data-open-bill-customer-name]');
        const newPhoneField = document.querySelector('[data-open-bill-phone]');
        const newPlateField = document.querySelector('[data-open-bill-plate]');
        const photoInputs = Array.from(document.querySelectorAll('[data-open-bill-photo-input]'));
        const photoPreview = document.querySelector('[data-open-bill-photo-preview]');
        const photoImage = document.querySelector('[data-open-bill-photo-image]');
        const photoPlaceholder = document.querySelector('[data-open-bill-photo-placeholder]');
        const photoHint = document.querySelector('[data-open-bill-photo-hint]');
        const photoModal = document.querySelector('[data-open-bill-photo-modal]');
        const photoModalImage = photoModal?.querySelector('[data-open-bill-photo-modal-image]');
        const photoModalTitle = photoModal?.querySelector('[data-open-bill-photo-modal-title]');
        const photoModalCloseButtons = photoModal
            ? Array.from(photoModal.querySelectorAll('[data-open-bill-photo-modal-close]'))
            : [];
        const openBillTexts = (() => {
            if (!textNode) {
                return {};
            }

            try {
                return JSON.parse(textNode.textContent || '{}');
            } catch (error) {
                return {};
            }
        })();

        const readOpenBillText = (key, fallback = '') => {
            const value = openBillTexts[key];
            return typeof value === 'string' && value !== '' ? value : fallback;
        };

        const openBillLanguage = typeof window.CCW_LANG === 'string' && window.CCW_LANG.trim() !== ''
            ? window.CCW_LANG.trim().toLowerCase()
            : String(document.documentElement.lang || 'en').trim().toLowerCase();

        const normalizeOpenBillMessage = (message) => {
            const nextMessage = String(message || '').trim();
            if (!nextMessage.startsWith('__CCW_FLASH__')) {
                return nextMessage;
            }

            try {
                const payload = JSON.parse(nextMessage.slice('__CCW_FLASH__'.length));
                if (!payload || typeof payload !== 'object') {
                    return nextMessage;
                }

                if (openBillLanguage.startsWith('th') && typeof payload.th === 'string' && payload.th.trim() !== '') {
                    return payload.th.trim();
                }

                if (typeof payload.en === 'string' && payload.en.trim() !== '') {
                    return payload.en.trim();
                }

                if (typeof payload.th === 'string' && payload.th.trim() !== '') {
                    return payload.th.trim();
                }
            } catch (error) {
                return nextMessage;
            }

            return nextMessage;
        };

        const readOpenBillPhotoPayload = (element) => {
            if (!(element instanceof HTMLElement)) {
                return null;
            }

            const srcFromData = String(element.dataset.photoSrc || '').trim();
            const srcFromImage = element instanceof HTMLImageElement
                ? String(element.getAttribute('src') || '').trim()
                : '';
            const src = srcFromData !== '' ? srcFromData : srcFromImage;
            if (src === '') {
                return null;
            }

            const altFromData = String(element.dataset.photoAlt || '').trim();
            const altFromImage = element instanceof HTMLImageElement
                ? String(element.getAttribute('alt') || '').trim()
                : '';

            return {
                src,
                alt: altFromData !== '' ? altFromData : altFromImage,
                title: String(element.dataset.photoTitle || '').trim(),
            };
        };

        const openBillModalDefaultTitle = photoModalTitle instanceof HTMLElement
            ? photoModalTitle.textContent.trim()
            : readOpenBillText('photoModalTitle', 'Vehicle profile photo');
        let openBillPhotoModalReturnFocus = null;
        let openBillPhotoModalZoomed = false;
        let openBillPhotoModalLastTapAt = 0;
        let openBillPhotoModalSwipeStartX = 0;
        let openBillPhotoModalSwipeStartY = 0;
        let openBillPhotoModalSwipeStartAt = 0;
        let openBillPhotoModalSwipeActive = false;

        const clampOpenBillPercentage = (value) => Math.max(0, Math.min(100, value));

        const setOpenBillPhotoModalZoom = (zoomed, originX = 50, originY = 50) => {
            if (!(photoModalImage instanceof HTMLImageElement)) {
                return;
            }

            openBillPhotoModalZoomed = !!zoomed;
            photoModalImage.classList.toggle('is-zoomed', openBillPhotoModalZoomed);
            photoModalImage.style.transformOrigin = openBillPhotoModalZoomed
                ? `${clampOpenBillPercentage(originX)}% ${clampOpenBillPercentage(originY)}%`
                : '50% 50%';
        };

        const toggleOpenBillPhotoModalZoomFromPoint = (clientX, clientY) => {
            if (!(photoModalImage instanceof HTMLImageElement)) {
                return;
            }

            if (openBillPhotoModalZoomed) {
                setOpenBillPhotoModalZoom(false);
                return;
            }

            const bounds = photoModalImage.getBoundingClientRect();
            if (bounds.width <= 0 || bounds.height <= 0) {
                setOpenBillPhotoModalZoom(true, 50, 50);
                return;
            }

            const originX = ((clientX - bounds.left) / bounds.width) * 100;
            const originY = ((clientY - bounds.top) / bounds.height) * 100;
            setOpenBillPhotoModalZoom(true, originX, originY);
        };

        const closeOpenBillPhotoModal = () => {
            if (!(photoModal instanceof HTMLElement)) {
                return;
            }

            if (openBillPhotoModalCloseTimer) {
                window.clearTimeout(openBillPhotoModalCloseTimer);
                openBillPhotoModalCloseTimer = 0;
            }

            const finalizeClose = () => {
                if (!(photoModal instanceof HTMLElement)) {
                    return;
                }

                photoModal.hidden = true;
                photoModal.setAttribute('aria-hidden', 'true');
                photoModal.classList.remove('is-open');
                document.body.classList.remove('open-bill-photo-modal-open');
                setOpenBillPhotoModalZoom(false);
                openBillPhotoModalLastTapAt = 0;
                openBillPhotoModalSwipeActive = false;

                if (photoModalImage instanceof HTMLImageElement) {
                    photoModalImage.removeAttribute('src');
                    photoModalImage.alt = '';
                }

                if (photoModalTitle instanceof HTMLElement) {
                    photoModalTitle.textContent = openBillModalDefaultTitle;
                }

                if (openBillPhotoModalReturnFocus instanceof HTMLElement) {
                    openBillPhotoModalReturnFocus.focus();
                }
                openBillPhotoModalReturnFocus = null;
            };

            if (photoModal.hidden) {
                finalizeClose();
                return;
            }

            photoModal.classList.remove('is-open');
            photoModal.setAttribute('aria-hidden', 'true');
            document.body.classList.remove('open-bill-photo-modal-open');
            openBillPhotoModalCloseTimer = window.setTimeout(finalizeClose, 180);
        };

        const openOpenBillPhotoModal = (payload, trigger = null) => {
            if (
                !(photoModal instanceof HTMLElement)
                || !(photoModalImage instanceof HTMLImageElement)
                || !payload
            ) {
                return;
            }

            const nextSrc = String(payload.src || '').trim();
            if (nextSrc === '') {
                return;
            }

            if (openBillPhotoModalCloseTimer) {
                window.clearTimeout(openBillPhotoModalCloseTimer);
                openBillPhotoModalCloseTimer = 0;
            }

            const nextTitle = String(payload.title || '').trim()
                || readOpenBillText('photoModalTitle', 'Vehicle profile photo');

            setOpenBillPhotoModalZoom(false);
            openBillPhotoModalLastTapAt = 0;
            openBillPhotoModalSwipeActive = false;
            photoModalImage.src = nextSrc;
            photoModalImage.alt = String(payload.alt || '').trim();

            if (photoModalTitle instanceof HTMLElement) {
                photoModalTitle.textContent = nextTitle;
            }

            openBillPhotoModalReturnFocus = trigger instanceof HTMLElement ? trigger : null;
            photoModal.hidden = false;
            photoModal.setAttribute('aria-hidden', 'false');
            document.body.classList.add('open-bill-photo-modal-open');
            window.requestAnimationFrame(() => {
                photoModal.classList.add('is-open');
            });

            const closeButton = photoModal.querySelector('[data-open-bill-photo-modal-close-button]');
            if (closeButton instanceof HTMLElement) {
                closeButton.focus();
            }
        };

        const hydrateOpenBillPhotoTriggers = (root = document) => {
            if (!root || typeof root.querySelectorAll !== 'function') {
                return;
            }

            root.querySelectorAll('.open-bill-match-photo').forEach((node) => {
                if (!(node instanceof HTMLImageElement)) {
                    return;
                }

                if (!node.hasAttribute('data-open-bill-photo-expand')) {
                    node.setAttribute('data-open-bill-photo-expand', '');
                    node.dataset.photoSrc = String(node.getAttribute('src') || '').trim();
                    node.dataset.photoAlt = String(node.getAttribute('alt') || '').trim();
                    node.dataset.photoTitle = readOpenBillText('photoModalTitle', 'Vehicle profile photo');
                }

                if (!node.hasAttribute('tabindex')) {
                    node.setAttribute('tabindex', '0');
                }
                if (!node.hasAttribute('role')) {
                    node.setAttribute('role', 'button');
                }
                if (!node.hasAttribute('aria-label')) {
                    node.setAttribute('aria-label', readOpenBillText('photoZoomHint', 'Click photo to view a larger image'));
                }

                const card = node.closest('.open-bill-match-card');
                if (card instanceof HTMLElement) {
                    card.classList.add('open-bill-match-card--with-photo');
                }
            });
        };

        const initialQuery = String(openBillRoot.dataset.initialQuery || '').trim();
        const initialFeedbackMessage = feedback ? feedback.textContent.trim() : '';
        const initialFeedbackState = feedback?.dataset.state || '';
        const initialNewFormVisible = newFormSection ? !newFormSection.hidden : false;
        const searchEndpoint = openBillRoot.dataset.searchEndpoint || '../process/search_customer.php';
        const baseUrl = openBillRoot.dataset.baseUrl || 'open_bill.php';
        const loginUrl = openBillRoot.dataset.loginUrl || 'login.php';
        const landingUrl = openBillRoot.dataset.landingUrl || 'dashboard.php';
        const initialMatchCount = Number(openBillRoot.dataset.matchCount || 0);
        const hasSelectedContext = openBillRoot.dataset.hasSelectedContext === '1';
        const saveButtonLabel = saveButton instanceof HTMLButtonElement ? saveButton.textContent.trim() : '';
        const saveButtonMarkup = saveButton instanceof HTMLButtonElement ? saveButton.innerHTML : '';
        const defaultPhotoHint = photoHint ? photoHint.textContent.trim() : readOpenBillText('photoDefaultHint', 'Upload or capture a vehicle photo to keep as the vehicle profile image. Vehicle details are filled in by staff.');
        let stableQuery = initialQuery;
        let stableFeedbackMessage = initialFeedbackMessage;
        let stableFeedbackState = initialFeedbackState;
        let stableNewFormVisible = initialNewFormVisible;
        let stableDynamicSelectedHtml = '';
        let requestSequence = 0;
        let debounceTimer = 0;
        let redirectTimer = 0;
        let liveResultLinks = [];
        let openBillPhotoObjectUrl = '';
        let openBillPhotoModalCloseTimer = 0;

        const setOpenBillFeedback = (message, state = '') => {
            if (!feedback) {
                return;
            }

            const nextMessage = normalizeOpenBillMessage(message);
            feedback.textContent = nextMessage;
            feedback.dataset.state = state;
            feedback.hidden = nextMessage.trim() === '';
        };

        const clearOpenBillResults = () => {
            if (!liveResults) {
                return;
            }

            liveResults.innerHTML = '';
            liveResults.hidden = true;
            liveResultLinks = [];
        };

        const setOpenBillServerSectionsHidden = (hidden) => {
            serverSections.forEach((section) => {
                section.hidden = hidden;
            });
        };

        const setOpenBillSelectedContextHtml = (html) => {
            if (!selectedContextRoot) {
                return;
            }

            const nextHtml = String(html || '').trim();
            selectedContextRoot.innerHTML = nextHtml;
            selectedContextRoot.hidden = nextHtml === '';
            if (nextHtml !== '') {
                hydrateOpenBillPhotoTriggers(selectedContextRoot);
            }
        };

        const setOpenBillLoading = (isLoading) => {
            openBillRoot.classList.toggle('is-loading', isLoading);
            openBillRoot.setAttribute('aria-busy', isLoading ? 'true' : 'false');

            if (searchButton instanceof HTMLButtonElement) {
                searchButton.disabled = isLoading;
            }

            if (saveButton instanceof HTMLButtonElement) {
                saveButton.disabled = isLoading;
            }
        };

        const setOpenBillSavePending = (isPending) => {
            if (newForm instanceof HTMLFormElement) {
                newForm.querySelectorAll('input, select, textarea').forEach((field) => {
                    const isInput = field instanceof HTMLInputElement;
                    const isSelectable = field instanceof HTMLSelectElement || field instanceof HTMLTextAreaElement;

                    if (!isInput && !isSelectable) {
                        return;
                    }

                    if (isInput && field.type === 'hidden') {
                        return;
                    }

                    field.disabled = isPending;
                });
            }

            if (saveButton instanceof HTMLButtonElement) {
                saveButton.disabled = isPending;
                if (saveButtonMarkup !== '') {
                    if (isPending) {
                        saveButton.textContent = readOpenBillText('saving', 'Saving customer and vehicle...');
                    } else {
                        saveButton.innerHTML = saveButtonMarkup;
                    }
                } else if (saveButtonLabel !== '') {
                    saveButton.textContent = isPending
                        ? readOpenBillText('saving', 'Saving customer and vehicle...')
                        : saveButtonLabel;
                }
            }

            if (resetLink instanceof HTMLAnchorElement) {
                resetLink.classList.toggle('is-disabled', isPending);
                resetLink.setAttribute('aria-disabled', isPending ? 'true' : 'false');
                if (isPending) {
                    resetLink.tabIndex = -1;
                } else {
                    resetLink.removeAttribute('tabindex');
                }
            }
        };

        const getOpenBillSelectedSection = () => {
            if (selectedContextRoot && !selectedContextRoot.hidden) {
                const dynamicSelectedSection = selectedContextRoot.querySelector('[data-open-bill-selected-section]');
                if (dynamicSelectedSection instanceof HTMLElement) {
                    return dynamicSelectedSection;
                }
            }

            const serverSelectedSection = document.querySelector('[data-open-bill-selected-section]');
            return serverSelectedSection instanceof HTMLElement ? serverSelectedSection : null;
        };

        const focusOpenBillPrimaryAction = () => {
            const selectedSection = getOpenBillSelectedSection();

            if (!(selectedSection instanceof HTMLElement)) {
                return;
            }

            const primaryAction = selectedSection.querySelector('.open-bill-action-grid a, .open-bill-action-grid button');
            if (!(primaryAction instanceof HTMLElement)) {
                return;
            }

            window.requestAnimationFrame(() => {
                primaryAction.focus();
                primaryAction.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            });
        };

        const scrollOpenBillSelectedSectionIntoView = () => {
            const selectedSection = getOpenBillSelectedSection();
            if (!(selectedSection instanceof HTMLElement)) {
                return;
            }

            window.requestAnimationFrame(() => {
                selectedSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
            });
        };

        const resolveOpenBillRedirectUrl = (data, fallbackUrl = '') => {
            const redirectUrl = typeof data?.redirect_url === 'string' ? data.redirect_url.trim() : '';
            return redirectUrl !== '' ? redirectUrl : fallbackUrl;
        };

        const queueOpenBillRedirect = (url, message, state = 'warning') => {
            const nextUrl = String(url || '').trim();
            if (nextUrl === '') {
                return false;
            }

            requestSequence += 1;
            if (debounceTimer) {
                window.clearTimeout(debounceTimer);
            }
            if (redirectTimer) {
                window.clearTimeout(redirectTimer);
            }

            setOpenBillLoading(false);
            setOpenBillSavePending(false);
            setOpenBillFeedback(message, state);

            redirectTimer = window.setTimeout(() => {
                window.location.assign(nextUrl);
            }, 900);

            return true;
        };

        const readOpenBillJsonResponse = async (response) => {
            const contentType = String(response.headers.get('content-type') || '').toLowerCase();
            if (!contentType.includes('application/json')) {
                return null;
            }

            try {
                return await response.json();
            } catch (error) {
                return null;
            }
        };

        const handleOpenBillAuthResponse = (response, data) => {
            if (response.status === 401) {
                return queueOpenBillRedirect(
                    resolveOpenBillRedirectUrl(data, loginUrl),
                    data?.message || readOpenBillText('sessionExpiredRedirecting', 'Your session expired. Redirecting to login...'),
                    'warning'
                );
            }

            if (response.status === 403) {
                return queueOpenBillRedirect(
                    resolveOpenBillRedirectUrl(data, landingUrl),
                    data?.message || readOpenBillText('permissionRedirecting', 'You no longer have permission to use this page. Redirecting...'),
                    'error'
                );
            }

            if (response.status === 419) {
                return queueOpenBillRedirect(
                    resolveOpenBillRedirectUrl(data, baseUrl),
                    data?.message || readOpenBillText('refreshingOpenBill', 'This page expired. Refreshing Open Bill...'),
                    'warning'
                );
            }

            const redirectedUrl = response.redirected && typeof response.url === 'string'
                ? response.url.trim()
                : '';

            if (data === null && redirectedUrl !== '') {
                const fallbackMessage = redirectedUrl.includes('login.php')
                    ? readOpenBillText('sessionExpiredRedirecting', 'Your session expired. Redirecting to login...')
                    : readOpenBillText('refreshingOpenBill', 'This page expired. Refreshing Open Bill...');
                return queueOpenBillRedirect(redirectedUrl, fallbackMessage, 'warning');
            }

            return false;
        };

        const clearOpenBillFieldErrors = () => {
            if (!(newForm instanceof HTMLFormElement)) {
                return;
            }

            newForm.querySelectorAll('input, select, textarea').forEach((field) => {
                if (
                    field instanceof HTMLInputElement ||
                    field instanceof HTMLSelectElement ||
                    field instanceof HTMLTextAreaElement
                ) {
                    field.setCustomValidity('');
                    field.removeAttribute('aria-invalid');
                }
            });
        };

        const resetOpenBillPhotoPreview = () => {
            if (openBillPhotoObjectUrl !== '') {
                window.URL.revokeObjectURL(openBillPhotoObjectUrl);
                openBillPhotoObjectUrl = '';
            }

            if (photoImage instanceof HTMLImageElement) {
                photoImage.src = '';
                photoImage.hidden = true;
            }

            if (photoPreview instanceof HTMLElement) {
                photoPreview.classList.remove('has-image');
                photoPreview.classList.remove('is-clickable');
                delete photoPreview.dataset.openBillPhotoExpand;
                delete photoPreview.dataset.photoSrc;
                delete photoPreview.dataset.photoAlt;
                delete photoPreview.dataset.photoTitle;
                photoPreview.removeAttribute('tabindex');
                photoPreview.removeAttribute('role');
                photoPreview.removeAttribute('aria-label');
            }

            if (photoPlaceholder instanceof HTMLElement) {
                photoPlaceholder.hidden = false;
            }

            if (photoHint instanceof HTMLElement) {
                photoHint.textContent = defaultPhotoHint;
            }
        };

        const updateOpenBillPhotoPreview = (file) => {
            if (!(file instanceof File)) {
                resetOpenBillPhotoPreview();
                return;
            }

            if (openBillPhotoObjectUrl !== '') {
                window.URL.revokeObjectURL(openBillPhotoObjectUrl);
            }

            openBillPhotoObjectUrl = window.URL.createObjectURL(file);

            if (photoImage instanceof HTMLImageElement) {
                photoImage.src = openBillPhotoObjectUrl;
                photoImage.hidden = false;
            }

            if (photoPreview instanceof HTMLElement) {
                photoPreview.classList.add('has-image');
                photoPreview.classList.add('is-clickable');
                photoPreview.dataset.openBillPhotoExpand = '1';
                photoPreview.dataset.photoSrc = openBillPhotoObjectUrl;
                photoPreview.dataset.photoAlt = photoImage instanceof HTMLImageElement
                    ? String(photoImage.getAttribute('alt') || '').trim()
                    : '';
                photoPreview.dataset.photoTitle = readOpenBillText('photoModalTitle', 'Vehicle profile photo');
                photoPreview.setAttribute('tabindex', '0');
                photoPreview.setAttribute('role', 'button');
                photoPreview.setAttribute('aria-label', readOpenBillText('photoZoomHint', 'Click photo to view a larger image'));
            }

            if (photoPlaceholder instanceof HTMLElement) {
                photoPlaceholder.hidden = true;
            }

            if (photoHint instanceof HTMLElement) {
                photoHint.textContent = readOpenBillText('photoReady', 'Vehicle photo is ready to be saved as the profile image.');
            }
        };

        const applyOpenBillFieldErrors = (fieldErrors) => {
            if (!(newForm instanceof HTMLFormElement) || !fieldErrors || typeof fieldErrors !== 'object') {
                return false;
            }

            let firstInvalidField = null;

            Object.entries(fieldErrors).forEach(([fieldName, message]) => {
                const field = newForm.querySelector(`[name="${fieldName}"]`);
                const nextMessage = normalizeOpenBillMessage(message);

                if (
                    nextMessage === '' ||
                    !(
                        field instanceof HTMLInputElement ||
                        field instanceof HTMLSelectElement ||
                        field instanceof HTMLTextAreaElement
                    )
                ) {
                    return;
                }

                field.setCustomValidity(nextMessage);
                field.setAttribute('aria-invalid', 'true');

                if (!firstInvalidField) {
                    firstInvalidField = field;
                }
            });

            if (!firstInvalidField) {
                return false;
            }

            firstInvalidField.reportValidity();
            firstInvalidField.focus();
            return true;
        };

        const validateOpenBillRequiredFields = () => {
            const requiredFields = [
                {
                    field: newCustomerNameField,
                    message: readOpenBillText('customerNameRequired', 'Customer name is required.'),
                },
                {
                    field: newPlateField,
                    message: readOpenBillText('plateNumberRequired', 'Plate number is required.'),
                },
            ];

            let firstInvalidField = null;
            let hasError = false;

            requiredFields.forEach(({ field, message }) => {
                if (!(field instanceof HTMLInputElement)) {
                    return;
                }

                field.value = field.value.trim();
                field.setCustomValidity('');
                field.removeAttribute('aria-invalid');

                if (field.value !== '') {
                    return;
                }

                hasError = true;
                field.setCustomValidity(message);
                field.setAttribute('aria-invalid', 'true');

                if (!firstInvalidField) {
                    firstInvalidField = field;
                }
            });

            if (!hasError || !(firstInvalidField instanceof HTMLInputElement)) {
                return true;
            }

            setOpenBillFeedback(
                readOpenBillText('requiredFieldsMessage', 'Customer name and plate number are required before saving.'),
                'error'
            );
            firstInvalidField.reportValidity();
            firstInvalidField.focus();
            return false;
        };

        const resetOpenBillNewFormDraft = () => {
            if (!(newForm instanceof HTMLFormElement)) {
                return;
            }

            newForm.querySelectorAll('input[type="text"]').forEach((field) => {
                if (field instanceof HTMLInputElement) {
                    field.value = '';
                }
            });

            newForm.querySelectorAll('select').forEach((field) => {
                if (field instanceof HTMLSelectElement) {
                    field.selectedIndex = 0;
                }
            });

            if (lookupQueryField instanceof HTMLInputElement) {
                lookupQueryField.value = searchInput ? searchInput.value.trim() : '';
            }

            photoInputs.forEach((photoInput) => {
                if (photoInput instanceof HTMLInputElement) {
                    photoInput.value = '';
                    photoInput.dispatchEvent(new Event('change', { bubbles: true }));
                }
            });

            resetOpenBillPhotoPreview();
            clearOpenBillFieldErrors();
        };

        const classifyOpenBillQuery = (query) => {
            const trimmed = String(query || '').trim();
            if (trimmed === '') {
                return '';
            }

            const digitCount = trimmed.replace(/\D+/g, '').length;
            if (/^[\d\s()+-]+$/.test(trimmed) && digitCount >= 8) {
                return 'phone';
            }

            return 'plate';
        };

        const setOpenBillNewFormVisible = (visible, query = '', options = {}) => {
            if (!newFormSection) {
                return;
            }

            const {
                focus = false,
                preserveInput = true,
            } = options;
            const nextQuery = String(query || '').trim();
            const queryType = classifyOpenBillQuery(nextQuery);

            newFormSection.hidden = !visible;

            if (lookupQueryField instanceof HTMLInputElement) {
                lookupQueryField.value = nextQuery;
            }

            if (!visible) {
                return;
            }

            if (!preserveInput) {
                if (newForm instanceof HTMLFormElement) {
                    newForm.querySelectorAll('input[type="text"]').forEach((field) => {
                        if (field instanceof HTMLInputElement) {
                            field.value = '';
                        }
                    });

                    newForm.querySelectorAll('select').forEach((field) => {
                        if (field instanceof HTMLSelectElement) {
                            field.selectedIndex = 0;
                        }
                    });
                }

                photoInputs.forEach((photoInput) => {
                    if (photoInput instanceof HTMLInputElement) {
                        photoInput.value = '';
                        photoInput.dispatchEvent(new Event('change', { bubbles: true }));
                    }
                });

                resetOpenBillPhotoPreview();
                clearOpenBillFieldErrors();
            }

            if (queryType === 'phone' && newPhoneField instanceof HTMLInputElement && (!preserveInput || newPhoneField.value.trim() === '')) {
                newPhoneField.value = nextQuery;
            }

            if (queryType === 'plate' && newPlateField instanceof HTMLInputElement && (!preserveInput || newPlateField.value.trim() === '')) {
                newPlateField.value = nextQuery;
            }

            if (focus) {
                if (queryType === 'phone' && newCustomerNameField instanceof HTMLInputElement) {
                    newCustomerNameField.focus();
                    return;
                }

                if (queryType === 'plate' && newCustomerNameField instanceof HTMLInputElement) {
                    newCustomerNameField.focus();
                    return;
                }

                if (newCustomerNameField instanceof HTMLInputElement) {
                    newCustomerNameField.focus();
                }
            }
        };

        const buildOpenBillNewCustomerHref = (query) => {
            const params = new URLSearchParams();
            params.set('new', '1');

            if (query !== '') {
                params.set('q', query);
            }

            return `${baseUrl}?${params.toString()}`;
        };

        const updateOpenBillNewCustomerHref = (query) => {
            if (newCustomerLink) {
                newCustomerLink.href = buildOpenBillNewCustomerHref(query);
            }
        };

        const buildOpenBillResultHref = (query, match) => {
            const params = new URLSearchParams();
            params.set('search', '1');

            if (query !== '') {
                params.set('q', query);
            }

            params.set('customer_id', String(Number(match.customerId || 0)));
            params.set('car_id', String(Number(match.carId || 0)));

            return `${baseUrl}?${params.toString()}`;
        };

        const appendOpenBillTextLine = (container, text, className = '') => {
            const value = String(text || '').trim();
            if (value === '') {
                return;
            }

            const line = document.createElement('span');
            if (className !== '') {
                line.className = className;
            }
            line.textContent = value;
            container.append(line);
        };

        const focusOpenBillResult = (index) => {
            if (liveResultLinks.length === 0) {
                return;
            }

            const boundedIndex = Math.max(0, Math.min(index, liveResultLinks.length - 1));
            liveResultLinks[boundedIndex].focus();
        };

        const renderOpenBillResults = (matches, query) => {
            if (!liveResults) {
                return;
            }

            liveResults.innerHTML = '';
            liveResultLinks = [];

            matches.forEach((match, index) => {
                const card = document.createElement('a');
                const image = document.createElement('img');
                const head = document.createElement('div');
                const title = document.createElement('strong');
                const badge = document.createElement('span');
                const stack = document.createElement('div');
                const plateCard = document.createElement('span');
                const plate = document.createElement('span');
                const province = document.createElement('span');
                const vehicleName = [match.brand, match.model].filter(Boolean).join(' ').trim();

                card.className = 'open-bill-match-card';
                card.href = buildOpenBillResultHref(query, match);
                card.dataset.resultIndex = String(index);

                if (String(match.profileImageUrl || '').trim() !== '') {
                    card.classList.add('open-bill-match-card--with-photo');
                    image.className = 'open-bill-match-photo';
                    image.src = String(match.profileImageUrl || '').trim();
                    image.alt = String(match.profileImageName || '').trim() || 'Vehicle photo';
                    image.dataset.openBillPhotoExpand = '1';
                    image.dataset.photoSrc = image.src;
                    image.dataset.photoAlt = image.alt;
                    image.dataset.photoTitle = readOpenBillText('photoModalTitle', 'Vehicle profile photo');
                    image.tabIndex = 0;
                    image.setAttribute('role', 'button');
                    image.setAttribute('aria-label', readOpenBillText('photoZoomHint', 'Click photo to view a larger image'));
                    card.append(image);
                }

                head.className = 'open-bill-match-head';
                title.textContent = String(match.customerName || '').trim() || readOpenBillText('unnamedCustomer', 'Unnamed customer');
                badge.className = 'badge badge-secondary';
                badge.textContent = String(match.customerGroupLabel || '').trim();
                head.append(title);
                if (badge.textContent !== '') {
                    head.append(badge);
                }

                stack.className = 'stack';
                appendOpenBillTextLine(stack, match.phone || '-');

                plateCard.className = 'plate-card';
                plate.className = 'plate';
                plate.textContent = String(match.plateNumber || '').trim() || readOpenBillText('noPlate', 'No plate');
                plateCard.append(plate);

                if (String(match.province || '').trim() !== '') {
                    province.className = 'plate-province';
                    province.textContent = String(match.province || '').trim();
                    plateCard.append(province);
                }

                stack.append(plateCard);
                appendOpenBillTextLine(
                    stack,
                    vehicleName !== '' ? vehicleName : readOpenBillText('vehiclePending', 'Vehicle details pending'),
                    'muted'
                );
                appendOpenBillTextLine(stack, match.color || '', 'muted');

                card.addEventListener('keydown', (event) => {
                    if (event.key === 'ArrowDown') {
                        event.preventDefault();
                        focusOpenBillResult(index + 1);
                        return;
                    }

                    if (event.key === 'ArrowUp') {
                        event.preventDefault();

                        if (index === 0) {
                            searchInput?.focus();
                            return;
                        }

                        focusOpenBillResult(index - 1);
                    }
                });

                card.append(head, stack);
                liveResults.append(card);
                liveResultLinks.push(card);
            });

            liveResults.hidden = matches.length === 0;
        };

        hydrateOpenBillPhotoTriggers(document);

        if (photoModalImage instanceof HTMLImageElement) {
            photoModalImage.addEventListener('dblclick', (event) => {
                if (photoModal instanceof HTMLElement && !photoModal.hidden) {
                    event.preventDefault();
                    toggleOpenBillPhotoModalZoomFromPoint(event.clientX, event.clientY);
                }
            });

            photoModalImage.addEventListener('click', (event) => {
                if (photoModal instanceof HTMLElement && !photoModal.hidden && openBillPhotoModalZoomed) {
                    event.preventDefault();
                    setOpenBillPhotoModalZoom(false);
                }
            });

            photoModalImage.addEventListener('touchend', (event) => {
                if (!(photoModal instanceof HTMLElement) || photoModal.hidden) {
                    return;
                }

                if (!event.changedTouches || event.changedTouches.length === 0) {
                    return;
                }

                const now = Date.now();
                const touch = event.changedTouches[0];

                if (now - openBillPhotoModalLastTapAt <= 280) {
                    event.preventDefault();
                    toggleOpenBillPhotoModalZoomFromPoint(touch.clientX, touch.clientY);
                    openBillPhotoModalLastTapAt = 0;
                    return;
                }

                openBillPhotoModalLastTapAt = now;
            }, { passive: false });
        }

        if (photoModal instanceof HTMLElement) {
            photoModal.addEventListener('touchstart', (event) => {
                if (photoModal.hidden || !event.touches || event.touches.length !== 1) {
                    openBillPhotoModalSwipeActive = false;
                    return;
                }

                const touch = event.touches[0];
                openBillPhotoModalSwipeStartX = touch.clientX;
                openBillPhotoModalSwipeStartY = touch.clientY;
                openBillPhotoModalSwipeStartAt = Date.now();
                openBillPhotoModalSwipeActive = true;
            }, { passive: true });

            photoModal.addEventListener('touchend', (event) => {
                if (!openBillPhotoModalSwipeActive || openBillPhotoModalZoomed) {
                    openBillPhotoModalSwipeActive = false;
                    return;
                }

                openBillPhotoModalSwipeActive = false;
                if (!event.changedTouches || event.changedTouches.length === 0) {
                    return;
                }

                const touch = event.changedTouches[0];
                const deltaX = touch.clientX - openBillPhotoModalSwipeStartX;
                const deltaY = touch.clientY - openBillPhotoModalSwipeStartY;
                const duration = Date.now() - openBillPhotoModalSwipeStartAt;

                if (
                    duration <= 700
                    && deltaY > 92
                    && Math.abs(deltaY) > (Math.abs(deltaX) * 1.2)
                ) {
                    closeOpenBillPhotoModal();
                }
            }, { passive: true });
        }

        photoModalCloseButtons.forEach((button) => {
            button.addEventListener('click', (event) => {
                event.preventDefault();
                closeOpenBillPhotoModal();
            });
        });

        document.addEventListener('click', (event) => {
            const target = event.target;
            if (!(target instanceof Element)) {
                return;
            }

            const trigger = target.closest('[data-open-bill-photo-expand]');
            if (trigger instanceof HTMLElement) {
                const payload = readOpenBillPhotoPayload(trigger);
                if (!payload) {
                    return;
                }

                event.preventDefault();
                event.stopPropagation();
                openOpenBillPhotoModal(payload, trigger);
                return;
            }

            const closeTrigger = target.closest('[data-open-bill-photo-modal-close]');
            if (closeTrigger instanceof HTMLElement) {
                event.preventDefault();
                closeOpenBillPhotoModal();
            }
        });

        document.addEventListener('keydown', (event) => {
            const keyboardTarget = event.target;
            if (
                (event.key === 'Enter' || event.key === ' ')
                && keyboardTarget instanceof Element
            ) {
                const trigger = keyboardTarget.closest('[data-open-bill-photo-expand]');
                if (trigger instanceof HTMLElement) {
                    const payload = readOpenBillPhotoPayload(trigger);
                    if (payload) {
                        event.preventDefault();
                        event.stopPropagation();
                        openOpenBillPhotoModal(payload, trigger);
                        return;
                    }
                }
            }

            if (
                event.key === 'Escape'
                && photoModal instanceof HTMLElement
                && !photoModal.hidden
            ) {
                event.preventDefault();
                closeOpenBillPhotoModal();
            }
        });

        const restoreOpenBillInitialState = () => {
            closeOpenBillPhotoModal();
            clearOpenBillResults();
            setOpenBillLoading(false);
            setOpenBillSavePending(false);
            updateOpenBillNewCustomerHref(searchInput ? searchInput.value.trim() : '');

            if (stableDynamicSelectedHtml !== '') {
                setOpenBillServerSectionsHidden(true);
                setOpenBillSelectedContextHtml(stableDynamicSelectedHtml);
            } else {
                setOpenBillSelectedContextHtml('');
                setOpenBillServerSectionsHidden(false);
            }

            setOpenBillNewFormVisible(stableNewFormVisible, searchInput ? searchInput.value.trim() : stableQuery, {
                preserveInput: true,
            });

            if (stableFeedbackMessage !== '') {
                setOpenBillFeedback(stableFeedbackMessage, stableFeedbackState);
                return;
            }

            setOpenBillFeedback('', '');
        };

        const resetOpenBillToStableState = () => {
            if (openBillRoot.classList.contains('is-loading')) {
                return;
            }

            requestSequence += 1;

            if (debounceTimer) {
                window.clearTimeout(debounceTimer);
            }

            if (searchInput) {
                searchInput.value = stableQuery;
            }

            updateOpenBillNewCustomerHref(stableQuery);
            resetOpenBillNewFormDraft();
            restoreOpenBillInitialState();

            if (searchInput) {
                searchInput.focus();
            }
        };

        const searchOpenBillMatches = async () => {
            if (!searchInput) {
                return;
            }

            const query = searchInput.value.trim();

            if (query === '' || query === stableQuery) {
                restoreOpenBillInitialState();
                return;
            }

            const currentRequest = ++requestSequence;
            const params = new URLSearchParams();
            params.set('q', query);

            setOpenBillServerSectionsHidden(true);
            setOpenBillSelectedContextHtml('');
            setOpenBillNewFormVisible(false, query, { preserveInput: true });
            setOpenBillLoading(true);
            setOpenBillFeedback(readOpenBillText('searching', 'Searching...'), '');
            clearOpenBillResults();

            try {
                const response = await fetch(`${searchEndpoint}?${params.toString()}`, {
                    headers: {
                        Accept: 'application/json',
                    },
                });
                const data = await readOpenBillJsonResponse(response);

                if (currentRequest !== requestSequence) {
                    return;
                }

                if (handleOpenBillAuthResponse(response, data)) {
                    return;
                }

                if (!response.ok || !data?.success) {
                    throw new Error(data.message || readOpenBillText('lookupFailed', 'Customer lookup failed.'));
                }

                const matches = Array.isArray(data.matches) ? data.matches : [];

                if (matches.length === 0) {
                    setOpenBillFeedback(readOpenBillText('notFound', 'No matching customer was found. You can register a new customer to continue.'), 'warning');
                    setOpenBillNewFormVisible(true, query, {
                        preserveInput: false,
                    });
                    return;
                }

                renderOpenBillResults(matches, query);

                if (matches.length === 1) {
                    setOpenBillFeedback(readOpenBillText('singleMatch', 'Found 1 match. Select it to continue.'), 'success');
                    return;
                }

                setOpenBillFeedback(
                    readOpenBillText('foundTemplate', 'Found {count} matches. Choose the correct record.').replace('{count}', String(matches.length)),
                    'success'
                );
            } catch (error) {
                if (currentRequest !== requestSequence) {
                    return;
                }

                setOpenBillNewFormVisible(false, query, { preserveInput: true });
                setOpenBillFeedback(error.message || readOpenBillText('lookupFailed', 'Customer lookup failed.'), 'error');
            } finally {
                if (currentRequest === requestSequence) {
                    setOpenBillLoading(false);
                }
            }
        };

        if (searchInput) {
            updateOpenBillNewCustomerHref(searchInput.value.trim());

            searchInput.addEventListener('input', () => {
                const query = searchInput.value.trim();
                updateOpenBillNewCustomerHref(query);
                if (lookupQueryField instanceof HTMLInputElement) {
                    lookupQueryField.value = query;
                }
                requestSequence += 1;

                if (debounceTimer) {
                    window.clearTimeout(debounceTimer);
                }

                if (query === '' || query === stableQuery) {
                    restoreOpenBillInitialState();
                    return;
                }

                setOpenBillSelectedContextHtml('');
                setOpenBillNewFormVisible(false, query, { preserveInput: true });

                debounceTimer = window.setTimeout(() => {
                    searchOpenBillMatches();
                }, 220);
            });

            searchInput.addEventListener('keydown', (event) => {
                const hasVisibleResults = !!liveResults && !liveResults.hidden && liveResultLinks.length > 0;

                if (event.key === 'ArrowDown' && hasVisibleResults) {
                    event.preventDefault();
                    focusOpenBillResult(0);
                    return;
                }

                if (event.key === 'Enter' && hasVisibleResults && liveResultLinks.length === 1) {
                    event.preventDefault();
                    liveResultLinks[0].click();
                    return;
                }

                if (event.key === 'Escape' && (hasVisibleResults || !newFormSection?.hidden || searchInput.value.trim() !== stableQuery)) {
                    event.preventDefault();
                    resetOpenBillToStableState();
                }
            });
        }

        if (searchForm) {
            searchForm.addEventListener('submit', () => {
                requestSequence += 1;

                if (debounceTimer) {
                    window.clearTimeout(debounceTimer);
                }
            });
        }

        if (newForm instanceof HTMLFormElement) {
            newForm.noValidate = true;
            if (saveButton instanceof HTMLButtonElement) {
                saveButton.formNoValidate = true;
            }

            newForm.querySelectorAll('input, select, textarea').forEach((field) => {
                if (
                    !(
                        field instanceof HTMLInputElement ||
                        field instanceof HTMLSelectElement ||
                        field instanceof HTMLTextAreaElement
                    )
                ) {
                    return;
                }

                const clearFieldError = () => {
                    field.setCustomValidity('');
                    field.removeAttribute('aria-invalid');
                };

                field.addEventListener('input', clearFieldError);
                field.addEventListener('change', clearFieldError);
                field.addEventListener('focus', clearFieldError);
            });

            photoInputs.forEach((photoInput) => {
                if (!(photoInput instanceof HTMLInputElement)) {
                    return;
                }

                photoInput.addEventListener('change', () => {
                    if (photoInput.files && photoInput.files.length > 0) {
                        photoInputs.forEach((otherInput) => {
                            if (otherInput instanceof HTMLInputElement && otherInput !== photoInput) {
                                otherInput.value = '';
                            }
                        });

                        updateOpenBillPhotoPreview(photoInput.files[0]);
                        return;
                    }

                    const fallbackFile = photoInputs
                        .filter((input) => input instanceof HTMLInputElement && input.files && input.files.length > 0)
                        .map((input) => input.files[0])[0] || null;
                    updateOpenBillPhotoPreview(fallbackFile);
                });
            });

            newForm.addEventListener('submit', (event) => {
                const submitter = event.submitter instanceof HTMLElement ? event.submitter : null;
                if (!submitter || submitter.dataset.openBillAjax !== '1') {
                    return;
                }

                event.preventDefault();
                requestSequence += 1;

                if (debounceTimer) {
                    window.clearTimeout(debounceTimer);
                }

                const query = searchInput ? searchInput.value.trim() : (lookupQueryField instanceof HTMLInputElement ? lookupQueryField.value.trim() : '');

                if (lookupQueryField instanceof HTMLInputElement) {
                    lookupQueryField.value = query;
                }

                clearOpenBillFieldErrors();
                if (!validateOpenBillRequiredFields()) {
                    return;
                }

                clearOpenBillResults();
                setOpenBillServerSectionsHidden(true);
                setOpenBillSelectedContextHtml('');
                setOpenBillNewFormVisible(true, query, { preserveInput: true });
                setOpenBillLoading(true);
                setOpenBillSavePending(true);
                setOpenBillFeedback(readOpenBillText('saving', 'Saving customer and vehicle...'), '');
            });

            newForm.addEventListener('keydown', (event) => {
                if (event.key !== 'Escape') {
                    return;
                }

                event.preventDefault();
                resetOpenBillToStableState();
            });
        }

        if (resetLink instanceof HTMLAnchorElement) {
            resetLink.addEventListener('click', (event) => {
                if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey || event.button !== 0) {
                    return;
                }

                event.preventDefault();
                resetOpenBillToStableState();
            });
        }

        if (newCustomerLink) {
            newCustomerLink.addEventListener('click', (event) => {
                if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey || event.button !== 0) {
                    return;
                }

                event.preventDefault();
                requestSequence += 1;

                if (debounceTimer) {
                    window.clearTimeout(debounceTimer);
                }

                clearOpenBillResults();
                setOpenBillServerSectionsHidden(true);
                setOpenBillSelectedContextHtml('');
                setOpenBillLoading(false);
                setOpenBillFeedback('', '');
                setOpenBillNewFormVisible(true, searchInput ? searchInput.value.trim() : '', {
                    focus: true,
                    preserveInput: false,
                });
            });
        }

        if (hasSelectedContext && initialMatchCount > 1) {
            window.setTimeout(() => {
                scrollOpenBillSelectedSectionIntoView();
                focusOpenBillPrimaryAction();
            }, 120);
        }
    }

    document.querySelectorAll('[data-deposit-manage-form]').forEach((depositForm) => {
        const amountInput = depositForm.querySelector('[data-deposit-amount-input]');
        const methodSelect = depositForm.querySelector('[data-deposit-method-select]');
        const slipGroup = depositForm.querySelector('[data-deposit-slip-group]');
        const slipInput = depositForm.querySelector('[data-deposit-slip-input]');
        const qrPanel = depositForm.querySelector('[data-deposit-qr-panel]');
        const qrHint = depositForm.querySelector('[data-deposit-qr-hint]');
        const qrImage = depositForm.querySelector('[data-deposit-qr-image]');
        const qrDownload = depositForm.querySelector('[data-deposit-qr-download]');
        const qrEndpoint = depositForm.dataset.qrEndpoint || '';
        const qrScope = depositForm.dataset.qrScope || '';
        const qrBranch = (depositForm.dataset.qrBranch || '').trim();
        const methodsWithSlipSupport = ['transfer', 'qr', 'card'];

        const formatMoney = (value) => Number(value || 0).toLocaleString('en-US', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
        });

        const parseAmount = () => {
            if (!amountInput) {
                return 0;
            }

            const numericValue = Number(String(amountInput.value || '').replace(/,/g, '').trim() || 0);
            return Number.isFinite(numericValue) ? Math.max(0, numericValue) : 0;
        };

        const updateSlipVisibility = () => {
            if (!slipGroup || !methodSelect) {
                return;
            }

            const showSlip = methodsWithSlipSupport.includes(methodSelect.value) && parseAmount() > 0;
            slipGroup.hidden = !showSlip;

            if (!showSlip && slipInput instanceof HTMLInputElement) {
                slipInput.value = '';
            }
        };

        const updateQrVisibility = () => {
            if (!qrPanel || !qrHint || !qrImage || !methodSelect) {
                return;
            }

            const amount = parseAmount();
            const showQr = methodSelect.value === 'qr' && amount > 0;
            qrPanel.hidden = !showQr;

            if (!showQr) {
                qrImage.removeAttribute('src');
                qrHint.textContent = t('Scan to receive payment.');
                if (qrDownload) {
                    qrDownload.hidden = true;
                    qrDownload.removeAttribute('href');
                }
                return;
            }

            const params = new URLSearchParams();
            params.set('amount', amount.toFixed(2));
            if (qrScope) {
                params.set('scope', qrScope);
            }
            if (qrBranch !== '') {
                params.set('branch', qrBranch);
            }

            const queryString = params.toString();
            if (qrEndpoint !== '') {
                qrImage.src = `${qrEndpoint}?${queryString}`;
                if (qrDownload) {
                    qrDownload.href = `${qrEndpoint}?${queryString}&download=1`;
                    qrDownload.hidden = false;
                }
            }

            qrHint.textContent = interpolate(t('Scan QR for :amount THB.'), { amount: formatMoney(amount) });
        };

        if (amountInput) {
            amountInput.addEventListener('input', () => {
                updateSlipVisibility();
                updateQrVisibility();
            });
        }

        if (methodSelect) {
            methodSelect.addEventListener('change', () => {
                updateSlipVisibility();
                updateQrVisibility();
            });
        }

        updateSlipVisibility();
        updateQrVisibility();
    });

    document.querySelectorAll('[data-service-edit-form]').forEach((serviceForm) => {
        const checkboxes = Array.from(serviceForm.querySelectorAll('[data-service-option]'));
        const countNode = serviceForm.querySelector('[data-selected-count]');
        const totalNode = serviceForm.querySelector('[data-selected-total]');
        const packageDiscountNode = serviceForm.querySelector('[data-selected-package-discount]');
        const totalPriceInput = serviceForm.querySelector('[data-total-price-input]');
        const packageUsageSelects = Array.from(serviceForm.querySelectorAll('[data-package-usage]'));
        const mainServiceGroupInputs = Array.from(serviceForm.querySelectorAll('[data-main-service-group]'));
        let totalPriceEdited = totalPriceInput ? totalPriceInput.value.trim() !== '' : false;

        const formatMoney = (value) => Number(value || 0).toLocaleString('en-US', {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
        });

        const updateSummary = () => {
            let count = 0;
            let total = 0;
            let packageDiscount = 0;

            syncLinkedGroupPanels(serviceForm);
            syncMainServiceFlows(serviceForm);
            syncWindowFilmPanels(serviceForm);

            checkboxes.forEach((checkbox) => {
                const packageSelect = serviceForm.querySelector(`[name="package_usage[${checkbox.value}]"]`);
                const serviceNoteInput = serviceForm.querySelector(`[name="service_notes[${checkbox.value}]"]`);

                if (packageSelect) {
                    const container = packageSelect.closest('[data-package-usage-container]');
                    packageSelect.disabled = !checkbox.checked || !!container?.hidden;
                }

                if (serviceNoteInput) {
                    serviceNoteInput.disabled = !checkbox.checked;
                }

                if (!checkbox.checked) {
                    return;
                }

                count += 1;
                total += Number(checkbox.dataset.price || 0);

                if (packageSelect && packageSelect.value !== '') {
                    packageDiscount += Number(checkbox.dataset.price || 0);
                }
            });

            if (countNode) {
                countNode.textContent = String(count);
            }

            if (totalNode) {
                totalNode.textContent = formatMoney(Math.max(0, total - packageDiscount));
            }

            if (packageDiscountNode) {
                packageDiscountNode.textContent = formatMoney(packageDiscount);
            }

            if (totalPriceInput && !totalPriceEdited) {
                totalPriceInput.value = Math.max(0, total - packageDiscount).toFixed(2);
            }
        };

        if (totalPriceInput) {
            totalPriceInput.addEventListener('input', () => {
                totalPriceEdited = true;
            });
        }

        checkboxes.forEach((checkbox) => checkbox.addEventListener('change', updateSummary));
        packageUsageSelects.forEach((select) => select.addEventListener('change', updateSummary));
        mainServiceGroupInputs.forEach((input) => input.addEventListener('change', updateSummary));
        serviceForm.addEventListener('submit', (event) => {
            if (syncFilmSearchInputs(serviceForm, true)) {
                return;
            }

            event.preventDefault();
            serviceForm.querySelector('[data-film-search]:invalid')?.reportValidity();
        });
        updateSummary();
    });

    document.querySelectorAll('[data-service-structure-form]').forEach((form) => {
        const typeSelect = form.querySelector('[data-service-type-select]');
        const categorySelect = form.querySelector('[data-service-category-select]');
        const mainServiceSelect = form.querySelector('[data-service-main-select]');
        const sync = () => syncServiceStructureForm(form);

        if (typeSelect) {
            typeSelect.addEventListener('change', sync);
        }

        if (categorySelect) {
            categorySelect.addEventListener('change', sync);
        }

        if (mainServiceSelect) {
            mainServiceSelect.addEventListener('change', sync);
        }

        sync();
    });

    document.querySelectorAll('[data-service-group-form]').forEach((form) => {
        const categorySelect = form.querySelector('[data-service-category-select]');
        const sync = () => syncServiceGroupForm(form);

        if (categorySelect) {
            categorySelect.addEventListener('change', sync);
        }

        sync();
    });

    document.querySelectorAll('[data-edit-toggle]').forEach((button) => {
        const panelId = button.getAttribute('aria-controls') || '';
        const panel = panelId ? document.getElementById(panelId) : null;

        if (!panel) {
            return;
        }

        const labelNode = button.querySelector('.app-action-button-label');
        const closedLabel = button.dataset.closedLabel || (labelNode ? labelNode.textContent.trim() : button.textContent.trim()) || t('Edit');
        const openLabel = button.dataset.openLabel || t('Hide');

        const setOpen = (isOpen) => {
            panel.hidden = !isOpen;
            button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
            if (labelNode) {
                labelNode.textContent = isOpen ? openLabel : closedLabel;
            } else {
                button.textContent = isOpen ? openLabel : closedLabel;
            }
            button.setAttribute('title', isOpen ? openLabel : closedLabel);
            button.setAttribute('aria-label', isOpen ? openLabel : closedLabel);

            if (isOpen) {
                panel.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
                const firstField = panel.querySelector('input:not([type="hidden"]), select, textarea');

                if (firstField) {
                    firstField.focus({ preventScroll: true });
                }
            }
        };

        button.addEventListener('click', () => {
            setOpen(panel.hidden);
        });
    });

    const photoPickerText = (thaiText, englishText) => {
        const language = String(document.documentElement.lang || window.CCW_LANG || '').toLowerCase();
        return language.startsWith('th') ? thaiText : englishText;
    };
    let activePhotoPicker = null;
    let photoCameraStream = null;
    let photoCameraModal = null;

    const stopPhotoCameraStream = () => {
        if (photoCameraStream) {
            photoCameraStream.getTracks().forEach((track) => track.stop());
            photoCameraStream = null;
        }
    };

    const ensurePhotoCameraModal = () => {
        if (photoCameraModal) {
            return photoCameraModal;
        }

        const modal = document.createElement('div');
        modal.className = 'photo-camera-modal';
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
        modal.innerHTML = `
            <button class="photo-camera-modal-backdrop" type="button" data-photo-camera-close aria-label="${photoPickerText('ปิดกล้อง', 'Close camera')}"></button>
            <section class="photo-camera-modal-dialog" role="dialog" aria-modal="true" aria-label="${photoPickerText('ถ่ายรูปรถ', 'Take vehicle photo')}">
                <div class="photo-camera-modal-head">
                    <strong>${photoPickerText('ถ่ายรูปรถ', 'Take vehicle photo')}</strong>
                    <button class="button button-ghost" type="button" data-photo-camera-close>${photoPickerText('ปิด', 'Close')}</button>
                </div>
                <video class="photo-camera-video" autoplay playsinline muted data-photo-camera-video></video>
                <canvas data-photo-camera-canvas hidden></canvas>
                <p class="photo-camera-error" data-photo-camera-error hidden></p>
                <div class="photo-camera-modal-actions">
                    <button class="button button-secondary" type="button" data-photo-camera-close>${photoPickerText('ยกเลิก', 'Cancel')}</button>
                    <button class="button button-accent" type="button" data-photo-camera-capture disabled>${photoPickerText('ใช้รูปนี้', 'Use this photo')}</button>
                </div>
            </section>
        `;
        document.body.appendChild(modal);

        modal.querySelectorAll('[data-photo-camera-close]').forEach((button) => {
            button.addEventListener('click', () => {
                closePhotoCameraModal();
            });
        });

        modal.querySelector('[data-photo-camera-capture]')?.addEventListener('click', () => {
            capturePhotoCameraFrame();
        });

        photoCameraModal = modal;
        return modal;
    };

    const closePhotoCameraModal = () => {
        stopPhotoCameraStream();

        if (!photoCameraModal) {
            activePhotoPicker = null;
            return;
        }

        const video = photoCameraModal.querySelector('[data-photo-camera-video]');
        if (video instanceof HTMLVideoElement) {
            video.srcObject = null;
        }

        photoCameraModal.classList.remove('is-open');
        photoCameraModal.setAttribute('aria-hidden', 'true');
        document.body.classList.remove('photo-camera-modal-open');
        window.setTimeout(() => {
            if (!photoCameraModal?.classList.contains('is-open')) {
                photoCameraModal.hidden = true;
            }
        }, 180);
        activePhotoPicker = null;
    };

    const updatePhotoPickerName = (picker) => {
        const input = picker.querySelector('[data-photo-picker-input]');
        const nameNode = picker.querySelector('[data-photo-picker-file-name]');
        const clearButton = picker.querySelector('[data-photo-picker-clear]');

        if (!(input instanceof HTMLInputElement) || !(nameNode instanceof HTMLElement)) {
            return;
        }

        const file = input.files && input.files.length > 0 ? input.files[0] : null;
        nameNode.textContent = file
            ? file.name
            : photoPickerText('ยังไม่ได้เลือกรูป', 'No image selected');
        picker.classList.toggle('has-file', Boolean(file));

        if (clearButton instanceof HTMLElement) {
            clearButton.hidden = !file;
        }
    };

    const setPhotoPickerError = (message) => {
        const modal = ensurePhotoCameraModal();
        const errorNode = modal.querySelector('[data-photo-camera-error]');

        if (errorNode instanceof HTMLElement) {
            errorNode.textContent = message;
            errorNode.hidden = false;
        }
    };

    const openPhotoCameraModal = async (picker) => {
        const modal = ensurePhotoCameraModal();
        const video = modal.querySelector('[data-photo-camera-video]');
        const captureButton = modal.querySelector('[data-photo-camera-capture]');
        const errorNode = modal.querySelector('[data-photo-camera-error]');

        activePhotoPicker = picker;
        stopPhotoCameraStream();

        if (errorNode instanceof HTMLElement) {
            errorNode.textContent = '';
            errorNode.hidden = true;
        }

        if (captureButton instanceof HTMLButtonElement) {
            captureButton.disabled = true;
        }

        modal.hidden = false;
        modal.setAttribute('aria-hidden', 'false');
        document.body.classList.add('photo-camera-modal-open');
        window.requestAnimationFrame(() => modal.classList.add('is-open'));

        if (!(video instanceof HTMLVideoElement) || !navigator.mediaDevices?.getUserMedia) {
            setPhotoPickerError(photoPickerText(
                'เบราว์เซอร์นี้ไม่รองรับการเปิดกล้อง กรุณาใช้ปุ่มเลือกรูปแทน',
                'This browser cannot open the camera. Please choose an image instead.'
            ));
            return;
        }

        try {
            photoCameraStream = await navigator.mediaDevices.getUserMedia({
                audio: false,
                video: {
                    facingMode: { ideal: 'environment' },
                },
            });
            video.srcObject = photoCameraStream;
            await video.play();

            if (captureButton instanceof HTMLButtonElement) {
                captureButton.disabled = false;
            }
        } catch (error) {
            setPhotoPickerError(photoPickerText(
                'ไม่สามารถเปิดกล้องได้ กรุณาอนุญาตการใช้งานกล้อง หรือใช้ปุ่มเลือกรูปแทน',
                'Unable to open the camera. Allow camera access or choose an image instead.'
            ));
        }
    };

    const capturePhotoCameraFrame = () => {
        const modal = ensurePhotoCameraModal();
        const video = modal.querySelector('[data-photo-camera-video]');
        const canvas = modal.querySelector('[data-photo-camera-canvas]');
        const input = activePhotoPicker?.querySelector('[data-photo-picker-input]');

        if (
            !(video instanceof HTMLVideoElement) ||
            !(canvas instanceof HTMLCanvasElement) ||
            !(input instanceof HTMLInputElement) ||
            video.videoWidth <= 0 ||
            video.videoHeight <= 0
        ) {
            setPhotoPickerError(photoPickerText('ยังไม่พบภาพจากกล้อง', 'Camera image is not ready yet.'));
            return;
        }

        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const context = canvas.getContext('2d');
        if (!context) {
            setPhotoPickerError(photoPickerText('ไม่สามารถจับภาพจากกล้องได้', 'Could not capture the camera image.'));
            return;
        }

        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        canvas.toBlob((blob) => {
            if (!blob || typeof File === 'undefined' || typeof DataTransfer === 'undefined') {
                setPhotoPickerError(photoPickerText('เบราว์เซอร์ไม่สามารถแนบรูปที่ถ่ายได้', 'This browser cannot attach the captured photo.'));
                return;
            }

            try {
                const file = new File([blob], `vehicle-photo-${Date.now()}.jpg`, { type: 'image/jpeg' });
                const transfer = new DataTransfer();
                transfer.items.add(file);
                input.files = transfer.files;
                input.dispatchEvent(new Event('change', { bubbles: true }));
                closePhotoCameraModal();
            } catch (error) {
                setPhotoPickerError(photoPickerText('เบราว์เซอร์ไม่สามารถแนบรูปที่ถ่ายได้', 'This browser cannot attach the captured photo.'));
            }
        }, 'image/jpeg', 0.9);
    };

    document.querySelectorAll('[data-photo-picker]').forEach((picker) => {
        const input = picker.querySelector('[data-photo-picker-input]');
        const cameraButton = picker.querySelector('[data-photo-picker-camera]');
        const selectButton = picker.querySelector('[data-photo-picker-select]');
        const clearButton = picker.querySelector('[data-photo-picker-clear]');

        if (!(picker instanceof HTMLElement) || !(input instanceof HTMLInputElement)) {
            return;
        }

        input.addEventListener('change', () => {
            updatePhotoPickerName(picker);
        });

        cameraButton?.addEventListener('click', () => {
            if (!navigator.mediaDevices?.getUserMedia) {
                input.setAttribute('capture', 'environment');
                input.click();
                window.setTimeout(() => {
                    input.removeAttribute('capture');
                }, 1000);
                return;
            }

            openPhotoCameraModal(picker);
        });

        selectButton?.addEventListener('click', () => {
            input.click();
        });

        clearButton?.addEventListener('click', () => {
            input.value = '';
            input.dispatchEvent(new Event('change', { bubbles: true }));
        });

        updatePhotoPickerName(picker);
    });

    document.querySelectorAll('[data-multi-role-permissions]').forEach((form) => {
        const toggleAll = form.querySelector('[data-multi-role-toggle-all]');
        const roleToggles = Array.from(form.querySelectorAll('[data-multi-role-toggle]'));

        if (roleToggles.length === 0) {
            return;
        }

        const syncMultiRoleColumns = () => {
            let checkedCount = 0;

            roleToggles.forEach((toggle) => {
                const columnId = toggle.dataset.columnId || '';
                const isVisible = toggle.checked;

                if (isVisible) {
                    checkedCount += 1;
                }

                form.querySelectorAll(`[data-multi-role-column-head="${columnId}"], [data-multi-role-column="${columnId}"]`).forEach((cell) => {
                    cell.hidden = !isVisible;
                });
            });

            if (toggleAll) {
                toggleAll.checked = checkedCount === roleToggles.length;
                toggleAll.indeterminate = checkedCount > 0 && checkedCount < roleToggles.length;
            }
        };

        if (toggleAll) {
            toggleAll.addEventListener('change', () => {
                roleToggles.forEach((toggle) => {
                    toggle.checked = toggleAll.checked;
                });

                syncMultiRoleColumns();
            });
        }

        roleToggles.forEach((toggle) => {
            toggle.addEventListener('change', syncMultiRoleColumns);
        });

        syncMultiRoleColumns();
    });
});
