/**
 * AccessiMate Frontend JavaScript
 * Modern accessibility toolbar functionality
 */

(function ($) {
    'use strict';

    class AccessiMateToolbar {
        constructor() {
            this.themeToggle = $('#accessimate-theme-toggle');
            this.toolbar = $('#accessimate-toolbar');
            this.toggle = $('#accessimate-toggle');
            this.panel = $('#accessimate-panel');
            this.close = $('#accessimate-close');
            this.fontSize = 100;
            this.isOpen = false;
            this.language = this.toolbar.data('accessimate-language') || 'en';
            this.excludedElements = ".accessimate-notification, .accessimate-notification *, .accessimate-toolbar, .accessimate-toolbar *, #wpadminbar, #wpadminbar *, rs-fullwidth-wrap, rs-fullwidth-wrap *, rs-module-wrap, rs-module-wrap *, sr7-module, sr7-module *";

            this.options = {
                biggerText: {
                    key: 'biggerText',
                    name: 'Bigger Text',
                    trigger: $('#accessimate-bigger-text'),
                    steps: ['default', 'small', 'medium', 'biggest'],
                    scales: { small: 0.25, medium: 0.5, biggest: 0.75 },
                },
                cursor: {
                    key: 'cursor',
                    name: 'Cursor',
                    trigger: $('#accessimate-cursor'),
                    steps: ['default', 'cursor-v1', 'cursor-v2', 'cursor-v3'],
                },
                lineHeight: {
                    key: 'lineHeight',
                    name: 'Line Height',
                    trigger: $('#accessimate-line-height'),
                    steps: ['default', 'small', 'medium', 'biggest'],
                    scales: { small: 0.25, medium: 0.5, biggest: 0.75 },
                },
                letterSpacing: {
                    key: 'letterSpacing',
                    name: 'Letter Spacing',
                    trigger: $('#accessimate-letter-spacing'),
                    steps: ['default', 'small', 'medium', 'biggest'],
                    scales: { small: 1, medium: 3, biggest: 5 },
                },
                readableFont: {
                    key: 'readableFont',
                    name: 'Readable Font',
                    trigger: $('#accessimate-readable-font'),
                },
                dyslexicFont: {
                    key: 'dyslexicFont',
                    name: 'Dyslexic Font',
                    trigger: $('#accessimate-dyslexic-font')
                },
                textAlign: {
                    key: 'textAlign',
                    name: 'Text Align',
                    trigger: $('#accessimate-text-align'),
                    steps: ['default', 'left', 'center', 'right'],
                },
                invertColors: {
                    key: 'invertColors',
                    name: 'Invert Colors',
                    trigger: $('#accessimate-invert-colors'),
                    steps: ['default', 'invert-v1', 'invert-v2', 'invert-v3'],
                },
                brightness: {
                    key: 'brightness',
                    name: 'Brightness',
                    trigger: $('#accessimate-brightness'),
                    steps: ['default', 'brightness-v1', 'brightness-v2', 'brightness-v3'],
                },
                grayscale: {
                    key: 'grayscale',
                    name: 'Grayscale',
                    trigger: $('#accessimate-grayscale'),
                    steps: ['default', 'grayscale-v1', 'grayscale-v2', 'grayscale-v3'],
                },
                saturation: {
                    key: 'saturation',
                    name: 'Saturation',
                    trigger: $('#accessimate-saturation'),
                    steps: ['default', 'saturation-v1', 'saturation-v2', 'saturation-v3'],
                },
                readingLine: {
                    key: 'readingLine',
                    name: 'Reading Line',
                    trigger: $('#accessimate-reading-line'),
                },
                readingMask: {
                    key: 'readingMask',
                    name: 'Reading Mask',
                    trigger: $('#accessimate-reading-mask'),
                    steps: ['default', 'rectangle', 'circle'],
                },
                highContrast: {
                    key: 'highContrast',
                    name: 'Contrast',
                    trigger: $('#accessimate-contrast'),
                    steps: ['default', 'dark', 'light', 'high-contrast'],
                },
                muteSounds: {
                    key: 'muteSounds',
                    name: 'Mute Sounds',
                    trigger: $('#accessimate-mute-sounds'),
                },
                hideImages: {
                    key: 'hideImages',
                    name: 'Hide Images',
                    trigger: $('#accessimate-hide-images'),
                },
                stopAnimations: {
                    key: 'stopAnimations',
                    name: 'Stop Animations',
                    trigger: $('#accessimate-stop-animations'),
                },
                textToSpeech: {
                    key: 'textToSpeech',
                    name: 'Text to Speech',
                    trigger: $('#accessimate-text-to-speech'),
                },
                textMagnifier: {
                    key: 'textMagnifier',
                    name: 'Text Magnifier',
                    trigger: $('#accessimate-text-magnifier'),
                },
                highlightTitles: {
                    key: 'highlightTitles',
                    name: 'Highlight Titles',
                    trigger: $('#accessimate-highlight-titles'),
                    steps: ['default', 'underline', 'box', 'background'],
                },
                highlightLinks: {
                    key: 'highlightLinks',
                    name: 'Highlight Links',
                    trigger: $('#accessimate-highlight-links'),
                    steps: ['default', 'underline', 'box', 'background'],
                },
                enhancedKeyboard: { // TODO: Need to add functionality
                    key: 'enhancedKeyboard',
                    name: 'Keyboard',
                    trigger: $('#accessimate-keyboard'),
                },
                highlightAll: { // TODO: Need to add functionality
                    key: 'highlightAll',
                    name: 'Highlight All',
                    trigger: $('#accessimate-highlight-all'),
                },
                resetAll: {
                    key: 'resetAll',
                    name: 'Reset All',
                    trigger: $('#accessimate-reset'),
                }
            };

            this.init();
            window.addEventListener('load', () => this.hasBackground());

        }

        init() {
            this.loaded();
            this.bindEvents();
            this.loadUserPreferences();
            this.setupAccessibilityFeatures();
            this.checkBackendSettings();
            // this.hasBackground();
        }

        loaded() {
            this.toggle.addClass('loaded');

            Object.keys(this.options).forEach(key => {
                this.updateButtonStatus(key);
            });
        }

        getTrigger($key) {
            return this.options[$key] ? this.options[$key].trigger : null;
        }

        bindEvents() {
            // Toggle panel
            this.toggle.on('click', (e) => {
                e.preventDefault();
                this.togglePanel();
            });

            // Close panel
            this.close.on('click', (e) => {
                e.preventDefault();
                this.closePanel();
            });

            // Theme toggle
            this.themeToggle.on('click', (e) => {
                e.preventDefault();
                this.toggleTheme();
            });

            Object.keys(this.options).forEach((id) => {

                if (typeof this[id] === 'function') {
                    this.getTrigger(id).on('click', (e) => {
                        e.preventDefault();

                        const isSteps = this.options[id]?.steps;
                        let value = null;
                        if (isSteps) {
                            let { _, value: level } = this.next(id);
                            value = level;
                        } else {
                            value = this.getPreferences(id) === 'enabled' ? 'disabled' : 'enabled';
                        }

                        if (!value) return;

                        this[id](value);
                        this.updateButtonStatus(id);
                    });
                }
            });

            this.getTrigger('resetAll').on('click', (e) => {
                e.preventDefault();
                this.reset();
            })

            // Close panel when clicking outside
            $(document).on('click', (e) => {
                if (!this.toolbar.is(e.target) && this.toolbar.has(e.target).length === 0) {
                    this.closePanel();
                }
            });

            // Keyboard navigation
            $(document).on('keydown', (e) => {
                if (e.key === 'Escape' && this.isOpen) {
                    this.closePanel();
                }

                if (e.key.toLowerCase() === 'a' && !this.isOpen && ((this.#isMac() && e.metaKey) || (!this.#isMac() && e.ctrlKey)) && !e.shiftKey) {
                    e.preventDefault();
                    this.openPanel();
                }

                if (e.key.toLowerCase() === 'r' && ((this.#isMac() && e.metaKey) || (!this.#isMac() && e.ctrlKey)) && e.shiftKey) {
                    this.reset(e);
                }

                if (e.key.toLowerCase() === 'm' && ((this.#isMac() && e.metaKey) || (!this.#isMac() && !e.ctrlKey)) && !e.shiftKey) {
                    e.preventDefault();
                    const value = this.getPreferences('muteSounds') === 'enabled' ? 'disabled' : 'enabled';
                    this.muteSounds(value);
                }
            });
        }

        #isMac() {
            if (navigator.userAgentData) {
                return navigator.userAgentData.platform === 'macOS';
            }
            return /Mac/i.test(navigator.userAgent);
        }

        togglePanel() {
            if (this.isOpen) {
                this.closePanel();
            } else {
                this.openPanel();
            }
        }

        panelAnimationClass(key, type = "in") {
            if (key === 'none') {
                return 'accessimate-animation-none';
            }

            if (key === 'fade') {
                return `accessimate-fade-${type}`;
            }

            const [direction, position] = key.split('-');

            return `accessimate-${direction}-${type}-${position}`;
        }

        openPanel() {
            const animationType = this.panel.data('animation') || 'slide-top';

            this.panel.show().removeClass(this.panelAnimationClass(animationType, 'out')).addClass('show ' + this.panelAnimationClass(animationType, 'in'));
            this.toggle.attr('aria-expanded', 'true');
            this.panel.attr('aria-hidden', 'false');
            this.isOpen = true;

            // Focus first button in panel
            setTimeout(() => {
                this.panel.find('button:first').focus();
            }, 100);
        }

        closePanel() {
            const animationType = this.panel.data('animation') || 'slide-top';
            this.panel.removeClass('show ' + this.panelAnimationClass(animationType, 'in')).addClass(this.panelAnimationClass(animationType, 'out')).delay(200);
            this.toggle.attr('aria-expanded', 'false');
            this.panel.attr('aria-hidden', 'true');
            this.isOpen = false;
        }

        toggleTheme() {
            const autoMode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
            const currentTheme = this.getPreferences('theme') || this.toolbar.attr('data-accessimate-theme') || autoMode;
            const newTheme = currentTheme === 'light' ? 'dark' : 'light';
            this.toolbar.attr('data-accessimate-theme', newTheme);
            this.savePreference('theme', newTheme);
            this.showNotification('Theme: ' + newTheme);
        }

        biggerText(level, notification = true) {
            this.applyTextStyle(level, {
                property: 'font-size',
                unit: 'px',
                scaleValues: this.options.biggerText.scales,
                notificationLabel: notification && 'Font size: ' + (100 + (this.options.biggerText.scales[level] * 100)) + '%'
            });
        }

        lineHeight(value, notification = true) {
            this.applyTextStyle(value, {
                property: 'line-height',
                unit: 'px',
                scaleValues: this.options.lineHeight.scales,
                notificationLabel: notification && 'Line height: ' + (100 + (this.options.lineHeight.scales[value] * 100)) + '%'
            });
        }

        decreaseFontSize() {
            if (this.fontSize > 70) {
                this.fontSize -= 10;
                this.updateFontSize();
            }
        }

        updateFontSize() {
            $('body').css('font-size', this.fontSize + '%');
            $('#accessimate-font-current').text(this.fontSize + '%');
            this.savePreference('fontSize', this.fontSize);
            this.showNotification('Font size: ' + this.fontSize + '%');
        }

        textMagnifier(value, notification = true) {
            const body = $('body');
            const magnifier = $('.accessimate-markup-text-magnifier');

            if (value === 'enabled') {
                if (!magnifier.length) {
                    const newMagnifier = $('<div class="accessimate-markup-text-magnifier"></div>');
                    body.append(newMagnifier);
                }

                $(document).on("mousemove", function (event) {
                    const windowWidth = $(window).width();
                    const windowHeight = $(window).height();
                    const element = document.elementFromPoint(event.clientX, event.clientY);

                    if (element && $(element).is('input, textarea, [contenteditable="true"], select, .accessimate-toolbar, .accessimate-toolbar *, .accessimate-markup-text-magnifier, .accessimate-markup-text-magnifier *')) {
                        return;
                    }

                    if (!$(element).hasClass("accessimate-markup-text-magnifier")) {
                        const text = element ? $(element).contents().filter(function () { return this.nodeType === 3; }).text().trim() : "";

                        $(".accessimate-markup-text-magnifier").text(text).toggle(!!text);
                        const position = {
                            left: event.pageX < windowWidth / 2 ? event.pageX + 15 : event.pageX - 115,
                            top: event.pageY < windowHeight / 2 ? event.pageY + 30 : event.pageY - 115
                        };
                        $(".accessimate-markup-text-magnifier").css(position);
                    }
                });
            } else {
                $(".accessimate-markup-text-magnifier").hide();
                $(document).off("mousemove");
            }
            if (notification) {
                this.showNotification(`Text magnifier ${value === 'enabled' ? 'enabled' : 'disabled'}`, value === 'enabled' ? 'success' : 'info');
            }
            this.savePreference('textMagnifier', value);
        }

        enhancedKeyboard(value, notification = true) {
            if ('default' === value || 'disabled' === value) {
                $('body').removeClass('accessimate-enhanced-keyboard');
            } else {
                $('body').addClass('accessimate-enhanced-keyboard');
            }

            this.savePreference('enhancedKeyboard', value);

            if (notification) {
                this.showNotification('Enhanced keyboard ' + (value === 'enabled' ? 'enabled' : 'disabled'));
            }
        }

        highlightAll(value, notification = true) {

            if ('default' === value || 'disabled' === value) {
                $('body').removeClass('accessimate-highlight-all');
            } else {
                $('body').addClass('accessimate-highlight-all');
            }

            this.savePreference('highlightAll', value);
            if (notification) {
                this.showNotification('Highlighting all elements ' + (value === 'enabled' ? 'enabled' : 'disabled'));
            }
        }

        reset(e = null) {
            const body = $('body');
            const LEVEL = 'default';
            let settings = 0;

            body.removeClass(function (index, className) {
                return (className.match(/\baccessimate-[^\s]+/g) || []).join(' ');
            });

            Object.keys(this.options).forEach(key => {
                const value = this.getPreferences(key);
                if (!value || value === LEVEL || value === 'disabled') return;
                settings++;

                if (e) {
                    e.preventDefault()
                }

                this.savePreference(key, LEVEL);
                this.updateButtonStatus(key);

                if (typeof this[key] === 'function') {
                    this[key](LEVEL, false);
                }
            });
            if (settings > 0) {
                this.showNotification(`All settings have been reset${settings ? ` (${settings} changed)` : ''}`, 'success');
            }
        }

        savePreference(key, value) {
            const preferences = this.getPreferences();
            preferences[key] = value;
            localStorage.setItem('accessimate_preferences', JSON.stringify(preferences));
        }

        getPreferences($key = null) {
            const stored = localStorage.getItem('accessimate_preferences');
            const preferences = stored ? JSON.parse(stored) : {};
            return $key ? preferences[$key] : preferences;
        }

        clearPreferences() {
            localStorage.removeItem('accessimate_preferences');
        }

        loadUserPreferences() {
            const preferences = this.getPreferences();

            if (preferences.theme) {
                this.toolbar.attr('data-accessimate-theme', preferences.theme);
            } else if (this.toolbar.attr('data-accessimate-theme') === 'auto') {
                const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
                if (darkModeMediaQuery.matches) {
                    this.toolbar.attr('data-accessimate-theme', 'dark');
                } else {
                    this.toolbar.attr('data-accessimate-theme', 'light');
                }
            }

            Object.keys(this.options).forEach(key => {
                if (!['default', 'disabled'].includes(preferences[key]) && preferences[key] && typeof this[key] === 'function') {
                    this[key](preferences[key], false);
                }
            });
        }

        setupAccessibilityFeatures() {
            // Add ARIA attributes
            this.toggle.attr({
                'aria-expanded': 'false',
                'aria-haspopup': 'true',
                'aria-controls': 'accessimate-panel'
            });

            this.panel.attr({
                'role': 'dialog',
                'aria-labelledby': 'accessimate-panel-title',
                'aria-hidden': 'true'
            });

            // Add IDs for ARIA references
            this.panel.find('h3').attr('id', 'accessimate-panel-title');
        }

        checkBackendSettings() {
            // Check if reading assistance features are enabled in backend
            if (typeof accessimate_ajax !== 'undefined' &&
                accessimate_ajax.ai_features &&
                !accessimate_ajax.ai_features.reading_assistance) {

                // Hide reading assistance buttons if not enabled in backend
                $('#accessimate-hide-images, #accessimate-reading-mask, #accessimate-reading-line').closest('.accessimate-option').hide();
            }
        }

        showNotification(message, type = 'info') {
            // Remove existing notifications
            $('.accessimate-notification').remove();

            const notificationClass = `accessimate-notification accessimate-notification-${type}`;
            const notification = $(`
                <div class="${notificationClass}" role="alert" aria-live="polite">
                    <span>${message}</span>
                    <button style="border: none; background: none; color: inherit; cursor: pointer;" class="accessimate-notification-close" aria-label="Close notification">&times;</button>
                </div>
            `);

            // Add notification styles
            notification.css({
                position: 'fixed',
                top: '20px',
                left: '50%',
                transform: 'translateX(-50%) translateY(-20px)', // combine transforms for initial hidden state
                background: (() => {
                    switch (type) {
                        case 'error': return '#ef4444';   // red
                        case 'warning': return '#f59e0b'; // amber
                        case 'success': return '#10b981'; // green
                        default: return '#3b82f6';         // blue (info/default)
                    }
                })(),
                color: '#fff',
                padding: '10px 20px',
                borderRadius: '8px',
                boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
                zIndex: '9999999',
                fontSize: '14px',
                fontWeight: '500',
                display: 'flex',
                alignItems: 'center',
                gap: '12px',
                maxWidth: '400px',
                opacity: '0',
            });


            $('body').append(notification);

            // Animate in
            notification.animate({
                opacity: 1,
                top: '20px'
            }, 200);

            // Auto remove after 3 seconds
            setTimeout(() => {
                this.removeNotification(notification);
            }, 3000);

            // Click to close
            notification.find('.accessimate-notification-close').on('click', () => {
                this.removeNotification(notification);
            });
        }

        removeNotification(notification) {
            notification.animate({
                opacity: 0,
                top: '0px'
            }, 200, () => {
                notification.remove();
            });
        }

        injectStyles(id, styles) {
            const style = document.createElement('style');
            if (!document.getElementById(id)) {
                style.id = id;
                style.rel = 'stylesheet';
                style.textContent = styles;
                document.head.appendChild(style);
            }
        }

        removeStyles(id) {
            const style = document.getElementById(id);
            if (style) {
                style.remove();
            }
        }

        letterSpacing($level, $notification = true) {
            const spacing = $level === 'small' ? "1px !important;" : $level === 'medium' ? "3px !important;" : $level === 'biggest' ? "5px !important;" : null;

            $("*").not(this.excludedElements).each(function () {

                let style = $(this).attr("style") || "";
                if ($level === 'default') {
                    style = style.replace(/letter-spacing:\s*[^;]+;?/, "");
                } else if (['small', 'medium', 'biggest'].includes($level)) {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /letter-spacing:\s*[^;]+;?/.test(style) ? style.replace(/letter-spacing:\s*[^;]+;?/, "letter-spacing: " + spacing) : style + " letter-spacing: " + spacing;
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                const label = $level === 'small' ? 'Small' : $level === 'medium' ? 'Medium' : $level === 'biggest' ? 'Biggest' : 'Default';
                this.showNotification(`Letter spacing: ${label}`);
            }
        }

        textAlign($value, $notification = true) {
            const alignment = $value === 'left' ? "left !important;" : $value === 'center' ? "center !important;" : $value === 'right' ? "right !important;" : null;
            $("*").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if ($value === 'default') {
                    style = style.replace(/text-align:\s*[^;]+;?/, "");
                } else if (['left', 'center', 'right'].includes($value)) {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /text-align:\s*[^;]+;?/.test(style) ? style.replace(/text-align:\s*[^;]+;?/, "text-align: " + alignment) : style + " text-align: " + alignment;
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                this.showNotification('Text alignment: ' + ($value === 'default' ? 'Default' : $value.charAt(0).toUpperCase() + $value.slice(1)));
            }
        }

        invertColors(level, $notification = true) {
            const filter = level === 'invert-v1' ? "invert(70%) !important;" : level === 'invert-v2' ? "invert(85%) !important;" : level === 'invert-v3' ? "invert(100%) !important;" : null;

            // $("svg, video, img, iframe")
            //     .not(this.excludedElements)
            //     .each(function () {
            //         let style = $(this).attr("style") || "";

            //         if (level === "default") {
            //             style = style.replace(/filter:\s*[^;]+;?/gi, "");
            //         } else if (["invert-v1", "invert-v2", "invert-v3"].includes(level)) {
            //             style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;

            //             if (/filter:\s*[^;]+;?/i.test(style)) {
            //                 style = style.replace(/filter:\s*[^;]+;?/gi, "filter: " + filter + ";");
            //             } else {
            //                 style += " filter: " + filter + ";";
            //             }
            //         }

            //         style = style.replace(/;;+/g, ";").trim();

            //         $(this).attr("style", style);
            //     });


            if ($notification) {
                const label = level === 'invert-v1' ? 'Invert V1' : level === 'invert-v2' ? 'Invert V2' : level === 'invert-v3' ? 'Invert V3' : 'Default';
                this.showNotification(`Color inversion: ${label}`);
            }
        }

        brightness(level, $notification = true) {
            const filter = level === 'brightness-v1' ? "brightness(50%) !important;" : level === 'brightness-v2' ? "brightness(80%) !important;" : level === 'brightness-v3' ? "brightness(110%) !important;" : null;
            $("html").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'default') {
                    style = style.replace(/filter:\s*[^;]+;?/, "");
                } else if (['brightness-v1', 'brightness-v2', 'brightness-v3'].includes(level)) {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /filter:\s*[^;]+;?/.test(style) ? style.replace(/filter:\s*[^;]+;?/, "filter: " + filter) : style + " filter: " + filter;
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                const label = level === 1 ? 'Brightness V1' : level === 2 ? 'Brightness V2' : level === 3 ? 'Brightness V3' : 'Default';
                this.showNotification(`Brightness: ${label}`);
            }
        }

        grayscale(level, $notification = true) {
   
            const filter = level === 'grayscale-v1' ? "grayscale(33%) !important;" : level === 'grayscale-v2' ? "grayscale(66%) !important;" : level === 'grayscale-v3' ? "grayscale(100%) !important;" : null;

            $("html").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'default') {
                    style = style.replace(/filter:\s*[^;]+;?/, "");
                } else if (['grayscale-v1', 'grayscale-v2', 'grayscale-v3'].includes(level)) {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /filter:\s*[^;]+;?/.test(style) ? style.replace(/filter:\s*[^;]+;?/, "filter: " + filter) : style + " filter: " + filter;
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                const label = level === 'grayscale-v1' ? 'Grayscale V1' : level === 'grayscale-v2' ? 'Grayscale V2' : level === 'grayscale-v3' ? 'Grayscale V3' : 'Default';
                this.showNotification(`Grayscale: ${label}`);
            }
        }

        highContrast($type, $notification = true) {
            const styleSheetId = 'accessimate-highContrast-styles';

            this.removeStyles(styleSheetId);

            const style = {
                dark: `
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(#accessimate-reading-mask-section,.accessimate-notification, .accessimate-notification *) {
                        box-shadow: none !important;
                        background-image: none !important;
                        text-shadow: none !important;
                        background-color: #18181b !important;
                    }
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(a, .accessimate-notification, .accessimate-notification *) {
                        color: #fafafa !important;
                    }
                    a:not(.accessimate-widget-link) {
                        color: #facc14 !important;
                    }
                `,
                light: `
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(#accessimate-reading-mask-section,.accessimate-notification,.accessimate-notification *) {
                        box-shadow: none !important;
                        background-image: none !important;
                        text-shadow: none !important;
                        background-color: #fff !important;
                    }
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(a, .accessimate-notification, .accessimate-notification *) {
                        color: #000 !important;
                    }
                    a:not(.accessimate-widget-link) {
                        color: rgb(0, 0, 211) !important;
                    }
                `,
                'high-contrast': `
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(#accessimate-reading-mask-section,.accessimate-notification, .accessimate-notification *) {
                        box-shadow: none !important;
                        background-image: none !important;
                        text-shadow: none !important;
                        background-color: #000 !important;
                    }
                    *:not(#accessimate-toolbar):not(#accessimate-toolbar *):not(a, .accessimate-notification, .accessimate-notification *) {
                        color: #fff !important;
                    }
                    a:not(.accessimate-widget-link) {
                        color: #facc14 !important;
                    }
                `,
            };

            if (!$type || !($type in style)) {
                return;
            }

            this.injectStyles(styleSheetId, style[$type]);

            if ($notification) {
                this.showNotification(`High contrast mode: ${$type.charAt(0).toUpperCase() + $type.slice(1)}`, 'success');
            }
        }

        applyTextStyle($level, {
            property,
            unit = '',
            scaleValues = {},
            excludeInherited = true,
            notificationLabel = '',
        }) {
            const $this = this;
            const scale = scaleValues[$level] ?? 0;

            $("body, body *").each(function () {
                if ($(this).is($this.excludedElements)) return;

                // Reset style
                if ($level === 'default' || scale === 0) {
                    $(this).css(property, '');
                    delete this.dataset[`original${property.replace(/-([a-z])/g, (_, char) => char.toUpperCase())}`];
                    return;
                }

                const computedStyle = window.getComputedStyle(this);
                const parentStyle = window.getComputedStyle(this.parentElement || document.body);

                const currentValue = computedStyle.getPropertyValue(property);
                const parentValue = parentStyle.getPropertyValue(property);

                // Skip if inherited
                if (excludeInherited && this !== document.body && currentValue === parentValue) return;

                const originalKey = `original${property.replace(/-([a-z])/g, (_, char) => char.toUpperCase())}`;
                const originalValue = parseFloat(currentValue);

                if (isNaN(originalValue)) return;

                this.dataset[originalKey] = this.dataset[originalKey] || originalValue;

                const baseValue = parseFloat(this.dataset[originalKey]);
                if (!baseValue) return;

                const newValue = `${property}: ${(baseValue * (1 + scale)).toFixed(2)}${unit} !important;`;

                let style = $(this).attr("style") || "";
                style = new RegExp(`${property}:\\s*[^;]+;?`).test(style)
                    ? style.replace(new RegExp(`${property}:\\s*[^;]+;?`), newValue)
                    : style + (style.trim().endsWith(";") || style.trim() === "" ? " " : "; ") + newValue;

                $(this).attr("style", style.trim());
            });

            if ($this.showNotification && notificationLabel) {
                const label = $level === 'default' ? 'Default' : notificationLabel;
                $this.showNotification(`${property.replace("-", " ")}: ${label}`);
            }
        }

        cursor(level, $notification = true) {
            $("html")
                .toggleClass("accessimate-cursor-feature1", level === 'cursor-v1')
                .toggleClass("accessimate-cursor-feature2", level === 'cursor-v2')
                .toggleClass("accessimate-cursor-feature3", level === 'cursor-v3');

            if ($notification) {
                const label = level === 'cursor-v1' ? 'Cursor V1' : level === 'cursor-v2' ? 'Cursor V2' : level === 'cursor-v3' ? 'Cursor V3' : 'Default';
                this.showNotification(`Cursor: ${label}`);
            }
        }

        readableFont(level, $notification = true) {
            const $this = this;
            $("*").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'enabled') {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /font-family:\s*[^;]+;?/.test(style) ? style.replace(/font-family:\s*[^;]+;?/, "font-family: Roboto, sans-serif !important;") : style + " font-family: Roboto, sans-serif !important;";
                } else if (level === 'disabled' || level === 'default') {
                    style = $this.getPreferences('dyslexicFont') === 'enabled' ? style.replace("font-family: Roboto, sans-serif !important;", "font-family: OpenDyslexic, sans-serif !important;") : style.replace(/font-family:\s*[^;]+;?/, "");
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                this.showNotification(`Readable Font: ${level === 'enabled' ? 'Enabled' : 'Disabled'}`);
            }
            this.savePreference('readableFont', level);
        }

        readingLine(level, $notification = true) {
            let lineSelection = document.getElementById('accessimate-reading-line-section');
            const button = $('#accessimate-reading-line');

            if (!lineSelection) {
                lineSelection = document.createElement('div');
                lineSelection.id = 'accessimate-reading-line-section';
                lineSelection.style.cssText = `
                    position: fixed !important;
                    left: 0 !important;
                    width: 100vw !important;
                    height: 4px !important;
                    background: linear-gradient(90deg, transparent, #ff0000, transparent) !important;
                    z-index: 999999 !important;
                    pointer-events: none !important;
                    display: none !important;
                    box-shadow: 0 0 15px rgba(255, 0, 0, 0.6) !important;
                    top: 50% !important;
                `;

                document.body.appendChild(lineSelection);
            }

            if (!this.lineMouseTracker) {
                this.lineMouseTracker = (e) => {
                    const currentLine = document.getElementById('accessimate-reading-line-section');
                    if (currentLine && window.getComputedStyle(currentLine).display !== 'none') {
                        currentLine.style.top = e.clientY + 'px';
                    }
                };
                document.addEventListener('mousemove', this.lineMouseTracker);
            }

            if (level === 'enabled') {
                lineSelection.style.display = 'block';
            } else {
                lineSelection.style.display = 'none';
            }

            if ($notification) {
                this.showNotification(`Reading Line: ${level === 'enabled' ? 'Enabled - Move mouse to see line guide' : 'Disabled'}`);
            }

            this.savePreference('readingLine', level);
        }

        readingMask(level, $notification = true) {
            let maskSelection = document.getElementById('accessimate-reading-mask-section');

            if (!maskSelection) {
                maskSelection = document.createElement('div');
                maskSelection.id = 'accessimate-reading-mask-section';
                const color = level === 'rectangle' ? 'linear-gradient(to bottom, #000000cc 40%, transparent 40%, transparent 60%, #000000cc 60%)' : level === 'circle' ? 'radial-gradient(circle 200px at 50% 50%, transparent 150px, rgba(0, 0, 0, 0.85) 250px)' : 'transparent';
                maskSelection.style.cssText = `
                    position: fixed !important;
                    top: 0 !important;
                    left: 0 !important;
                    width: 100vw !important;
                    height: 100vh !important;
                    background: ${color} !important;
                    z-index: 999998 !important;
                    pointer-events: none !important;
                    display: none !important;
                `;

                document.body.appendChild(maskSelection);
            } else if (level === 'rectangle' || level === 'circle') {
                const color = level === 'rectangle' ? 'linear-gradient(to bottom, #000000cc 40%, transparent 40%, transparent 60%, #000000cc 60%)' : level === 'circle' ? 'radial-gradient(circle 200px at 50% 50%, transparent 150px, rgba(0, 0, 0, 0.85) 250px)' : 'transparent';
                maskSelection.style.background = color;
                document.removeEventListener('mousemove', this.maskMouseTracker);
                this.maskMouseTracker = null;
            }

            if (!this.maskMouseTracker) {
                this.maskMouseTracker = (e) => {
                    const currentMask = document.getElementById('accessimate-reading-mask-section');
                    if (currentMask && window.getComputedStyle(currentMask).display !== 'none') {
                        const x = (e.clientX / window.innerWidth) * 100;
                        const y = (e.clientY / window.innerHeight) * 100;
                        const color = level === 'rectangle' ? `linear-gradient(to bottom, #000000cc ${y - 10}%, transparent ${y - 10}%, transparent ${y + 10}%, #000000cc ${y + 10}%)` : level === 'circle' ? `radial-gradient(circle 200px at ${x}% ${y}%, transparent 150px, rgba(0, 0, 0, 0.85) 250px)` : 'transparent';
                        currentMask.style.background = color;
                    }
                };
                document.addEventListener('mousemove', this.maskMouseTracker);
            }

            if (level === 'default' || level === 'disabled') {
                maskSelection.style.display = 'none';
            } else {
                maskSelection.style.display = 'block';
            }

            if ($notification) {
                this.showNotification(`Reading Mask: ${level === 'default' ? 'Disabled' : level === 'rectangle' ? 'Rectangle Enabled - Move mouse to see mask' : level === 'circle' ? 'Circle Enabled - Move mouse to see mask' : ''}`);
            }

            this.savePreference('readingMask', level);

        }

        dyslexicFont(level, $notification = true) {
            $("*").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'enabled') {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /font-family:\s*[^;]+;?/.test(style) ? style.replace(/font-family:\s*[^;]+;?/, "font-family: OpenDyslexic, sans-serif !important;") : style + " font-family: OpenDyslexic, sans-serif !important;";
                } else if (level === 'disabled' || level === 'default') {
                    style = style.replace(/font-family:\s*[^;]+;?/, "");
                }
                $(this).attr("style", style.trim());
            });

            if ($notification) {
                this.showNotification(`Dyslexic Font: ${level === 'enabled' ? 'Enabled' : 'Disabled'}`);
            }
            this.savePreference('dyslexicFont', level);
        }

        saturation(level, $notification = true) {
            const filter = level === 'saturation-v1' ? "saturate(150%) !important;" : level === 'saturation-v2' ? "saturate(200%) !important;" : level === 'saturation-v3' ? "saturate(250%) !important;" : null;
            $("html").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'default') {
                    style = style.replace(/filter:\s*[^;]+;?/, "");
                } else if (['saturation-v1', 'saturation-v2', 'saturation-v3'].includes(level)) {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /filter:\s*[^;]+;?/.test(style) ? style.replace(/filter:\s*[^;]+;?/, "filter: " + filter) : style + " filter: " + filter;
                }
                $(this).attr("style", style.trim());
            });
            if ($notification) {
                const label = level === 'saturation-v1' ? 'Saturation V1' : level === 'saturation-v2' ? 'Saturation V2' : level === 'saturation-v3' ? 'Saturation V3' : 'Default';
                this.showNotification(`Saturation: ${label}`);
            }
            this.savePreference('saturation', level);
        }

        hideImages(level, $notification = true) {
            const images = document.querySelectorAll('img, svg, [role="img"]');
            const backgroundElements = document.querySelectorAll('*:not(.accessimate-toolbar, .accessimate-toolbar *)');
            const button = $('#accessimate-hide-images');

            images.forEach(img => {
                if (level === 'enabled') {
                    img.style.opacity = '0';
                    img.style.transition = 'opacity 0.3s ease';
                    img.setAttribute('data-accessimate-hidden', 'true');
                } else {
                    img.style.opacity = '1';
                    img.style.transition = 'opacity 0.3s ease';
                    img.removeAttribute('data-accessimate-hidden');
                }
            });

            backgroundElements.forEach(element => {
                if (level === 'enabled') {
                    element.style.setProperty('background-size', '0 0', 'important');
                } else {
                    element.style.backgroundSize = '';
                }
            });

            if ($notification) {
                this.showNotification(`Image Visibility: ${level === 'enabled' ? 'Enabled' : 'Disabled'}`);
            }
            this.savePreference('hideImages', level);
        }

        muteSounds(level, $notification = true) {
            if (level === 'enabled') {
                $("audio, video").not(this.excludedElements).prop("muted", true);
                $('iframe[src*="youtube.com"]').each(function () {
                    const src = $(this).attr("src");
                    if (!src.includes("mute=1")) {
                        $(this).attr("src", src + (src.includes("?") ? "&" : "?") + "mute=1");
                    }
                });
            } else {
                $("audio, video").not(this.excludedElements).prop("muted", false);
                $('iframe[src*="youtube.com"]').each(function () {
                    const src = $(this).attr("src");
                    if (src.includes("mute=1")) {
                        $(this).attr("src", src.replace("mute=1", ""));
                    }
                });
            }

            if ($notification) {
                this.showNotification(`Mute Sounds: ${level === 'enabled' ? 'Enabled' : 'Disabled'}`);
            }
            this.savePreference('muteSounds', level);
        }

        stopAnimations(level, $notification = true) {
            $("*").not(this.excludedElements).each(function () {
                let style = $(this).attr("style") || "";
                if (level === 'enabled') {
                    style = style.trim() && !/;$/.test(style.trim()) ? style + ";" : style;
                    style = /transition:\s*[^;]+;?/.test(style) ? style.replace(/transition:\s*[^;]+;?/, "transition: none !important;") : style + " transition: none !important;";
                    style = /animation:\s*[^;]+;?/.test(style) ? style.replace(/animation:\s*[^;]+;?/, "animation: none !important;") : style + " animation: none !important;";
                } else {
                    style = style.replace(/transition:\s*[^;]+;?/, "").replace(/animation:\s*[^;]+;?/, "");
                }
                $(this).attr("style", style.trim());
            });
            if ($notification) {
                this.showNotification(`Stop Animations: ${level === 'enabled' ? 'Enabled' : 'Disabled'}`);
            }
            this.savePreference('stopAnimations', level);
        }

        escapeHTML(str) {
            return str.replace(/[&<>"']/g, function (m) {
                return {
                    '&': '&amp;',
                    '<': '&lt;',
                    '>': '&gt;',
                    '"': '&quot;',
                    "'": '&#39;'
                }[m];
            });
        }

        textToSpeech(level, $notification = true) {
            const $this = this;

            if (!this._highlightedElement) {
                this._highlightedElement = null;
            }

            $(document).off("click.accessimateTTS");

            if (level === 'disabled') {
                window.speechSynthesis.cancel();
                $("*").removeClass("accessimate-highlight");
                this._highlightedElement = null;

                if ($notification) {
                    $this.showNotification("Text to Speech: Disabled");
                }

                $this.savePreference('textToSpeech', level);
                return;
            }

            if (level === 'enabled') {
                $(document).on("click.accessimateTTS", function (e) {
                    if (!window.getSelection().isCollapsed) return;

                    if ($(e.target).closest("input, textarea, select, .accessimate-panel, .accessimate-panel *").length) return;

                    const $target = $(e.target).closest("p, span, li, h1, h2, h3, h4, h5, h6, button, a, div");

                    if ($target.length === 0) {
                        window.speechSynthesis.cancel();
                        if ($this._highlightedElement) {
                            const $el = $($this._highlightedElement);
                            $el.removeClass("accessimate-highlight");
                            $el.find(".accessimate-word-highlight").each(function () {
                                $(this).replaceWith($(this).text());
                            });
                            $this._highlightedElement = null;
                        }
                        return;
                    }

                    const $element = $target.first();
                    const fullText = $element.clone().children().remove().end().text().trim();

                    if (!fullText) return;

                    window.speechSynthesis.cancel();

                    if ($this._highlightedElement) {
                        const $el = $($this._highlightedElement);
                        $el.removeClass("accessimate-highlight");
                        $el.find(".accessimate-word-highlight").each(function () {
                            $(this).replaceWith($(this).text());
                        });
                        $this._highlightedElement = null;
                    }

                    $element.addClass("accessimate-highlight");
                    $this._highlightedElement = $element;

                    const originalHTML = $element.html();
                    const utterance = new SpeechSynthesisUtterance(fullText);
                    utterance.volume = 1;
                    utterance.rate = 1;

                    utterance.onboundary = function (event) {
                        if (event.name === "word") {
                            const start = event.charIndex;
                            const end = start + event.charLength;
                            const before = fullText.slice(0, start);
                            const word = fullText.slice(start, end);
                            const after = fullText.slice(end);

                            const highlightedHTML =
                                $this.escapeHTML(before) +
                                `<span class="accessimate-word-highlight">${$this.escapeHTML(word)}</span>` +
                                $this.escapeHTML(after);

                            $element.html(highlightedHTML);
                        }
                    };

                    utterance.onend = function () {
                        $element.html(originalHTML);
                        $element.removeClass("accessimate-highlight");
                        $this._highlightedElement = null;
                    };

                    window.speechSynthesis.speak(utterance);
                });

                if ($notification) {
                    $this.showNotification("Text to Speech: Enabled (Normal volume and speed)");
                }

                $this.savePreference('textToSpeech', level);
            }
        }

        highlightLinks(level, $notification = true) {
            const styleSheetId = 'accessimate-highlightLinks-styles';

            this.removeStyles(styleSheetId);

            const style = {
                underline: `
                    a:not(.accessimate-widget-link) {
                        text-decoration: underline 5px solid #fff176 !important;
                    }
                `,
                box: `
                    a:not(.accessimate-widget-link) {
                        box-shadow: 0 0 0 2px #fff176 !important;
                        background-color: #fff176a0 !important;
                        padding: 2px !important;
                        border-radius: 4px !important;
                    }
                `,
                background: `
                    a:not(.accessimate-widget-link) {
                        background: linear-gradient(45deg, var(--accessimate-warning), var(--accessimate-warning)) !important;
                        color: var(--accessimate-dark) !important;
                        padding: 2px 4px !important;
                        border-radius: 3px !important;
                        font-weight: 600 !important;
                    }
                    a:not(.accessimate-widget-link) *,
                    a:not(.accessimate-widget-link)::after,
                    a:not(.accessimate-widget-link)::before,
                    a:not(.accessimate-widget-link) *::after,
                    a:not(.accessimate-widget-link) *::before {
                        color: #000 !important;
                    }
                `,
            };

            if (!level || !level in style) {
                return;
            }

            this.injectStyles(styleSheetId, style[level]);

            if ($notification) {
                this.showNotification(`Highlight Links: ${level.charAt(0).toUpperCase() + level.slice(1)}`, 'success');
            }
        }

        highlightTitles(level, $notification = true) {
            const styleSheetId = 'accessimate-highlightTitles-styles';

            this.removeStyles(styleSheetId);

            const style = {
                underline: `
                    h1:not(.accessimate-panel h1), 
                    h2:not(.accessimate-panel h2), 
                    h3:not(.accessimate-panel h3), 
                    h4:not(.accessimate-panel h4), 
                    h5:not(.accessimate-panel h5), 
                    h6:not(.accessimate-panel h6) {
                        text-decoration: underline 5px solid #90caf9 !important;
                    }
                `,
                box: `
                    h1:not(.accessimate-panel h1), 
                    h2:not(.accessimate-panel h2), 
                    h3:not(.accessimate-panel h3), 
                    h4:not(.accessimate-panel h4), 
                    h5:not(.accessimate-panel h5), 
                    h6:not(.accessimate-panel h6) {
                        box-shadow: 0 0 0 2px #90caf9 !important;
                        background-color: #90caf9a0 !important;
                        padding: 2px !important;
                        border-radius: 4px !important;
                    }
                `,
                background: `
                    h1:not(.accessimate-panel h1), 
                    h2:not(.accessimate-panel h2), 
                    h3:not(.accessimate-panel h3), 
                    h4:not(.accessimate-panel h4), 
                    h5:not(.accessimate-panel h5), 
                    h6:not(.accessimate-panel h6) {
                        background: var(--accessimate-warning, #90caf9) !important;
                        color: var(--accessimate-dark) !important;
                        padding: 2px 4px !important;
                        border-radius: 3px !important;
                        font-weight: 600 !important;
                    }
                `,
            };

            if (!level || !level in style) {
                return;
            }

            this.injectStyles(styleSheetId, style[level]);

            if ($notification) {
                this.showNotification(`Highlight Titles: ${level.charAt(0).toUpperCase() + level.slice(1)}`, 'success');
            }
        }

        // =========================================================
        // Preference Handling
        // =========================================================
        next($key) {
            if (!this.options[$key]) {
                return;
            }

            const current = this.getPreferences($key) || 'default',
                nextIndex = (this.options[$key].steps.indexOf(current) + 1) % this.options[$key].steps.length,
                nextValue = this.options[$key].steps[nextIndex];

            this.savePreference($key, nextValue);
            return {
                index: nextIndex,
                value: nextValue
            };
        }

        #camelToHyphen(str) {
            return str
                .replace(/([a-z0-9])([A-Z])/g, '$1-$2') // insert hyphen between lower/number and upper
                .toLowerCase();
        }

        updateButtonStatus($key) {

            if (!this.options[$key]) {
                return;
            }

            const body = $('body'),
                button = this.getTrigger($key),
                buttonText = button.find('.accessimate-option-label'),
                label = this.options[$key].name || $key.charAt(0).toUpperCase() + $key.slice(1),
                currentType = this.getPreferences($key) || 'default',
                prefix = `accessimate-${this.#camelToHyphen($key)}`;

                let labels = {
                    default: {
                        en: 'Default',
                        fr: 'Par défaut',
                        es: 'Predeterminado',
                        de: 'Standard',
                        it: 'Predefinito',
                        pt: 'Padrão',
                        ar: 'افتراضي',
                    },
                    disabled: {
                        en: 'Disabled',
                        fr: 'Désactivé',
                        es: 'Desactivado',
                        de: 'Deaktiviert',
                        it: 'Disattivato',
                        pt: 'Desativado',
                        ar: 'معطل',
                    },
                    enabled: {
                        en: 'Enabled',
                        fr: 'Activé',
                        es: 'Activado',
                        de: 'Aktiviert',
                        it: 'Attivato',
                        pt: 'Ativado',
                        ar: 'مفعل',
                    },
                    'bigger-text': {
                        en: 'Bigger Text',
                        fr: 'Texte plus grand',
                        es: 'Texto más grande',
                        de: 'Größerer Text',
                        it: 'Testo più grande',
                        pt: 'Texto maior',
                        ar: 'نص أكبر',
                    },
                    small: {
                        en: 'Small',
                        fr: 'Petit',
                        es: 'Pequeño',
                        de: 'Klein',
                        it: 'Piccolo',
                        pt: 'Pequeno',
                        ar: 'صغير',
                    },
                    medium: {
                        en: 'Medium',
                        fr: 'Moyen',
                        es: 'Medio',
                        de: 'Mittel',
                        it: 'Medio',
                        pt: 'Médio',
                        ar: 'متوسط',
                    },
                    large: {
                        en: 'Large',
                        fr: 'Grand',
                        es: 'Grande',
                        de: 'Groß',
                        it: 'Grande',
                        pt: 'Grande',
                        ar: 'كبير',
                    },
                    biggest: {
                        en: 'Biggest',
                        fr: 'Très grand',
                        es: 'Muy grande',
                        de: 'Sehr groß',
                        it: 'Molto grande',
                        pt: 'Muito grande',
                        ar: 'كبير جدًا',
                    },
                    cursor: {
                        en: 'Cursor',
                        fr: 'Curseur',
                        es: 'Cursor',
                        de: 'Cursor',
                        it: 'Cursore',
                        pt: 'Cursor',
                        ar: 'المؤشر',
                    },
                    'cursor-v1': {
                        en: 'Cursor V1',
                        fr: 'Curseur V1',
                        es: 'Cursor V1',
                        de: 'Cursor V1',
                        it: 'Cursore V1',
                        pt: 'Cursor V1',
                        ar: 'المؤشر V1',
                    },
                    'cursor-v2': {
                        en: 'Cursor V2',
                        fr: 'Curseur V2',
                        es: 'Cursor V2',
                        de: 'Cursor V2',
                        it: 'Cursore V2',
                        pt: 'Cursor V2',
                        ar: 'المؤشر V2',
                    },
                    'cursor-v3': {
                        en: 'Cursor V3',
                        fr: 'Curseur V3',
                        es: 'Cursor V3',
                        de: 'Cursor V3',
                        it: 'Cursore V3',
                        pt: 'Cursor V3',
                        ar: 'المؤشر V3',
                    },
                    'line-height': {
                        en: 'Line Height',
                        fr: 'Hauteur de ligne',
                        es: 'Altura de línea',
                        de: 'Zeilenhöhe',
                        it: 'Altezza linea',
                        pt: 'Altura da linha',
                        ar: 'ارتفاع السطر',
                    },
                    'letter-spacing': {
                        en: 'Letter Spacing',
                        fr: 'Espacement des lettres',
                        es: 'Espaciado de letras',
                        de: 'Zeichenabstand',
                        it: 'Spaziatura lettere',
                        pt: 'Espaçamento de letras',
                        ar: 'تباعد الحروف',
                    },
                    'readable-font': {
                        en: 'Readable Font',
                        fr: 'Police lisible',
                        es: 'Fuente legible',
                        de: 'Lesbare Schrift',
                        it: 'Font leggibile',
                        pt: 'Fonte legível',
                        ar: 'خط واضح',
                    },
                    'dyslexic-font': {
                        en: 'Dyslexic Font',
                        fr: 'Police pour dyslexie',
                        es: 'Fuente para dislexia',
                        de: 'Dyslexie-Schrift',
                        it: 'Font per dislessia',
                        pt: 'Fonte para dislexia',
                        ar: 'خط لعسر القراءة',
                    },
                    'text-align': {
                        en: 'Text Align',
                        fr: 'Alignement du texte',
                        es: 'Alineación del texto',
                        de: 'Textausrichtung',
                        it: 'Allineamento testo',
                        pt: 'Alinhamento do texto',
                        ar: 'محاذاة النص',
                    },
                    left: {
                        en: 'Left',
                        fr: 'Gauche',
                        es: 'Izquierda',
                        de: 'Links',
                        it: 'Sinistra',
                        pt: 'Esquerda',
                        ar: 'يسار',
                    },
                    center: {
                        en: 'Center',
                        fr: 'Centre',
                        es: 'Centro',
                        de: 'Zentriert',
                        it: 'Centro',
                        pt: 'Centro',
                        ar: 'وسط',
                    },
                    right: {
                        en: 'Right',
                        fr: 'Droite',
                        es: 'Derecha',
                        de: 'Rechts',
                        it: 'Destra',
                        pt: 'Direita',
                        ar: 'يمين',
                    },
                    justify: {
                        en: 'Justify',
                        fr: 'Justifié',
                        es: 'Justificado',
                        de: 'Blocksatz',
                        it: 'Giustificato',
                        pt: 'Justificado',
                        ar: 'محاذاة كاملة',
                    },
                    'text-magnifier': {
                        en: 'Text Magnifier',
                        fr: 'Loupe de texte',
                        es: 'Lupa de texto',
                        de: 'Textlupe',
                        it: 'Lente di testo',
                        pt: 'Lupa de texto',
                        ar: 'مكبر النص',
                    },
                    'highlight-links': {
                        en: 'Highlight Links',
                        fr: 'Mettre en évidence les liens',
                        es: 'Resaltar enlaces',
                        de: 'Links hervorheben',
                        it: 'Evidenzia link',
                        pt: 'Destacar links',
                        ar: 'تمييز الروابط',
                    },
                    underline: {
                        en: 'Underline',
                        fr: 'Souligner',
                        es: 'Subrayar',
                        de: 'Unterstreichen',
                        it: 'Sottolinea',
                        pt: 'Sublinhar',
                        ar: 'تسطير',
                    },
                    box: {
                        en: 'Box',
                        fr: 'Boîte',
                        es: 'Caja',
                        de: 'Box',
                        it: 'Riquadro',
                        pt: 'Caixa',
                        ar: 'مربع',
                    },
                    background: {
                        en: 'Background',
                        fr: 'Arrière-plan',
                        es: 'Fondo',
                        de: 'Hintergrund',
                        it: 'Sfondo',
                        pt: 'Fundo',
                        ar: 'الخلفية',
                    },
                    'invert-colors': {
                        en: 'Invert Colors',
                        fr: 'Inverser les couleurs',
                        es: 'Invertir colores',
                        de: 'Farben invertieren',
                        it: 'Inverti colori',
                        pt: 'Inverter cores',
                        ar: 'عكس الألوان',
                    },
                    brightness: {
                        en: 'Brightness',
                        fr: 'Luminosité',
                        es: 'Brillo',
                        de: 'Helligkeit',
                        it: 'Luminosità',
                        pt: 'Brilho',
                        ar: 'السطوع',
                    },
                    contrast: {
                        en: 'Contrast',
                        fr: 'Contraste',
                        es: 'Contraste',
                        de: 'Kontrast',
                        it: 'Contrasto',
                        pt: 'Contraste',
                        ar: 'التباين',
                    },
                    dark: {
                        en: 'Dark',
                        fr: 'Sombre',
                        es: 'Oscuro',
                        de: 'Dunkel',
                        it: 'Scuro',
                        pt: 'Escuro',
                        ar: 'داكن',
                    },
                    light: {
                        en: 'Light',
                        fr: 'Clair',
                        es: 'Claro',
                        de: 'Hell',
                        it: 'Chiaro',
                        pt: 'Claro',
                        ar: 'فاتح',
                    },
                    grayscale: {
                        en: 'Grayscale',
                        fr: 'Niveaux de gris',
                        es: 'Escala de grises',
                        de: 'Graustufen',
                        it: 'Scala di grigi',
                        pt: 'Escala de cinza',
                        ar: 'تدرج الرمادي',
                    },
                    'grayscale-v1': {
                        en: 'Grayscale V1',
                        fr: 'Niveaux de gris V1',
                        es: 'Escala de grises V1',
                        de: 'Graustufen V1',
                        it: 'Scala di grigi V1',
                        pt: 'Escala de cinza V1',
                        ar: 'تدرج الرمادي V1',
                    },
                    'grayscale-v2': {
                        en: 'Grayscale V2',
                        fr: 'Niveaux de gris V2',
                        es: 'Escala de grises V2',
                        de: 'Graustufen V2',
                        it: 'Scala di grigi V2',
                        pt: 'Escala de cinza V2',
                        ar: 'تدرج الرمادي V2',
                    },
                    'grayscale-v3': {
                        en: 'Grayscale V3',
                        fr: 'Niveaux de gris V3',
                        es: 'Escala de grises V3',
                        de: 'Graustufen V3',
                        it: 'Scala di grigi V3',
                        pt: 'Escala de cinza V3',
                        ar: 'تدرج الرمادي V3',
                    },
                    saturation: {
                        en: 'Saturation',
                        fr: 'Saturation',
                        es: 'Saturación',
                        de: 'Sättigung',
                        it: 'Saturazione',
                        pt: 'Saturação',
                        ar: 'التشبع',
                    },
                    'high-contrast': {
                        en: 'High Contrast',
                        fr: 'Haut contraste',
                        es: 'Alto contraste',
                        de: 'Hoher Kontrast',
                        it: 'Alto contrasto',
                        pt: 'Alto contraste',
                        ar: 'تباين عالٍ',
                    },
                    'reading-line': {
                        en: 'Reading Line',
                        fr: 'Ligne de lecture',
                        es: 'Línea de lectura',
                        de: 'Leselinie',
                        it: 'Linea di lettura',
                        pt: 'Linha de leitura',
                        ar: 'سطر القراءة',
                    },
                    'reading-mask': {
                        en: 'Reading Mask',
                        fr: 'Masque de lecture',
                        es: 'Máscara de lectura',
                        de: 'Lesemaske',
                        it: 'Maschera di lettura',
                        pt: 'Máscara de leitura',
                        ar: 'قناع القراءة',
                    },
                    rectangle: {
                        en: 'Rectangle',
                        fr: 'Rectangle',
                        es: 'Rectángulo',
                        de: 'Rechteck',
                        it: 'Rettangolo',
                        pt: 'Retângulo',
                        ar: 'مستطيل',
                    },
                    circle: {
                        en: 'Circle',
                        fr: 'Cercle',
                        es: 'Círculo',
                        de: 'Kreis',
                        it: 'Cerchio',
                        pt: 'Círculo',
                        ar: 'دائرة',
                    },
                    'mute-sounds': {
                        en: 'Mute Sounds',
                        fr: 'Couper les sons',
                        es: 'Silenciar sonidos',
                        de: 'Sounds stummschalten',
                        it: 'Disattiva suoni',
                        pt: 'Silenciar sons',
                        ar: 'كتم الأصوات',
                    },
                    'stop-animations': {
                        en: 'Stop Animations',
                        fr: 'Arrêter les animations',
                        es: 'Detener animaciones',
                        de: 'Animationen stoppen',
                        it: 'Ferma animazioni',
                        pt: 'Parar animações',
                        ar: 'إيقاف الرسوم المتحركة',
                    },
                    'text-to-speech': {
                        en: 'Text to Speech',
                        fr: 'Synthèse vocale',
                        es: 'Texto a voz',
                        de: 'Text-zu-Sprache',
                        it: 'Sintesi vocale',
                        pt: 'Texto para fala',
                        ar: 'تحويل النص إلى كلام',
                    },
                    'highlight-all': {
                        en: 'Highlight All',
                        fr: 'Tout mettre en évidence',
                        es: 'Resaltar todo',
                        de: 'Alles hervorheben',
                        it: 'Evidenzia tutto',
                        pt: 'Destacar tudo',
                        ar: 'تسليط الضوء على الكل',
                    },
                    'highlight-titles': {
                        en: 'Highlight Titles',
                        fr: 'Mettre en évidence les titres',
                        es: 'Resaltar títulos',
                        de: 'Titel hervorheben',
                        it: 'Evidenzia titoli',
                        pt: 'Destacar títulos',
                        ar: 'تمييز العناوين',
                    },
                    keyboard: {
                        en: 'Keyboard',
                        fr: 'Clavier',
                        es: 'Teclado',
                        de: 'Tastatur',
                        it: 'Tastiera',
                        pt: 'Teclado',
                        ar: 'لوحة المفاتيح',
                    },
                    'hide-images': {
                        en: 'Hide Images',
                        fr: 'Masquer les images',
                        es: 'Ocultar imágenes',
                        de: 'Bilder ausblenden',
                        it: 'Nascondi immagini',
                        pt: 'Ocultar imagens',
                        ar: 'إخفاء الصور',
                    }
                };

            const labelLang = labels[label.toLowerCase().replace(/ /g, '-')] || { en: label, fr: label };
            const name = labelLang[this.language] || labelLang['en'];

            if (currentType === 'default' || currentType === 'disabled') {
                body.removeClass((index, className) => {
                    return (className.match(new RegExp(`\\b${prefix}-\\S+`, 'g')) || []).join(' ');
                });
                button.removeClass('active');
                
                buttonText.text(name);
            } else if (currentType === 'enabled') {
                body.addClass(`accessimate-${this.#camelToHyphen($key)}`);
                button.addClass('active');
                buttonText.text(name);
            } else if (this.options[$key]?.steps?.includes(currentType)) {

                body.removeClass((index, className) => {
                    return (className.match(new RegExp(`\\b${prefix}-\\S+`, 'g')) || []).join(' ');
                });

                body.addClass(`${prefix}-${currentType}`);
                button.addClass('active');
                buttonText.text(
                    labels[currentType][this.language] || labels[currentType]['en']
                );

            }

            if (this.options[$key].steps) {
                this.updateSteps($key);
            }
        }

        updateSteps(key) {
            const $target = this.options[key].trigger;
            const $steps = this.options[key].steps;
            const $current = this.getPreferences(key) || 'default';
            const $currentIndex = $steps.indexOf($current);

            const stepWrapper = $target.find('.accessimate-option-step');
            if (stepWrapper.length === 0) {
                return;
            }
            const $createSteps = Array.from($steps).map((option, index) => {
                if (index === 0) return;
                return `<div class="accessimate-option-step-item" data-value="${option}"></div>`;
            }).join('');

            stepWrapper.html($createSteps);

            const $currentItemIndex = parseInt($currentIndex, 10) - 1;
            const stepItems = stepWrapper.find('.accessimate-option-step-item');
            stepItems.removeClass('active');
            stepItems.each(function (index) {

                if (-1 === $currentItemIndex) {
                    $(this).removeClass('active');
                    return;
                }

                if (index <= $currentItemIndex) {
                    $(this).addClass('active');
                }
            });
        }

        hasBackground() {
            const excluded = this.excludedElements || "";

            $("div").not(excluded).each(function () {
                const style = window.getComputedStyle(this);
                const bgColor = style.backgroundColor;
                const bgImage = style.backgroundImage;

                if (
                    bgColor &&
                    bgColor !== "transparent" &&
                    !bgColor.endsWith("(0, 0, 0, 0)")
                ) {
                    $(this).addClass("accessimate-has-background-color");
                }

                if (bgImage && bgImage !== "none") {
                    $(this).addClass("accessimate-has-background-image");
                }
            });
        }
    }

    window.AccessiMateToolbar = new AccessiMateToolbar();

})(jQuery);