
(function($) {
    'use strict';

    window.ImpulseLivePreview = {

        

        currentElementId: null,
        currentElementType: null,
        currentSettings: {},
        iframe: null,
        previousSettings: {},

        

        universalStyles: {
            
            padding_top: { property: 'padding-top', unit: 'px' },
            padding_right: { property: 'padding-right', unit: 'px' },
            padding_bottom: { property: 'padding-bottom', unit: 'px' },
            padding_left: { property: 'padding-left', unit: 'px' },
            margin_top: { property: 'margin-top', unit: 'px' },
            margin_right: { property: 'margin-right', unit: 'px' },
            margin_bottom: { property: 'margin-bottom', unit: 'px' },
            margin_left: { property: 'margin-left', unit: 'px' },
            
            border_radius: { property: 'border-radius', unit: 'px' },
            border_width: { property: 'border-width', unit: 'px' },
            
            max_width: { property: 'max-width', unit: 'px' },
            min_height: { property: 'min-height', unit: 'px' },
            
            opacity: { property: 'opacity', unit: function(v) { return v / 100; } }
        },

        universalColorStyles: {
            bg_color: 'background-color',
            background: 'background-color',
            border_color: 'border-color'
        },

        

        
        init: function() {
            var self = this;

            this.iframe = document.getElementById('impulse-iframe');
            if (!this.iframe) return;

            if (typeof ImpulseElementConfig === 'undefined') {
                return;
            }

            window.impulseLivePreviewUpdate = function(id, type, settings) {
                return self.update(id, type, settings);
            };
        },

        

        
        update: function(id, type, settings) {
            this.currentElementId = id;
            this.currentElementType = type;
            this.currentSettings = settings;

            var needsRefresh = this.checkStructuralChanges(id, type, settings);

            this.previousSettings[id] = JSON.parse(JSON.stringify(settings));
            
            if (needsRefresh) {
                return { needsRefresh: true };
            }

            this.injectCSS(id, type, settings);

            this.updateContent(id, type, settings);

            this.sendToIframe(id, type, settings);
            
            return { needsRefresh: false };
        },

        

        
        checkStructuralChanges: function(id, type, settings) {
            var prevSettings = this.previousSettings[id];

            if (!prevSettings) {
                return false;
            }

            var elementConfig = ImpulseElementConfig.get(type);
            if (!elementConfig) {
                
                return this.checkLegacyStructural(settings, prevSettings);
            }

            for (var key in settings) {
                if (!settings.hasOwnProperty(key)) continue;
                
                var oldVal = prevSettings[key];
                var newVal = settings[key];

                if (JSON.stringify(oldVal) === JSON.stringify(newVal)) {
                    continue;
                }

                
                if (ImpulseElementConfig.needsRefresh(type, key)) {
                    return true;
                }
                var baseKey = key.replace(/_tablet$|_mobile$/, '');
                if (baseKey !== key && ImpulseElementConfig.needsRefresh(type, baseKey)) {
                    return true;
                }
            }
            
            return false;
        },

        legacyStructuralSettings: [
            'columns', 'layout', 'source', 'query_type', 'per_page', 'items',
            'tabs', 'icon_position', 'category_id',
            'card_design', 'fit_text', 'tag', 'element_type', 'animation_type',
            'slide_direction', 'menu_items', 'template', 'plans', 'testimonials',
            'fields', 'badges', 'shortcode'
        ],
        
        checkLegacyStructural: function(settings, prevSettings) {
            for (var i = 0; i < this.legacyStructuralSettings.length; i++) {
                var key = this.legacyStructuralSettings[i];
                if (JSON.stringify(settings[key]) !== JSON.stringify(prevSettings[key])) {
                    return true;
                }
            }
            return false;
        },

        

        
        generateCSS: function(id, type, settings) {
            var self = this;
            var css = [];
            var baseSelector = '.impulse-el[data-id="' + id + '"]';
            var device = window.impulseDevice || 'desktop';

            var cssSettings = ImpulseElementConfig.getCssSettings(type);

            var resolvedSettings = this.resolveDeviceSettings(settings, type, device);

            var rulesBySelector = {};

            for (var settingName in cssSettings) {
                var value = resolvedSettings[settingName];
                if (value === undefined || value === '' || value === null) continue;

                if (settingName === 'font_size' && value === 0) continue;

                if ((settingName === 'max_width' || settingName === 'height') && value === 0) continue;

                

                
                
                if (settingName === 'btn_min_width' && (value === 0 || value === '0')) continue;

                if (type === 'title' && settingName === 'size' && resolvedSettings.fit_text) {
                    continue;
                }
                
                var config = cssSettings[settingName];

                var selector = config.selector.replace(/\{\{WRAPPER\}\}/g, baseSelector);

                var cssValue = this.formatValue(value, config.unit);
                
                if (!rulesBySelector[selector]) {
                    rulesBySelector[selector] = {};
                }

                var properties = Array.isArray(config.property) ? config.property : [config.property];
                properties.forEach(function(prop) {
                    rulesBySelector[selector][prop] = cssValue;
                });

                if (config.property === 'background-color') {
                    var _isFieldBg = (
                        (settingName === 'field_bg' && (type === 'form' || type === 'login_form' || type === 'register_form')) ||
                        (settingName === 'checkout_design_field_bg' && type === 'checkout_block')
                    );
                    var _isBtnBg = (
                        (settingName === 'button_bg' && (type === 'form' || type === 'login_form' || type === 'register_form')) ||
                        (settingName === 'checkout_design_button' && type === 'checkout_block')
                    );
                    if (_isFieldBg && value && value.indexOf('rgba') === -1) {
                        var _hex = String(value).replace('#', '');
                        if (_hex.length === 3) _hex = _hex[0]+_hex[0]+_hex[1]+_hex[1]+_hex[2]+_hex[2];
                        var _r = parseInt(_hex.substr(0,2),16), _g = parseInt(_hex.substr(2,2),16), _bl = parseInt(_hex.substr(4,2),16);
                        var _light = (0.299*_r + 0.587*_g + 0.114*_bl) / 255 > 0.5;
                        rulesBySelector[selector]['color'] = _light ? '#000000' : '#ffffff';
                    }
                    if (_isBtnBg && value) {
                        
                        var _btnColorKey = (type === 'checkout_block') ? 'checkout_design_button_text' : 'button_color';
                        if (!resolvedSettings[_btnColorKey]) {
                            var _hex2 = String(value).replace('#', '');
                            if (_hex2.length === 3) _hex2 = _hex2[0]+_hex2[0]+_hex2[1]+_hex2[1]+_hex2[2]+_hex2[2];
                            var _r2 = parseInt(_hex2.substr(0,2),16), _g2 = parseInt(_hex2.substr(2,2),16), _bl2 = parseInt(_hex2.substr(4,2),16);
                            rulesBySelector[selector]['color'] = (0.299*_r2 + 0.587*_g2 + 0.114*_bl2) / 255 > 0.5 ? '#000000' : '#ffffff';
                        }
                    }
                }
            }

            if (type === 'checkout_block' && resolvedSettings.width) {
                var checkoutSelector = baseSelector + ' .impulse-checkout-block';
                if (!rulesBySelector[checkoutSelector]) {
                    rulesBySelector[checkoutSelector] = {};
                }
                rulesBySelector[checkoutSelector]['margin-left'] = 'auto';
                rulesBySelector[checkoutSelector]['margin-right'] = 'auto';
            }

            if (type === 'order_summary' && resolvedSettings.width && resolvedSettings.width < 100) {
                var summarySelector = baseSelector + ' .impulse-order-summary';
                if (!rulesBySelector[summarySelector]) {
                    rulesBySelector[summarySelector] = {};
                }
                rulesBySelector[summarySelector]['margin-left'] = 'auto';
                rulesBySelector[summarySelector]['margin-right'] = 'auto';
            }

            if (type === 'cart_block' && resolvedSettings.width && resolvedSettings.width < 100) {
                var cartSelector = baseSelector + ' .impulse-cart-block';
                if (!rulesBySelector[cartSelector]) {
                    rulesBySelector[cartSelector] = {};
                }
                rulesBySelector[cartSelector]['margin-left'] = 'auto';
                rulesBySelector[cartSelector]['margin-right'] = 'auto';
            }

            if (type === 'mini_cart' && resolvedSettings.width && resolvedSettings.width < 100) {
                var miniCartSelector = baseSelector + ' .impulse-mini-cart';
                if (!rulesBySelector[miniCartSelector]) {
                    rulesBySelector[miniCartSelector] = {};
                }
                rulesBySelector[miniCartSelector]['margin-left'] = 'auto';
                rulesBySelector[miniCartSelector]['margin-right'] = 'auto';
            }

            if (type === 'coupon_field' && resolvedSettings.width && resolvedSettings.width < 100) {
                var couponSelector = baseSelector + ' .impulse-coupon-field';
                if (!rulesBySelector[couponSelector]) {
                    rulesBySelector[couponSelector] = {};
                }
                rulesBySelector[couponSelector]['margin-left'] = 'auto';
                rulesBySelector[couponSelector]['margin-right'] = 'auto';
            }

            if (type === 'contact_form' && resolvedSettings.form_width && resolvedSettings.form_width < 100) {
                var formSelector = baseSelector + ' .impulse-contact-form';
                if (!rulesBySelector[formSelector]) {
                    rulesBySelector[formSelector] = {};
                }
                rulesBySelector[formSelector]['margin-left'] = 'auto';
                rulesBySelector[formSelector]['margin-right'] = 'auto';
            }

            if (type === 'form' && resolvedSettings.form_width && resolvedSettings.form_width < 100) {
                var formSelector2 = baseSelector + ' .impulse-form';
                if (!rulesBySelector[formSelector2]) {
                    rulesBySelector[formSelector2] = {};
                }
                rulesBySelector[formSelector2]['margin-left'] = 'auto';
                rulesBySelector[formSelector2]['margin-right'] = 'auto';
            }

            
            
            if (type === 'form' || type === 'login_form' || type === 'register_form' || type === 'checkout_block') {
                var _fbg = (type === 'checkout_block') ? resolvedSettings.checkout_design_field_bg : resolvedSettings.field_bg;
                if (_fbg && _fbg.indexOf('rgba') === -1) {
                    var _hx = String(_fbg).replace('#','');
                    if (_hx.length === 3) _hx = _hx[0]+_hx[0]+_hx[1]+_hx[1]+_hx[2]+_hx[2];
                    var _rr = parseInt(_hx.substr(0,2),16), _gg = parseInt(_hx.substr(2,2),16), _bb = parseInt(_hx.substr(4,2),16);
                    var _isLt = (0.299*_rr + 0.587*_gg + 0.114*_bb) / 255 > 0.5;
                    var _plc = _isLt ? '#86868b' : 'rgba(255,255,255,0.45)';
                    var _phSels = {
                        'form':           [baseSelector + ' .impulse-form input::placeholder', baseSelector + ' .impulse-form textarea::placeholder'],
                        'login_form':     [baseSelector + ' .impulse-login-form input::placeholder'],
                        'register_form':  [baseSelector + ' .impulse-register-form input::placeholder'],
                        'checkout_block': [baseSelector + ' .impulse-checkout-block input::placeholder']
                    };
                    (_phSels[type] || []).forEach(function(s) {
                        css.push(s + '{color:' + _plc + '!important}');
                    });
                }
            }

            
            for (var marginKey in this.universalStyles) {
                
                if (cssSettings[marginKey]) continue;

                
                if (marginKey === 'min_height' && type === 'section') continue;

                var marginValue = resolvedSettings[marginKey];
                if (marginValue === undefined || marginValue === '' || marginValue === null) continue;
                
                if ((marginKey === 'max_width' || marginKey === 'min_height') && marginValue === 0) continue;

                var marginConfig = this.universalStyles[marginKey];
                var marginCssValue = this.formatValue(marginValue, marginConfig.unit);

                if (!rulesBySelector[baseSelector]) {
                    rulesBySelector[baseSelector] = {};
                }
                rulesBySelector[baseSelector][marginConfig.property] = marginCssValue;
            }

            

            if (type === 'section') {
                var hMode  = resolvedSettings.height_mode;
                var rawMH  = resolvedSettings.min_height;
                if (!hMode && rawMH != null && rawMH !== '' && rawMH !== 0) hMode = 'vh';
                if (hMode) {
                    if (!rulesBySelector[baseSelector]) rulesBySelector[baseSelector] = {};
                    if (hMode === 'aspect') {
                        var ar = resolvedSettings.aspect_ratio || '16:9';
                        if (!/^\d+:\d+$/.test(ar)) ar = '16:9';
                        rulesBySelector[baseSelector]['aspect-ratio'] = ar.replace(':', ' / ');
                        rulesBySelector[baseSelector]['min-height']   = '0';
                    } else if (hMode === 'px') {
                        var px = Math.max(0, Math.min(2000, parseInt(resolvedSettings.height_px || 0, 10)));

                        

                        
                        if (px > 0) {
                            rulesBySelector[baseSelector]['min-height']   = px + 'px';
                            rulesBySelector[baseSelector]['aspect-ratio'] = 'auto';
                        }
                    } else if (hMode === 'vh') {
                        var vh = Math.max(0, Math.min(100, parseInt(rawMH || 0, 10)));
                        if (vh > 0) {
                            rulesBySelector[baseSelector]['min-height']   = vh + 'vh';
                            rulesBySelector[baseSelector]['aspect-ratio'] = 'auto';
                        }

                        
                    } else { 
                        rulesBySelector[baseSelector]['min-height']   = '0';
                        rulesBySelector[baseSelector]['aspect-ratio'] = 'auto';
                    }
                }
            }

            if (!cssSettings.bg_color && !cssSettings.background) {
                for (var colorKey in this.universalColorStyles) {
                    var colorValue = resolvedSettings[colorKey];
                    if (colorValue === undefined || colorValue === '' || colorValue === null) continue;
                    
                    if (!rulesBySelector[baseSelector]) {
                        rulesBySelector[baseSelector] = {};
                    }
                    rulesBySelector[baseSelector][this.universalColorStyles[colorKey]] = colorValue;
                }
            }

            

            

            

            for (var sel in rulesBySelector) {
                var props = [];
                for (var prop in rulesBySelector[sel]) {
                    props.push(prop + ':' + rulesBySelector[sel][prop] + '!important');
                }
                if (props.length) {
                    css.push(sel + '{' + props.join(';') + '}');
                }
            }
            
            return css.join('\n');
        },

        resolveDeviceSettings: function(settings, type, device) {
            var resolved = $.extend({}, settings);
            
            if (device === 'desktop') {
                return resolved;
            }

            var cssSettings = ImpulseElementConfig.getCssSettings(type);
            
            for (var key in cssSettings) {
                if (ImpulseElementConfig.isResponsive(type, key)) {
                    if (device === 'mobile') {
                        
                        if (settings[key + '_mobile'] !== undefined && settings[key + '_mobile'] !== '') {
                            resolved[key] = settings[key + '_mobile'];
                        } else if (settings[key + '_tablet'] !== undefined && settings[key + '_tablet'] !== '') {
                            resolved[key] = settings[key + '_tablet'];
                        }
                    } else {
                        
                        if (settings[key + '_tablet'] !== undefined && settings[key + '_tablet'] !== '') {
                            resolved[key] = settings[key + '_tablet'];
                        }
                    }
                }
            }

            var universalKeys = ['margin_top', 'margin_right', 'margin_bottom', 'margin_left',
                               'padding_top', 'padding_right', 'padding_bottom', 'padding_left'];
            for (var i = 0; i < universalKeys.length; i++) {
                var uKey = universalKeys[i];
                if (device === 'mobile') {
                    if (settings[uKey + '_mobile'] !== undefined && settings[uKey + '_mobile'] !== '') {
                        resolved[uKey] = settings[uKey + '_mobile'];
                    } else if (settings[uKey + '_tablet'] !== undefined && settings[uKey + '_tablet'] !== '') {
                        resolved[uKey] = settings[uKey + '_tablet'];
                    }
                } else {
                    if (settings[uKey + '_tablet'] !== undefined && settings[uKey + '_tablet'] !== '') {
                        resolved[uKey] = settings[uKey + '_tablet'];
                    }
                }
            }

            

            if (device === 'mobile') {

                if (type === 'unfold' &&
                    (settings.tiles_cols_mobile === undefined ||
                     settings.tiles_cols_mobile === '' ||
                     settings.tiles_cols_mobile === null)) {
                    resolved.tiles_cols = 1;
                }
            }

            return resolved;
        },

        formatValue: function(value, unit) {
            if (!unit) return value;
            if (typeof unit === 'function') return unit(value);
            if (typeof unit === 'string') return value + unit;
            return value;
        },

        

        
        injectCSS: function(id, type, settings) {
            if (!this.iframe || !this.iframe.contentDocument) {
                console.warn('ImpulseLivePreview: No iframe or contentDocument');
                return;
            }
            
            var doc = this.iframe.contentDocument;
            var styleId = 'impulse-live-css-' + id;

            var styleEl = doc.getElementById(styleId);
            if (!styleEl) {
                styleEl = doc.createElement('style');
                styleEl.id = styleId;
                styleEl.setAttribute('data-impulse-live', 'true');
                doc.head.appendChild(styleEl);
            }

            var css = this.generateCSS(id, type, settings);
            styleEl.textContent = css;
        },

        clearCSS: function(id) {
            if (!this.iframe || !this.iframe.contentDocument) return;
            
            var styleEl = this.iframe.contentDocument.getElementById('impulse-live-css-' + id);
            if (styleEl) {
                styleEl.remove();
            }
        },

        clearAllCSS: function() {
            if (!this.iframe || !this.iframe.contentDocument) return;
            
            var styles = this.iframe.contentDocument.querySelectorAll('style[data-impulse-live]');
            styles.forEach(function(el) {
                el.remove();
            });
        },

        

        
        updateContent: function(id, type, settings) {
            if (!this.iframe || !this.iframe.contentDocument) return;
            
            var doc = this.iframe.contentDocument;
            var el = doc.querySelector('.impulse-el[data-id="' + id + '"]');
            if (!el) return;

            var contentSettings = ImpulseElementConfig.getContentSettings(type);
            
            for (var settingName in contentSettings) {
                var value = settings[settingName];
                
                if (value === undefined || value === '') continue;
                
                var config = contentSettings[settingName];
                var target = el.querySelector(config.target);
                if (!target) continue;

                if (settings.transform) {
                    value = this.applyTextTransform(value, settings.transform);
                }
                
                if (config.type === 'html') {
                    target.innerHTML = value;
                } else if (config.type === 'text') {
                    if (config.preserve) {
                        
                        this.updateTextPreserving(target, value, config.preserve);
                    } else {
                        target.textContent = value;
                    }
                }
            }
        },

        updateTextPreserving: function(target, value, preserveSelector) {
            var preserved = [];
            var iconPosition = 'before';
            
            target.querySelectorAll(preserveSelector).forEach(function(child, index) {
                preserved.push(child.outerHTML);
                
                var textAfter = child.nextSibling;
                if (textAfter && textAfter.textContent && textAfter.textContent.trim()) {
                    iconPosition = 'before';
                } else {
                    iconPosition = 'after';
                }
            });
            
            if (preserved.length) {
                if (iconPosition === 'before') {
                    target.innerHTML = preserved.join('') + ' ' + value;
                } else {
                    target.innerHTML = value + ' ' + preserved.join('');
                }
            } else {
                target.textContent = value;
            }
        },

        applyTextTransform: function(text, transform) {
            if (!text || typeof text !== 'string') return text;
            
            switch (transform) {
                case 'uppercase': 
                    return text.toUpperCase();
                case 'lowercase': 
                    return text.toLowerCase();
                case 'capitalize': 
                    return text.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); });
                default: 
                    return text;
            }
        },

        

        
        sendToIframe: function(id, type, settings) {
            if (!this.iframe || !this.iframe.contentWindow) return;
            
            this.iframe.contentWindow.postMessage({
                type: 'impulse-live-preview',
                id: id,
                elementType: type,
                settings: settings
            }, '*');
        }
    };

    $(function() {
        ImpulseLivePreview.init();
    });
    
})(jQuery);
