/**
 * Class: DooSearchas_Class_Preview
 * 
 * Handles live preview customization of the search bar within the WordPress admin settings panel.
 * Applies dynamic styles based on user-selected options such as placeholder, width, height, alignment, colors, button style, and shape.
 * Provides immediate visual feedback while editing the "Style Options" tab of the search plugin settings.
 * Supports sticky positioning of the preview bar, restoring scroll position, and hiding related column widths for visual consistency.
 * 
 * Core Features:
 * - Live updates for width, height, shape, placeholder text, and alignment
 * - Dynamic styling of button/icon color, background, shadow, and border
 * - Button style switching (icon-only, icon-square, default)
 * - Sticky positioning of preview bar with scroll memory using localStorage
 * - Hides `<th>` widths next to preview containers to enhance UI layout
 * 
 * Called From:
 * - Automatically initialized when the active settings tab is `style_options`
 */
class DooSearchas_Class_Preview {
    constructor() {
        // Check if the current settings tab is 'style_options' to initialize the preview
        const settingsWrapper = document.getElementById('doosearchas-search-settings');
        const activeTab = settingsWrapper ? settingsWrapper.dataset.activeTab : null;
        if (activeTab === 'style_options') {
            document.addEventListener('DOMContentLoaded', () => this.init());
        }
    }

    // Initialize preview by caching DOM elements, binding events, and applying initial UI behaviors
    init() {
        this.cacheElements();
        this.bindEvents();
        this.handleSticky();
        this.restoreScrollPosition();
        this.hideThWidths();
    }

    // Cache all necessary DOM elements for efficient access during event handling and updates
    cacheElements() {
        this.placeholderInput = document.getElementById('doosearchas_search_bar_placeholder');
        this.searchBar = document.getElementById('doosearchas-search-preview-bar');
        this.btnInput = document.getElementById('doosearchas-preview-bar-wrapper');
        this.widthSlider = document.getElementById('doosearchas_search_bar_width');
        this.hightSlider = document.getElementById('doosearchas_search_bar_hight');
        this.showButtonCheckbox = document.getElementById('doosearchas_search_bar_button_show');
        this.buttonStyleSelect = document.getElementById('doosearchas_search_bar_button_style');
        this.searchButton = document.getElementById('doosearchas-preview-bar-btn');
        this.searchIconId = document.getElementById('doosearchas-preview-search-icon');
        this.searchIconInput = document.getElementById('doosearchas_search_bar_button_icon');
        this.buttonBgColorPicker = document.getElementById('doosearchas_search_bar_button_bg_color');
        this.shapeSelect = document.getElementById('doosearchas_search_bar_shape');
        this.alignmentRadios = document.querySelectorAll('input[name="doosearchas_search_style_options[doosearchas_search_bar_alignment]"]');
        this.iconColorInput = document.getElementById('doosearchas_search_bar_icon_color');
        this.searchIcon = document.querySelector('#doosearchas-preview-bar-wrapper i');
        this.backgroundColorInput = document.getElementById('doosearchas_search_bar_bg_color');
        this.textColorInput = document.getElementById('doosearchas_search_bar_text_color');
        this.borderColorInput = document.getElementById('doosearchas_search_bar_border_color');
        this.searchBarBorder = document.getElementById('doosearchas-search-preview-bar');
        this.shadowSelect = document.getElementById('doosearchas_search_bar_shadow');
    }

    // Attach event listeners to inputs and controls to update the preview live on user interaction
    bindEvents() {
        // Update width of search bar wrapper on slider input change (percentage)
        if (this.widthSlider) {
            this.widthSlider.addEventListener('input', () => {
                this.btnInput.style.width = this.widthSlider.value + '%';
            });
        }

        // Update vertical padding of the search bar on height slider input change (pixels)
        this.hightSlider.addEventListener('input', () => {
            this.searchBar.style.paddingTop = this.hightSlider.value + 'px';
            this.searchBar.style.paddingBottom = this.hightSlider.value + 'px';
        });

        // Change border radius based on selected shape option ('round' or default)
        this.shapeSelect.addEventListener('change', () => {
            this.searchBar.style.borderRadius = this.shapeSelect.value === 'round' ? '30px' : '5px';
        });

        // Update alignment of search bar wrapper when user changes alignment radios
        this.alignmentRadios.forEach(radio => {
            radio.addEventListener('change', () => {
                const alignmentValue = radio.value;
                document.getElementById('searchBarWrapper').style.justifyContent = alignmentValue;

                // Highlight the selected alignment radio's label/icon for visual feedback
                this.alignmentRadios.forEach(r => {
                    const icon = r.nextElementSibling;
                    if (r.checked) {
                        icon.style.backgroundColor = '#0073e6';
                        icon.style.color = 'white';
                    } else {
                        icon.style.backgroundColor = 'transparent';
                        icon.style.color = 'inherit';
                    }
                });
            });
        });

        // Update placeholder text in search input field live
        this.placeholderInput.addEventListener('input', () => {
            this.searchBar.setAttribute('placeholder', this.placeholderInput.value);
        });

        // Toggle box shadow on/off for search bar preview based on select option
        this.shadowSelect.addEventListener('change', () => {
            this.searchBar.style.boxShadow = this.shadowSelect.value === 'on'
                ? '0 1px 3px rgba(0, 0, 0, 0.1)'
                : 'none';
        });

        // Show or hide the search button based on checkbox toggle
        this.showButtonCheckbox.addEventListener('change', () => {
            this.searchButton.style.display = this.showButtonCheckbox.checked ? 'flex' : 'none';
        });

        // Change button style (icon-only, icon-square, default) and apply related CSS
        this.buttonStyleSelect.addEventListener('change', () => this.updateButtonStyle());

        // Change icon class inside the button on user input
        this.searchIconInput.addEventListener('input', () => {
            this.searchButton.querySelector('i').className = this.searchIconInput.value;
        });

        // Update button background color and optionally text color if icon-only style is active
        this.buttonBgColorPicker.addEventListener('input', () => {
            this.searchButton.style.backgroundColor = this.buttonBgColorPicker.value;
            if (this.buttonStyleSelect.value === 'icon-only') {
                this.searchButton.style.color = this.buttonBgColorPicker.value;
            }
        });

        // Change search icon color live
        this.iconColorInput.addEventListener('input', () => {
            this.searchIcon.style.color = this.iconColorInput.value;
        });

        // Update search bar background color live
        this.backgroundColorInput.addEventListener('input', () => {
            this.searchBar.style.backgroundColor = this.backgroundColorInput.value;
        });

        // Update search bar text color live
        this.textColorInput.addEventListener('input', () => {
            this.searchBar.style.color = this.textColorInput.value;
        });

        // Update border color of the search bar preview
        this.borderColorInput.addEventListener('input', () => {
            this.searchBarBorder.style.borderColor = this.borderColorInput.value;
        });
    }

    // Applies different CSS styles based on the selected button style option
    updateButtonStyle() {
        const style = this.buttonStyleSelect.value;
        if (style === 'icon-only') {
            // Minimal icon-only style with no background or border
            Object.assign(this.searchButton.style, {
                background: 'none',
                border: 'none',
                color: this.buttonBgColorPicker.value,
                borderRadius: '0',
                width: 'auto',
                height: 'auto',
                right: '10px'
            });
            this.searchIconId.style.fontSize = '20px';
        } else if (style === 'icon-square') {
            // Square style with background color and right border radius
            Object.assign(this.searchButton.style, {
                background: this.buttonBgColorPicker.value,
                border: 'none',
                borderRadius: '0px 5px 5px 0px',
                width: '9%',
                height: '98%',
                color: 'white',
                right: '-1px'
            });
            this.searchIconId.style.fontSize = '20px';
        } else {
            // Default round style button
            Object.assign(this.searchButton.style, {
                background: this.buttonBgColorPicker.value,
                border: 'none',
                borderRadius: '50%',
                width: '35px',
                height: '35px',
                color: 'white',
                right: '10px'
            });
            this.searchIconId.style.fontSize = '16px';
        }
    }

    // Manages sticky positioning of the search bar preview, saving scroll position to localStorage
    handleSticky() {
        // Retrieve last saved scroll Y position or default to 100
        this.lastScrollY = parseInt(localStorage.getItem("lastScrollY")) || 100;
        this.isSticky = false;

        window.addEventListener("scroll", () => {
            const scrollY = window.scrollY;
            const item = document.querySelector(".searchBarPreview");
            const rect = item.getBoundingClientRect();

            // If preview is near the top or already sticky, update its top position and save scrollY
            if (rect.top <= 10 || this.isSticky) {
                requestAnimationFrame(() => {
                    const ssPX = Math.max(100, scrollY);
                    item.style.top = `${ssPX}px`;
                    localStorage.setItem("lastScrollY", ssPX);
                    this.isSticky = true;
                });
            }

            // Reset sticky state and position if scroll is near the top
            if (scrollY < 100) {
                this.isSticky = false;
                item.style.top = '100px';
                localStorage.setItem("lastScrollY", 100);
            }
        });
    }

    // Restores the search bar preview's top position on page load from localStorage
    restoreScrollPosition() {
        window.addEventListener("load", () => {
            const savedScrollY = parseInt(localStorage.getItem("lastScrollY"));
            if (savedScrollY && savedScrollY >= 100) {
                document.querySelector(".searchBarPreview").style.top = `${savedScrollY}px`;
                this.isSticky = true;
            }
        });
    }

    // Hide widths of <th> elements adjacent to the preview containers to improve layout
    hideThWidths() {
        const elements = document.querySelectorAll("td .searchBarDiv");
        elements.forEach((myClassDiv) => {
            const thElement = myClassDiv.closest("td").previousElementSibling;
            if (thElement && thElement.tagName === "TH") {
                thElement.style.width = "0px";
            }
        });
    }
}

// Initialize the slider 
new DooSearchas_Class_Preview();
