(function($) {
    'use strict';
    
    var productsState = {
        products: [],
        categories: [],
        stats: { total: 0, in_stock: 0, low_stock: 0, out_of_stock: 0 },
        filters: {
            status: 'published',  
            stock_filter: '',
            category: 0,
            search: ''
        },
        view: 'cards', 
        selectedProduct: null,
        bulkSelected: [],
        page: 1,
        totalPages: 1,
        hasMore: false,
        _retries: 0,
        loading: false,
        initialized: false
    };

    
    
    window._productsState = productsState;
    
    var pageFullyLoaded = false;

    $(document).on('impulse:workspace:store', function() {

        if (pageFullyLoaded && !productsState.initialized) {
            initProductsWorkspace();
        }
    });

    $(document).ready(function() {
        
        $(document).off('click.addcategory').on('click.addcategory', '#impulse-add-category', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            $('.impulse-cat-inline-add').remove();
            var $tree = $('#impulse-categories-tree');
            var inputHtml = '<div class="impulse-cat-inline-add" style="display:flex;align-items:center;gap:4px;padding:4px 8px;margin-top:4px">' +
                '<input type="text" class="impulse-cat-new-input" placeholder="Category name" ' +
                'style="flex:1;background:#2a2e33 !important;border:1px solid #3a3f44 !important;color:#e0e0e0 !important;font-size:11px;padding:5px 8px;border-radius:3px;outline:none !important;box-shadow:none !important">' +
                '<span class="impulse-cat-new-ok" style="cursor:pointer;color:#999;font-size:11px;font-weight:600;padding:0 4px">OK</span>' +
                '<span class="impulse-cat-new-cancel" style="cursor:pointer;color:#666;font-size:11px;padding:0 4px">&times;</span>' +
                '</div>';
            $tree.append(inputHtml);
            setTimeout(function() { $tree.find('.impulse-cat-new-input').focus(); }, 30);
        });
    });

    $(document).on('impulse:products:show', function() {
        if (!productsState.initialized) {
            
            initProductsWorkspace();
        } else if (!productsState.loading) {
            
            loadProductsList();
            if (!productsState.categories.length) loadCategories();
        }
    });

    $(document).on('impulse:store:products', function() {
        if (!productsState.initialized) {
            initProductsWorkspace();
        }
    });

    $(document).on('impulse:products:open-new', function() {
        openNewProduct();
    });

    $(document).on('click', '#impulse-add-product, #topbar-add-product', function() {
        if (!productsState.initialized) {
            
            $(document).trigger('impulse:products:show');
            var _waitOpen = setInterval(function() {
                if (productsState.initialized) {
                    clearInterval(_waitOpen);
                    openNewProduct();
                }
            }, 50);
            setTimeout(function() { clearInterval(_waitOpen); }, 3000);
        } else {
            openNewProduct();
        }
    });

    $(window).on('load', function() {
        
        if (window.self !== window.top) {
            return;
        }
        
        pageFullyLoaded = true;

        if (window.Impulse && window.Impulse.workspace === 'store') {
            
            setTimeout(function() {
                if (!productsState.initialized) {
                    initProductsWorkspace();
                }
            }, 100);
        }
    });
    
    function initProductsWorkspace() {
        if (productsState.initialized) return; 

        if (window.self !== window.top) {
            return;
        }

        if (!window.Impulse || !window.Impulse.adminNonce || !window.Impulse.products) {
            setTimeout(initProductsWorkspace, 200);
            return;
        }
        
        productsState.initialized = true;

        $('#topbar-add-product').show();

        bindProductEvents();

        loadProductsList();
        loadCategories();
        loadInventoryStats();

        
        $('#impulse-products-search').val('');
        setTimeout(function() {
            var val = $('#impulse-products-search').val();
            if (val) {
                $('#impulse-products-search').val('');
            }
        }, 100);
    }
    
    function bindProductEvents() {
        
        var $sizeSlider = $('#impulse-product-card-size');
        $sizeSlider.on('input', function() {
            var size = $(this).val();
            $('.impulse-products-grid').css('--product-card-size', size + 'px');
            localStorage.setItem('impulse-product-card-size', size);
        });
        var savedProductSize = localStorage.getItem('impulse-product-card-size');
        if (savedProductSize) {
            $sizeSlider.val(savedProductSize);
            $('.impulse-products-grid').css('--product-card-size', savedProductSize + 'px');
        }

        var searchTimer;
        var searchInitialized = false;
        var $searchInput = $('#impulse-products-search');

        var autofillClearInterval = setInterval(function() {
            if ($searchInput.val()) {
                $searchInput.val('');
            }
        }, 100);

        setTimeout(function() {
            clearInterval(autofillClearInterval);
            $searchInput.val(''); 
            searchInitialized = true;
        }, 800);
        
        $searchInput.on('input', function() {
            clearTimeout(searchTimer);
            var val = $(this).val();

            if (!searchInitialized) {
                $(this).val('');
                return;
            }
            
            searchTimer = setTimeout(function() {
                productsState.filters.search = val;
                productsState.page = 1;
                loadProductsList();
            }, 300);
        });

        $(document).on('click', '.impulse-status-tab', function() {
            var status = $(this).data('status');
            if (status === 'bundle') {
                productsState.filters.type = 'bundle';
                productsState.filters.status = 'all';
            } else {
                productsState.filters.type = '';
                productsState.filters.status = status;
            }
            productsState.page = 1;
            $('.impulse-status-tab').removeClass('active');
            $(this).addClass('active');
            loadProductsList();
        });

        $(document).on('click', '.impulse-stat-item', function() {
            var filter = $(this).data('filter');
            $('.impulse-stat-item').removeClass('active');
            $(this).addClass('active');
            
            if (filter === 'all' || filter === 'in_stock') {
                productsState.filters.stock_filter = '';
            } else {
                productsState.filters.stock_filter = filter;
            }
            productsState.page = 1;
            loadProductsList();
        });

        $(document).on('click', '.impulse-category-item', function() {
            var catId = $(this).data('id');
            $('.impulse-category-item').removeClass('active');
            $(this).addClass('active');
            productsState.filters.category = catId || 0;
            productsState.page = 1;
            loadProductsList();
        });

        $(document).on('click', '.impulse-view-toggle', function() {
            var view = $(this).data('view');
            $('.impulse-view-toggle').removeClass('active');
            $(this).addClass('active');
            productsState.view = view;
            renderProducts();
        });

        
        
        $(document).on('click', '.impulse-product-card, .impulse-products-table tr[data-id]', function(e) {

            
            if ($(e.target).closest('.impulse-card-drag, .col-drag, .impulse-card-status, .impulse-editable-input').length) {
                return;
            }
            var id = $(this).data('id');
            toggleProductSelection(id);
        });

        (function() {
            function findProduct(id) {
                for (var i = 0; i < productsState.products.length; i++) {
                    if (productsState.products[i].id == id) return productsState.products[i];
                }
                return null;
            }

            var _pCtxProductId = null;

            $(document).on('contextmenu', '#impulse-products-list, .impulse-products-table', function(e) {
                if (e.shiftKey) return;
                e.preventDefault();

                var $card = $(e.target).closest('.impulse-product-card, tr[data-id]');
                var pid = $card.length ? $card.data('id') : 0;
                _pCtxProductId = pid;

                var h = '';
                if (pid) {
                    var p = findProduct(pid);
                    var currency = window.Impulse.products.currency || '$';
                    var isFeatured = p && p.is_featured;

                    h += window.ctxItem('p-edit', 'Edit');
                    h += window.ctxDiv();

                    if (p) {
                        var priceLabel = 'Price: ';
                        if (p.price && parseFloat(p.price) > 0) priceLabel += currency + parseFloat(p.price).toFixed(2);
                        else priceLabel += 'not set';
                        if (p.sale_price && parseFloat(p.sale_price) > 0) priceLabel += ' / ' + currency + parseFloat(p.sale_price).toFixed(2);
                        h += window.ctxItem('p-quick-price', priceLabel);

                        var stockLabel = 'Stock: ';
                        if (p.stock_status === 'out') stockLabel += 'Out of stock';
                        else if (p.stock !== null) stockLabel += p.stock + ' in stock';
                        else stockLabel += 'In stock';
                        h += window.ctxItem('p-toggle-stock', stockLabel);

                        if (p.sku) h += window.ctxItem('p-copy-sku', 'Copy SKU: ' + p.sku);
                    }
                    h += window.ctxDiv();
                    h += window.ctxItem('p-toggle-status', (p && p.status === 'published') ? 'Unpublish' : 'Publish');
                    h += window.ctxItem('p-featured', isFeatured ? 'Remove Featured' : 'Mark as Featured');
                    h += window.ctxDiv();
                    h += window.ctxItem('p-duplicate', 'Duplicate');
                    h += window.ctxItem('p-trash', 'Delete', '', 'danger');
                }

                if (!h) return;
                window.ctxShow($('#impulse-context-menu'), e.clientX, e.clientY, h);
            });

            $(document).on('click', '.impulse-context-item[data-action^="p-"]', function() {
                var action = $(this).data('action');
                var pid = _pCtxProductId;
                if (!pid) return;
                var p = findProduct(pid);

                switch (action) {
                    case 'p-edit':
                        selectProduct(pid);
                        break;

                    case 'p-quick-price':
                        
                        var $item = $(this);
                        var currency = window.Impulse.products.currency || '$';
                        var reg = p ? (p.price || '') : '';
                        var sale = p ? (p.sale_price || '') : '';
                        $item.html(
                            '<div style="display:flex;gap:4px;align-items:center;width:100%">' +
                            '<input type="text" inputmode="decimal" id="pctx-price" value="' + reg + '" placeholder="Price" ' +
                                'style="width:65px;background:#2a2e33;border:1px solid #3a3f44;color:#e0e0e0;font-size:11px;padding:4px 6px;border-radius:3px;outline:none">' +
                            '<input type="text" inputmode="decimal" id="pctx-sale" value="' + sale + '" placeholder="Sale" ' +
                                'style="width:65px;background:#2a2e33;border:1px solid #3a3f44;color:#e0e0e0;font-size:11px;padding:4px 6px;border-radius:3px;outline:none">' +
                            '<span style="cursor:pointer;color:#999;font-size:11px;font-weight:600" id="pctx-price-ok">OK</span>' +
                            '</div>'
                        );
                        $item.off('click'); 
                        setTimeout(function() { $('#pctx-price').focus().select(); }, 50);

                        $(document).on('click.pctxprice', '#pctx-price-ok', function(ev) {
                            ev.stopPropagation();
                            var newPrice = $('#pctx-price').val().trim();
                            var newSale = $('#pctx-sale').val().trim();
                            $.post(window.Impulse.products.ajaxurl, {
                                action: 'instinctor_update_product',
                                nonce: Impulse.nonce,
                                product_id: pid,
                                price: newPrice,
                                sale_price: newSale
                            }, function(r) {
                                if (r.success) {
                                    if (p) { p.price = newPrice; p.sale_price = newSale; }
                                    
                                    var newDisplay = '';
                                    var rp = parseFloat(newPrice), sp = parseFloat(newSale);
                                    if (rp > 0 && sp > 0 && sp < rp) newDisplay = '<s style="color:#666">' + currency + rp.toFixed(2) + '</s> ' + currency + sp.toFixed(2);
                                    else if (sp > 0) newDisplay = currency + sp.toFixed(2);
                                    else if (rp > 0) newDisplay = currency + rp.toFixed(2);
                                    else newDisplay = '<span class="no-price">Set price</span>';
                                    var $priceEl = $('.impulse-product-card[data-id="' + pid + '"] .impulse-product-price .impulse-editable-value');
                                    if ($priceEl.length) $priceEl.html(newDisplay);
                                    window.showToast && window.showToast('Price updated');
                                }
                                window.ctxHide();
                            });
                            $(document).off('click.pctxprice');
                        });
                        $('#pctx-price, #pctx-sale').on('keydown', function(ev) {
                            if (ev.key === 'Enter') { ev.preventDefault(); $('#pctx-price-ok').trigger('click'); }
                            if (ev.key === 'Escape') { window.ctxHide(); }
                        });
                        return false; 
                        break;

                    case 'p-toggle-stock':
                        if (p) {
                            var newStatus = (p.stock_status === 'out') ? 'in' : 'out';
                            var newStock = (newStatus === 'out') ? 0 : (p.stock || null);
                            $.post(window.Impulse.products.ajaxurl, {
                                action: 'instinctor_update_product',
                                nonce: Impulse.nonce,
                                product_id: pid,
                                stock: newStock,
                                stock_status: newStatus
                            }, function(r) {
                                if (r.success) {
                                    p.stock_status = newStatus;
                                    if (newStatus === 'out') p.stock = 0;
                                    var $stockEl = $('.impulse-product-card[data-id="' + pid + '"] .impulse-product-stock');
                                    $stockEl.removeClass('out low').addClass(newStatus === 'out' ? 'out' : '');
                                    $stockEl.find('.impulse-editable-value').text(newStatus === 'out' ? 'Out of stock' : (newStock || '∞') + ' in stock');
                                    window.showToast && window.showToast(newStatus === 'out' ? 'Marked out of stock' : 'Marked in stock');
                                }
                            });
                        }
                        break;

                    case 'p-copy-sku':
                        if (p && p.sku) {
                            navigator.clipboard.writeText(p.sku).then(function() {
                                window.showToast && window.showToast('SKU copied');
                            });
                        }
                        break;

                    case 'p-toggle-status':
                        toggleProductStatus(pid);
                        break;

                    case 'p-featured':
                        toggleProductFeatured(pid);
                        break;

                    case 'p-duplicate':
                        duplicateProduct(pid);
                        break;

                    case 'p-trash':
                        trashProduct(pid, p ? p.name : '');
                        break;
                }

                if (action !== 'p-quick-price') {
                    window.ctxHide();
                }
            });
        })();

        $(document).on('click', '.impulse-product-card .impulse-card-status', function(e) {
            e.stopPropagation();
            var id = $(this).data('id');
            toggleProductStatus(id);
        });

        $(document).on('click', '.impulse-product-type-btn', function() {
            var ptype = $(this).data('ptype');
            $('.impulse-product-type-btn').removeClass('active');
            $(this).addClass('active');
            $('[name="product_type"]').val(ptype);
            var isSub    = ptype === 'subscription';
            var isBundle = ptype === 'bundle';
            $('#impulse-subscription-fields').toggle(isSub);
            $('#impulse-bundle-fields').toggle(isBundle);
            $('#impulse-price-fields').toggle(!isBundle);
            var isDownloadable = $('#impulse-product-downloadable').is(':checked');
            $('#impulse-stock-field').toggle(!isSub && !isBundle && !isDownloadable && window.Impulse.products.stockManagement);
        });

        
        $(document).on('click', '.impulse-product-card .impulse-inline-editable .impulse-editable-value', function(e) {
            e.stopPropagation();
            var $editable = $(this).closest('.impulse-inline-editable');
            var $value = $editable.find('.impulse-editable-value');
            var $input = $editable.find('.impulse-editable-input');

            $value.hide();
            $input.show().focus().select();
        });

        $(document).on('blur', '.impulse-product-card .impulse-editable-input', function() {
            saveInlineEdit($(this));
        });
        
        $(document).on('keydown', '.impulse-product-card .impulse-editable-input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).blur();
            } else if (e.key === 'Escape') {
                e.preventDefault();
                
                var $editable = $(this).closest('.impulse-inline-editable');
                var $value = $editable.find('.impulse-editable-value');
                $(this).hide();
                $value.show();
            }
        });

        $(document).on('keydown', '.impulse-product-card', function(e) {
            var $card = $(this);
            var id = $card.data('id');

            if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
                e.preventDefault();
                var $next = $card.next('.impulse-product-card');
                if ($next.length) $next.focus();
            } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
                e.preventDefault();
                var $prev = $card.prev('.impulse-product-card');
                if ($prev.length) $prev.focus();
            } else if (e.key === 'Enter') {
                e.preventDefault();
                selectProduct(id);
            } else if (e.key === 'Escape') {
                e.preventDefault();
                $card.blur();
                productsState.selectedProduct = null;
                $('.impulse-product-card').removeClass('selected');
                $('#impulse-products-edit').empty();
            } else if (e.key === 'Delete' || e.key === 'Backspace') {
                if (!$(e.target).is('input, textarea')) {
                    e.preventDefault();
                    var name = productsState.products.find(function(p) { return p.id === id; })?.name || 'Product';
                    trashProduct(id, name);
                }
            } else if ((e.metaKey || e.ctrlKey) && e.key === 'd') {
                e.preventDefault();
                duplicateProduct(id);
            } else if ((e.metaKey || e.ctrlKey) && e.key === 's') {
                e.preventDefault();
                
                if (productsState.selectedProduct) {
                    saveProduct(productsState.selectedProduct, false);
                }
            }
        });

        $(document).on('keydown', function(e) {
            if ((e.metaKey || e.ctrlKey) && e.key === 's') {
                if ($('.impulse-store-section[data-section="products"]').is(':visible') && productsState.selectedProduct) {
                    e.preventDefault();
                    saveProduct(productsState.selectedProduct, false);
                }
            }
        });

        
        
        $(document).on('click', '.impulse-category-item', function(e) {
            if ($(e.target).closest('.impulse-cat-menu').length) return;
            
            var id = $(this).data('id');
            $('.impulse-category-item').removeClass('active');
            $(this).addClass('active');
            
            productsState.filters.category = id;
            productsState.page = 1;
            loadProductsList();
        });

        $(document).on('dblclick', '.impulse-category-item .impulse-cat-name', function(e) {
            e.stopPropagation();
            var $item = $(this).closest('.impulse-category-item');
            var id = $item.data('id');
            if (id === 0) return; 
            
            var $name = $(this);
            var $input = $item.find('.impulse-cat-name-input');
            
            $name.hide();
            $input.show().focus().select();
        });

        $(document).on('blur', '.impulse-cat-name-input', function() {
            var $input = $(this);
            var $item = $input.closest('.impulse-category-item');
            var $name = $item.find('.impulse-cat-name');
            var id = $input.data('id');
            var newName = $input.val().trim();
            var oldName = $name.text();
            
            $input.hide();
            $name.show();
            
            if (newName && newName !== oldName) {
                $name.text(newName);
                
                $.post(window.Impulse.products.ajaxurl, {
                    action: 'instinctor_update_category',
                    nonce: window.Impulse.adminNonce,
                    id: id,
                    name: newName
                }, function(response) {
                    if (response.success) {
                        
                        (function updateCatInState(cats) {
                            if (!cats) return;
                            for (var i = 0; i < cats.length; i++) {
                                if (cats[i].id === parseInt(id)) { cats[i].name = newName; return; }
                                if (cats[i].children) updateCatInState(cats[i].children);
                            }
                        })(productsState.categories);
                        
                        var $catBtns = $('#impulse-product-categories');
                        if ($catBtns.length) {
                            var selected = [];
                            $catBtns.find('.impulse-category-btn.active').each(function() { selected.push(parseInt($(this).data('id'))); });
                            $catBtns.html(renderCategoryButtons(productsState.categories, selected));
                        }
                    } else {
                        $name.text(oldName);
                        $input.val(oldName);
                    }
                });
            }
        });

        $(document).on('keydown', '.impulse-cat-name-input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).blur();
            } else if (e.key === 'Escape') {
                var $item = $(this).closest('.impulse-category-item');
                var $name = $item.find('.impulse-cat-name');
                $(this).val($name.text()).hide();
                $name.show();
            }
        });

        $(document).on('click', '.impulse-add-subcategory', function(e) {
            e.stopPropagation();
            $('.impulse-cat-inline-add').remove();
            var parentId = $(this).data('id');
            var $item = $(this).closest('.impulse-category-item');
            var $children = $item.next('.impulse-cat-children');
            var inputHtml = '<div class="impulse-cat-inline-add" data-parent="' + parentId + '" style="display:flex;align-items:center;gap:4px;padding:4px 8px 4px 24px;margin-top:2px">' +
                '<input type="text" class="impulse-cat-new-input" placeholder="Subcategory name" ' +
                'style="flex:1;background:#2a2e33 !important;border:1px solid #3a3f44 !important;color:#e0e0e0 !important;font-size:11px;padding:5px 8px;border-radius:3px;outline:none !important;box-shadow:none !important">' +
                '<span class="impulse-cat-new-ok" style="cursor:pointer;color:#999;font-size:11px;font-weight:600;padding:0 4px">OK</span>' +
                '<span class="impulse-cat-new-cancel" style="cursor:pointer;color:#666;font-size:11px;padding:0 4px">&times;</span>' +
                '</div>';
            if ($children.length) {
                $children.append(inputHtml);
            } else {
                $item.after(inputHtml);
            }
            setTimeout(function() { $('.impulse-cat-inline-add .impulse-cat-new-input').last().focus(); }, 30);
        });

        $(document).on('click', '.impulse-cat-new-ok', function(e) {
            e.stopPropagation();
            var $wrap = $(this).closest('.impulse-cat-inline-add');
            var name = $wrap.find('.impulse-cat-new-input').val().trim();
            var parentId = $wrap.data('parent') || 0;
            if (!name) { $wrap.find('.impulse-cat-new-input').focus(); return; }
            $wrap.remove();
            createCategory(name, parentId);
        });

        $(document).on('click', '.impulse-cat-new-cancel', function(e) {
            e.stopPropagation();
            $(this).closest('.impulse-cat-inline-add').remove();
        });

        $(document).on('keydown', '.impulse-cat-new-input', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).closest('.impulse-cat-inline-add').find('.impulse-cat-new-ok').trigger('click');
            } else if (e.key === 'Escape') {
                $(this).closest('.impulse-cat-inline-add').remove();
            }
        });

        $(document).on('click', '.impulse-delete-category', function(e) {
            e.stopPropagation();
            var id = $(this).data('id');
            var name = $(this).data('name');
            deleteCategory(id, name);
        });

        $(document).on('dragstart', '.impulse-product-card', function(e) {
            var ids = [];

            if (productsState.bulkSelected.length > 0 && productsState.bulkSelected.indexOf($(this).data('id')) !== -1) {
                ids = productsState.bulkSelected;
            } else {
                ids = [$(this).data('id')];
            }
            
            e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify(ids));
            e.originalEvent.dataTransfer.effectAllowed = 'move';

            $(this).addClass('is-dragging');
        });
        
        $(document).on('dragend', '.impulse-product-card', function() {
            $(this).removeClass('is-dragging');
            $('.impulse-category-item').removeClass('drag-over');
        });

        $(document).on('change', '.impulse-bulk-check', function(e) {
            e.stopPropagation();
            var $item = $(this).closest('[data-id]');
            var id = $item.data('id');
            
            if ($(this).is(':checked')) {
                if (productsState.bulkSelected.indexOf(id) === -1) {
                    productsState.bulkSelected.push(id);
                }
                $item.addClass('bulk-checked');
            } else {
                productsState.bulkSelected = productsState.bulkSelected.filter(function(i) { return i !== id; });
                $item.removeClass('bulk-checked');
            }
            updateBulkToolbar();
        });

        $(document).on('change', '#impulse-bulk-all', function() {
            var checked = $(this).is(':checked');
            productsState.bulkSelected = [];
            
            if (checked) {
                productsState.products.forEach(function(p) {
                    productsState.bulkSelected.push(p.id);
                });
            }
            
            $('.impulse-bulk-check').prop('checked', checked);
            $('.impulse-product-card, .impulse-products-table tr[data-id]').toggleClass('bulk-checked', checked);
            updateBulkToolbar();
        });

        $(document).on('click', '.impulse-bulk-btn', function() {
            var action = $(this).data('action');
            if (productsState.bulkSelected.length === 0) return;

            if (action === 'ai_generate') {
                bulkGenerateAIContent();
                return;
            }
            
            var count = productsState.bulkSelected.length;
            var ids = productsState.bulkSelected.slice(); 

            $.post(window.Impulse.products.ajaxurl, {
                action: 'instinctor_bulk_products',
                nonce: window.Impulse.adminNonce,
                bulk_action: action,
                ids: ids
            }, function(response) {
                if (response.success) {
                    productsState.bulkSelected = [];
                    loadProductsList();
                    loadInventoryStats();
                    updateBulkToolbar();

                    var actionText = action === 'delete' ? 'moved to trash' : (action === 'publish' ? 'published' : (action === 'draft' ? 'set to draft' : action + 'ed'));
                    
                    if (action === 'delete') {
                        showToast(count + ' product' + (count > 1 ? 's' : '') + ' moved to trash', 'success', function() {
                            
                            $.post(window.Impulse.products.ajaxurl, {
                                action: 'instinctor_bulk_products',
                                nonce: window.Impulse.adminNonce,
                                bulk_action: 'restore',
                                ids: ids
                            }, function() {
                                loadProductsList();
                                loadInventoryStats();
                                showToast('Products restored');
                            });
                        });
                    } else {
                        showToast(count + ' product' + (count > 1 ? 's' : '') + ' ' + actionText);
                    }
                } else {
                    showToast('Error: ' + (response.data?.message || 'Unknown error'), 'error');
                }
            });
        });

        $(document).on('click', '.impulse-bulk-clear', function() {
            productsState.bulkSelected = [];
            $('.impulse-bulk-check').prop('checked', false);
            $('.impulse-product-card, .impulse-products-table tr[data-id]').removeClass('bulk-checked');
            updateBulkToolbar();
        });

        $(document).on('click', '#impulse-products-list', function(e) {
            if (window._productsLassoDone) { window._productsLassoDone = false; return; }
            
            var $t = $(e.target);
            var isEmptyArea = e.target === this
                || $t.hasClass('impulse-products-grid')
                || $t.hasClass('impulse-products-table')
                || ($t.is('tbody') && !$t.closest('tr[data-id]').length);
            if (isEmptyArea) {
                productsState.bulkSelected = [];
                productsState.selectedProduct = 0;
                $('.impulse-product-card, .impulse-products-table tr[data-id]').removeClass('selected');
                updateBulkToolbar();
                if (typeof window.crudRightPanelEmpty === 'function') window.crudRightPanelEmpty(); else storeRightCollapse();
            }
        });

        $(document).on('keydown.productsDeselect', function(e) {
            if (e.key !== 'Escape') return;
            if (!$('.impulse-store-section[data-section="products"]').is(':visible')) return;
            if (!productsState.selectedProduct) return;
            productsState.bulkSelected = [];
            productsState.selectedProduct = 0;
            $('.impulse-product-card, .impulse-products-table tr[data-id]').removeClass('selected');
            updateBulkToolbar();
            if (typeof window.crudRightPanelEmpty === 'function') window.crudRightPanelEmpty(); else storeRightCollapse();
        });

        (function() {
            var dragging = false, startX, startY, $box;

            $(document).on('mousedown', '#impulse-products-list', function(e) {
                if (e.button !== 0) return;
                if ($(e.target).closest('.impulse-product-card, .impulse-products-table tr[data-id]').length) return;
                e.preventDefault();
                dragging = true;
                startX = e.clientX;
                startY = e.clientY;
                $box = $('<div class="impulse-selection-box">').appendTo('body');
                $box.css({ left: startX, top: startY, width: 0, height: 0 });
            });

            $(document).on('mousemove.productsLasso', function(e) {
                if (!dragging) return;
                var x = Math.min(e.clientX, startX);
                var y = Math.min(e.clientY, startY);
                var w = Math.abs(e.clientX - startX);
                var h = Math.abs(e.clientY - startY);
                $box.css({ left: x, top: y, width: w, height: h });
            });

            $(document).on('mouseup.productsLasso', function(e) {
                if (!dragging) return;
                dragging = false;
                var boxRect = $box[0].getBoundingClientRect();
                $box.remove();
                $box = null;

                if (boxRect.width < 5 && boxRect.height < 5) return;

                var selected = [];
                $('.impulse-product-card:visible').each(function() {
                    var r = this.getBoundingClientRect();
                    if (!(r.right < boxRect.left || r.left > boxRect.right ||
                          r.bottom < boxRect.top  || r.top > boxRect.bottom)) {
                        $(this).addClass('selected');
                        var id = parseInt($(this).data('id'));
                        if (id && productsState.bulkSelected.indexOf(id) === -1) {
                            productsState.bulkSelected.push(id);
                        }
                        selected.push(id);
                    }
                });
                if (selected.length > 0) {
                    window._productsLassoDone = true;
                    updateBulkToolbar();
                }
            });
        }());
        
    }
    
    function loadProductsList(append) {
        if (productsState.loading) return;
        if (append && !productsState.hasMore) return;

        if (!window.Impulse || !window.Impulse.adminNonce || !window.Impulse.products) {
            setTimeout(function() { loadProductsList(append); }, 200);
            return;
        }
        
        productsState.loading = true;
        
        var $list = $('#impulse-products-list');
        
        if (append) {
            
            $list.find('.impulse-load-more').remove();
            $list.append('<div class="impulse-loading-more">Loading more...</div>');
        } else {

            productsState.page = 1;
            $list.html('<div class="impulse-loading">Loading products...</div>');
        }
        
        var ajaxData = {
            action: 'instinctor_get_products',
            nonce: window.Impulse.adminNonce,
            status: productsState.filters.status,
            stock_filter: productsState.filters.stock_filter,
            category: productsState.filters.category,
            search: productsState.filters.search,
            type: productsState.filters.type,
            page: productsState.page
        };

        $.ajax({
            url: window.Impulse.products.ajaxurl,
            type: 'POST',
            data: ajaxData,
            dataType: 'json',
            timeout: 30000,
            cache: false,
            xhrFields: {
                withCredentials: true
            },
            success: function(response) {
                productsState._retries = 0;
                if (response.data?.query_time_ms) {
                }
                productsState.loading = false;
                $list.find('.impulse-loading-more').remove();
                
                if (response.success) {
                    var newProducts = response.data.products;
                    productsState.totalPages = response.data.pages;
                    productsState.hasMore = productsState.page < productsState.totalPages;
                    
                    if (append) {
                        productsState.products = productsState.products.concat(newProducts);
                        appendProducts(newProducts);
                    } else {
                        productsState.products = newProducts;
                        renderProducts();
                    }
                    
                    productsState.page++;
                } else {
                    console.error('Products load error:', response);
                    if (!append) {
                        $list.html('<div class="impulse-loading">Error loading products: ' + (response.data?.message || 'Unknown error') + '</div>');
                    }
                }
            },
            error: function(xhr, status, error) {
                productsState.loading = false;
                $list.find('.impulse-loading-more').remove();
                console.error('Products AJAX failed:', {
                    status: status,
                    error: error,
                    readyState: xhr.readyState,
                    statusCode: xhr.status,
                    statusText: xhr.statusText,
                    responseText: xhr.responseText ? xhr.responseText.substring(0, 1000) : 'empty'
                });
                if (!append && productsState._retries < 2) {
                    productsState._retries = (productsState._retries || 0) + 1;
                    setTimeout(function() { loadProductsList(); }, 500);
                } else if (!append) {
                    $list.html('<div class="impulse-loading">Error loading products. Check console for details.</div>');
                }
            }
        });
    }
    
    function appendProducts(newProducts) {
        var $list = $('#impulse-products-list');
        var currency = window.Impulse.products.currency || '$';
        var startIndex = productsState.products.length - newProducts.length;
        
        var html = '';
        
        newProducts.forEach(function(p, i) {
            var index = startIndex + i;
            html += buildProductHtml(p, index);
        });
        
        if (productsState.view === 'cards') {
            $('#impulse-products-sortable').append(html);
        } else {
            $('#impulse-products-sortable').append(html);
        }
        
        initSortable();
        updateBulkToolbar();
    }
    
    function buildProductHtml(p, index) {
        var currency = window.Impulse.products.currency || '$';
        var stockClass = p.stock_status === 'out' ? 'out' : (p.stock_status === 'low' ? 'low' : '');
        var isChecked = productsState.bulkSelected.indexOf(p.id) !== -1;
        var isSelected = productsState.selectedProduct === p.id;
        var isLive = p.status === 'published';
        var isFeatured = p.is_featured || false;
        var hasRegularPrice = p.price && parseFloat(p.price) > 0;
        var hasSalePrice = p.sale_price && parseFloat(p.sale_price) > 0;
        var hasSale = hasRegularPrice && hasSalePrice && parseFloat(p.sale_price) < parseFloat(p.price);
        var html = '';
        
        var isBundle = p.type === 'bundle';

        if (productsState.view === 'cards') {
            var stockText = p.stock !== null ? p.stock : '∞';
            var stockDisplay = p.stock !== null ? p.stock + ' in stock' : 'In stock';
            if (p.stock_status === 'out') stockDisplay = 'Out of stock';
            else if (p.stock_status === 'low') stockDisplay = p.stock + ' left';

            var bundleCount = isBundle ? (function(){ try { return JSON.parse(p.bundle_products || '[]').length; } catch(e) { return 0; } })() : 0;
            var bundleDisc  = isBundle ? (parseFloat(p.bundle_discount_value) > 0
                ? (p.bundle_discount_type === 'percent'
                    ? p.bundle_discount_value + '% off'
                    : currency + parseFloat(p.bundle_discount_value).toFixed(2) + ' off')
                : 'No discount') : '';

            var priceDisplay = hasRegularPrice ? currency + parseFloat(p.price).toFixed(2) : '';
            var salePriceDisplay = hasSalePrice ? currency + parseFloat(p.sale_price).toFixed(2) : '';

            var actualPrice = '';
            if (hasSale) {
                actualPrice = salePriceDisplay;
            } else if (hasSalePrice) {
                actualPrice = salePriceDisplay; 
            } else if (hasRegularPrice) {
                actualPrice = priceDisplay;
            }
            
            html += '<div class="impulse-product-card' + (isChecked ? ' selected' : '') + '" data-id="' + p.id + '" data-index="' + index + '" data-status="' + p.status + '" tabindex="0" draggable="true">';

            html += '<div class="impulse-card-status' + (isLive ? ' is-live' : '') + '" data-id="' + p.id + '" title="' + (isLive ? 'Published - click to unpublish' : 'Draft - click to publish') + '">';
            html += '<span class="status-circle"></span>';
            html += '</div>';

            if (hasSale || isFeatured) {
                html += '<div class="impulse-product-badges">';
                if (hasSale) html += '<span class="impulse-product-badge">Sale</span>';
                if (isFeatured) html += '<span class="impulse-product-badge impulse-badge-featured">Featured</span>';
                html += '</div>';
            }

            html += '<div class="impulse-card-drag"><svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><line x1="8" y1="6" x2="8" y2="6.01"/><line x1="8" y1="12" x2="8" y2="12.01"/><line x1="8" y1="18" x2="8" y2="18.01"/><line x1="16" y1="6" x2="16" y2="6.01"/><line x1="16" y1="12" x2="16" y2="12.01"/><line x1="16" y1="18" x2="16" y2="18.01"/></svg></div>';

            html += '<div class="impulse-product-thumb">';
            if (p.image) {
                html += '<img src="' + p.image + '" alt="" loading="lazy">';
            } else {
                html += '<div class="impulse-thumb-placeholder"><img src="' + window.Impulse.pluginUrl + 'assets/images/placeholder-logo.svg" alt=""></div>';
            }
            html += '</div>';

            html += '<div class="impulse-product-info">';
            html += '<div class="impulse-product-name-row">';
            html += '<div class="impulse-product-name impulse-inline-editable" data-field="name" data-id="' + p.id + '">';
            html += '<span class="impulse-editable-value">' + escapeHtml(p.name || 'Untitled') + '</span>';
            html += '<input type="text" class="impulse-editable-input" value="' + escapeHtml(p.name || '') + '" style="display:none">';
            html += '</div>';
            if (isBundle) {
                html += '<span class="impulse-product-price" style="font-size:10px;color:#888">' + bundleCount + ' products</span>';
            } else {
                html += '<span class="impulse-product-price impulse-inline-editable" data-field="price" data-id="' + p.id + '">';
                if (actualPrice) {
                    html += '<span class="impulse-editable-value">' + actualPrice + '</span>';
                } else {
                    html += '<span class="impulse-editable-value no-price">Set price</span>';
                }
                html += '<input type="text" class="impulse-editable-input" value="' + (p.price || '') + '" placeholder="0.00" style="display:none">';
                html += '</span>';
            }
            html += '</div>';
            html += '</div>';
            html += '</div>';
        } else {
            
            var stockText = p.stock !== null ? p.stock : '—';
            if (p.stock_status === 'out') stockText = 'Out';

            var priceText = '—';
            if (hasSale || hasSalePrice) {
                priceText = currency + parseFloat(p.sale_price).toFixed(2);
            } else if (hasRegularPrice) {
                priceText = currency + parseFloat(p.price).toFixed(2);
            }
            
            html += '<tr data-id="' + p.id + '" data-index="' + index + '"' + (isChecked ? ' class="selected"' : '') + '>';
            html += '<td class="col-drag"><svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><line x1="8" y1="6" x2="8" y2="6.01"/><line x1="8" y1="12" x2="8" y2="12.01"/><line x1="8" y1="18" x2="8" y2="18.01"/><line x1="16" y1="6" x2="16" y2="6.01"/><line x1="16" y1="12" x2="16" y2="12.01"/><line x1="16" y1="18" x2="16" y2="18.01"/></svg></td>';
            html += '<td class="product-name">' + escapeHtml(p.name) + '</td>';
            html += '<td>' + (isBundle ? '—' : (p.sku || '—')) + '</td>';
            html += '<td>' + (isBundle ? bundleCount + ' products' : priceText) + '</td>';
            html += '<td class="' + (!isBundle ? 'impulse-product-stock ' + stockClass + ' impulse-inline-editable' : '') + '" data-field="stock" data-id="' + p.id + '">';
            if (isBundle) {
                html += '<span style="font-size:11px;color:#888">' + bundleDisc + '</span>';
            } else {
                html += '<span class="impulse-editable-value">' + stockText + '</span>';
                html += '<input type="text" class="impulse-editable-input" value="' + (p.stock !== null ? p.stock : '') + '" placeholder="∞" style="display:none">';
            }
            html += '</td>';
            html += '<td>' + ucfirst(p.type) + '</td>';
            html += '<td>' + ucfirst(p.status) + '</td>';
            html += '<td><button type="button" class="impulse-tool-btn impulse-product-star-btn' + (isFeatured ? ' is-featured' : '') + '" data-id="' + p.id + '" title="' + (isFeatured ? 'Remove from featured' : 'Mark as featured') + '" style="background:none;border:none;cursor:pointer;padding:4px;color:' + (isFeatured ? '#e0e0e0' : '#555') + '"><svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="' + (isFeatured ? 'currentColor' : 'none') + '" stroke-width="2"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg></button></td>';
            html += '</tr>';
        }
        
        return html;
    }
    
    function renderProducts() {
        var $list = $('#impulse-products-list');
        var products = productsState.products;
        
        if (products.length === 0) {
            $list.html('');
            updateBulkToolbar();
            return;
        }
        
        var html = '';
        var itemsHtml = '';
        
        products.forEach(function(p, index) {
            itemsHtml += buildProductHtml(p, index);
        });
        
        if (productsState.view === 'cards') {
            html = '<div class="impulse-products-grid" id="impulse-products-sortable">' + itemsHtml + '</div>';
        } else {
            html = '<table class="impulse-products-table">';
            html += '<thead><tr><th class="col-drag"></th><th>Product</th><th>SKU</th><th>Price</th><th>Stock</th><th>Type</th><th>Status</th><th style="width:40px;text-align:center" title="Featured">★</th></tr></thead>';
            html += '<tbody id="impulse-products-sortable">' + itemsHtml + '</tbody></table>';
        }
        
        $list.html(html);

        if (productsState.view === 'cards') {
            var savedSize = localStorage.getItem('impulse-product-card-size');
            if (savedSize) {
                $list.find('.impulse-products-grid').css('--product-card-size', savedSize + 'px');
            }
            $('#impulse-product-size-slider').show();
        } else {
            $('#impulse-product-size-slider').hide();
        }

        initSortable();
        updateBulkToolbar();
        bindInfiniteScroll();
    }
    
    function initSortable() {
        var $sortable = $('#impulse-products-sortable');
        if ($sortable.length && typeof Sortable !== 'undefined') {
            new Sortable($sortable[0], {
                animation: 150,
                handle: '.impulse-card-drag, .col-drag',
                ghostClass: 'sortable-ghost',
                onEnd: function(evt) {
                    if (evt.oldIndex !== evt.newIndex) {
                        reorderProducts(evt.oldIndex, evt.newIndex);
                    }
                }
            });
        }
    }
    
    function reorderProducts(oldIndex, newIndex) {
        
        var ids = [];
        $('#impulse-products-sortable').children().each(function() {
            ids.push($(this).data('id'));
        });
        
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_reorder_products',
            nonce: window.Impulse.adminNonce,
            product_ids: ids
        }, function(response) {
            if (!response.success) {
                loadProductsList(); 
            }
        });
    }
    
    function updateBulkToolbar() {
        var count = productsState.bulkSelected.length;
        var $toolbar = $('#impulse-bulk-toolbar');
        
        if (count > 0) {
            $toolbar.show().find('.impulse-bulk-count').text(count + ' selected');
        } else {
            $toolbar.hide();
        }

        var $selectAll = $('#impulse-bulk-all');
        if ($selectAll.length) {
            var totalVisible = productsState.products.length;
            $selectAll.prop('checked', count > 0 && count === totalVisible);
            $selectAll.prop('indeterminate', count > 0 && count < totalVisible);
        }
    }
    
    function bindInfiniteScroll() {
        var $list = $('#impulse-products-list');

        $list.off('scroll.infinite');

        $list.on('scroll.infinite', function() {
            if (productsState.loading || !productsState.hasMore) return;
            
            var $this = $(this);
            var scrollTop = $this.scrollTop();
            var scrollHeight = $this[0].scrollHeight;
            var clientHeight = $this.innerHeight();

            if (scrollTop + clientHeight >= scrollHeight - 200) {
                loadProductsList(true); 
            }
        });
    }
    
    function loadCategories(retries) {
        retries = retries || 0;
        var $tree = $('#impulse-categories-tree');

        if (!window.Impulse || !window.Impulse.adminNonce || !window.Impulse.products) {
            setTimeout(loadCategories, 200);
            return;
        }

        $.ajax({
            url: window.Impulse.products.ajaxurl,
            type: 'POST',
            data: {
                action: 'instinctor_get_categories',
                nonce: window.Impulse.adminNonce
            },
            dataType: 'json',
            timeout: 30000,
            cache: false,
            xhrFields: {
                withCredentials: true
            },
            success: function(response) {
                if (response.success) {
                    productsState.categories = response.data.categories || [];
                    renderCategories();
                } else {
                    console.error('Categories load error:', response);
                    productsState.categories = [];
                    renderCategories();
                }
            },
            error: function(xhr, status, error) {
                console.error('Categories AJAX failed:', {
                    status: status,
                    error: error,
                    readyState: xhr.readyState,
                    statusCode: xhr.status,
                    statusText: xhr.statusText,
                    responseText: xhr.responseText ? xhr.responseText.substring(0, 1000) : 'empty'
                });
                if (retries < 2) {
                    setTimeout(function() { loadCategories(retries + 1); }, 500);
                } else {
                    productsState.categories = [];
                    renderCategories();
                }
            }
        });
    }
    
    function renderCategories() {
        var $tree = $('#impulse-categories-tree');
        var categories = productsState.categories;
        
        var html = '';

        var allActive = productsState.filters.category === 0 ? ' active' : '';
        html += '<div class="impulse-category-item' + allActive + '" data-id="0" data-droptarget="root">';
        html += '<span class="impulse-cat-icon"><svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" fill="none" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg></span>';
        html += '<span class="impulse-cat-name">All Products</span>';
        html += '</div>';
        
        if (categories.length === 0) {
            html += '<div style="padding:16px 8px;color:#555;font-size:11px;text-align:center">No categories yet</div>';
        } else {
            html += '<div id="impulse-categories-sortable">';
            
            function renderCat(cat, level) {
                var isActive = productsState.filters.category === cat.id ? ' active' : '';
                var hasChildren = cat.children && cat.children.length > 0;
                
                html += '<div class="impulse-category-item' + isActive + '" data-id="' + cat.id + '" data-parent="' + (cat.parent_id || 0) + '" data-level="' + level + '" data-droptarget="category" draggable="true">';

                html += '<span class="impulse-cat-drag"><svg viewBox="0 0 24 24" width="8" height="8" stroke="currentColor" fill="none" stroke-width="3"><circle cx="5" cy="5" r="1"/><circle cx="5" cy="12" r="1"/><circle cx="5" cy="19" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg></span>';
                
                html += '<span class="impulse-cat-name">' + escapeHtml(cat.name) + '</span>';
                
                if (cat.count > 0) {
                    html += '<span class="impulse-cat-badge">' + cat.count + '</span>';
                }
                
                html += '<input type="text" class="impulse-cat-name-input" data-id="' + cat.id + '" value="' + escapeHtml(cat.name) + '" style="display:none">';
                
                html += '<div class="impulse-cat-actions">';
                html += '<button type="button" class="impulse-cat-action impulse-add-subcategory" data-id="' + cat.id + '" data-name="' + escapeHtml(cat.name) + '" title="Add subcategory"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></button>';
                html += '<button type="button" class="impulse-cat-action impulse-delete-category" data-id="' + cat.id + '" data-name="' + escapeHtml(cat.name) + '" title="Delete"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg></button>';
                html += '</div>';
                
                html += '</div>';
                
                if (hasChildren) {
                    html += '<div class="impulse-cat-children">';
                    cat.children.forEach(function(child) {
                        renderCat(child, level + 1);
                    });
                    html += '</div>';
                }
            }
            
            categories.forEach(function(cat) {
                renderCat(cat, 0);
            });
            
            html += '</div>';
        }
        
        $tree.html(html);
        initCategoryDragDrop();
    }
    
    var draggedCategoryId = null;
    
    function initCategoryDragDrop() {
        var $tree = $('#impulse-categories-tree');

        $tree.off('dragstart.cat').on('dragstart.cat', '.impulse-category-item[draggable="true"]', function(e) {
            draggedCategoryId = $(this).data('id');
            $(this).addClass('dragging');
            e.originalEvent.dataTransfer.effectAllowed = 'move';
            e.originalEvent.dataTransfer.setData('text/plain', draggedCategoryId);
        });

        $tree.off('dragend.cat').on('dragend.cat', '.impulse-category-item[draggable="true"]', function(e) {
            $(this).removeClass('dragging');
            $('.impulse-category-item').removeClass('drag-over drag-above drag-below');
            draggedCategoryId = null;
        });

        $tree.off('dragover.cat').on('dragover.cat', '.impulse-category-item[data-droptarget]', function(e) {
            e.preventDefault();
            var $target = $(this);
            var targetId = $target.data('id');

            if (targetId === draggedCategoryId) return;
            if (isDescendant(targetId, draggedCategoryId)) return;

            $('.impulse-category-item').removeClass('drag-over drag-above drag-below');

            var rect = this.getBoundingClientRect();
            var y = e.originalEvent.clientY - rect.top;
            var height = rect.height;
            
            if (targetId === 0) {
                
                $target.addClass('drag-over');
            } else if (y < height * 0.25) {
                $target.addClass('drag-above');
            } else if (y > height * 0.75) {
                $target.addClass('drag-below');
            } else {
                $target.addClass('drag-over'); 
            }
        });

        $tree.off('dragleave.cat').on('dragleave.cat', '.impulse-category-item[data-droptarget]', function(e) {
            $(this).removeClass('drag-over drag-above drag-below');
        });

        $tree.off('drop.cat').on('drop.cat', '.impulse-category-item[data-droptarget]', function(e) {
            e.preventDefault();
            var $target = $(this);
            var targetId = $target.data('id');
            var targetParent = $target.data('parent') || 0;
            
            if (!draggedCategoryId || targetId === draggedCategoryId) return;
            if (isDescendant(targetId, draggedCategoryId)) {
                showToast('Cannot move to own child', 'error');
                return;
            }
            
            var newParentId = 0;
            var action = '';
            
            if ($target.hasClass('drag-over')) {
                
                newParentId = targetId === 0 ? 0 : targetId;
                action = 'nest';
            } else if ($target.hasClass('drag-above') || $target.hasClass('drag-below')) {
                
                newParentId = targetParent;
                action = $target.hasClass('drag-above') ? 'above' : 'below';
            }

            $('.impulse-category-item').removeClass('drag-over drag-above drag-below dragging');

            updateCategoryParent(draggedCategoryId, newParentId, targetId, action);
        });
    }
    
    function isDescendant(potentialChildId, parentId) {
        
        function findInChildren(categories, targetId) {
            for (var i = 0; i < categories.length; i++) {
                if (categories[i].id === targetId) return true;
                if (categories[i].children && findInChildren(categories[i].children, targetId)) return true;
            }
            return false;
        }
        
        function findCategory(categories, id) {
            for (var i = 0; i < categories.length; i++) {
                if (categories[i].id === id) return categories[i];
                if (categories[i].children) {
                    var found = findCategory(categories[i].children, id);
                    if (found) return found;
                }
            }
            return null;
        }
        
        var parent = findCategory(productsState.categories, parentId);
        if (!parent || !parent.children) return false;
        return findInChildren(parent.children, potentialChildId);
    }
    
    function updateCategoryParent(categoryId, newParentId, targetId, action) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_move_category',
            nonce: window.Impulse.adminNonce,
            id: categoryId,
            parent_id: newParentId,
            target_id: targetId,
            position: action
        }, function(response) {
            if (response.success) {
                loadCategories(); 
                showToast('Category moved');
            } else {
                showToast(response.data?.message || 'Failed to move category', 'error');
            }
        });
    }

    function createCategory(name, parentId) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_create_category',
            nonce: window.Impulse.adminNonce,
            name: name,
            parent_id: parentId || 0
        }, function(response) {
            if (response.success) {
                loadCategories();
                showToast('Category created');
            } else {
                var errorMsg = response.data?.message || 'Unknown error';
                if (response.data?.db_error) {
                    console.error('DB Error:', response.data.db_error);
                }
                showToast('Error: ' + errorMsg, 'error');
            }
        }).fail(function(xhr, status, error) {
            console.error('Create category AJAX failed:', status, error);
            showToast('Failed to create category', 'error');
        });
    }
    
    function updateCategory(id, name) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_update_category',
            nonce: window.Impulse.adminNonce,
            id: id,
            name: name
        }, function(response) {
            if (response.success) {
                loadCategories();
                showToast('Category updated');
            } else {
                showToast('Error updating category', 'error');
            }
        });
    }
    
    function deleteCategory(id, name) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_delete_category',
            nonce: window.Impulse.adminNonce,
            id: id
        }, function(response) {
            if (response.success) {
                loadCategories();
                loadProductsList();
                showToast('"' + name + '" deleted');
            } else {
                showToast('Error deleting category', 'error');
            }
        });
    }
    
    function loadInventoryStats(retries) {
        retries = retries || 0;
        if (!window.Impulse || !window.Impulse.adminNonce || !window.Impulse.products) {
            setTimeout(loadInventoryStats, 200);
            return;
        }
        
        $.ajax({
            url: window.Impulse.products.ajaxurl,
            type: 'POST',
            data: {
                action: 'instinctor_get_inventory_stats',
                nonce: window.Impulse.adminNonce
            },
            dataType: 'json',
            timeout: 30000,
            cache: false,
            xhrFields: {
                withCredentials: true
            },
            success: function(response) {
                if (response.success) {
                    productsState.stats = response.data;
                    renderInventoryStats();
                }
            },
            error: function(xhr, status, error) {
                console.error('Inventory stats AJAX failed:', {
                    status: status,
                    error: error,
                    readyState: xhr.readyState,
                    statusCode: xhr.status
                });
                if (retries < 2) {
                    setTimeout(function() { loadInventoryStats(retries + 1); }, 500);
                }
            }
        });
    }
    
    function renderInventoryStats() {
        var stats = productsState.stats;
        $('.impulse-stat-item[data-filter="all"] .impulse-stat-num').text(stats.total);
        $('.impulse-stat-item[data-filter="in_stock"] .impulse-stat-num').text(stats.in_stock);
        $('.impulse-stat-item[data-filter="low_stock"] .impulse-stat-num').text(stats.low_stock);
        $('.impulse-stat-item[data-filter="out_of_stock"] .impulse-stat-num').text(stats.out_of_stock);
    }
    
    function toggleProductSelection(id) {
        var index = productsState.bulkSelected.indexOf(id);
        if (index === -1) {
            
            productsState.bulkSelected.push(id);
            $('.impulse-product-card[data-id="' + id + '"], .impulse-products-table tr[data-id="' + id + '"]').addClass('selected');
        } else {
            
            productsState.bulkSelected.splice(index, 1);
            $('.impulse-product-card[data-id="' + id + '"], .impulse-products-table tr[data-id="' + id + '"]').removeClass('selected');
        }

        productsState.selectedProduct = id;
        window.setProductsRightTitle('Product Details');
        var product = productsState.products.find(function(p) { return p.id === id; });
        if (product) {
            renderProductEdit(product);
        }
    }
    
    function selectProduct(id) {
        productsState.selectedProduct = id;
        window.setProductsRightTitle('Product Details');

        $('.impulse-product-card, .impulse-products-table tr').removeClass('selected');
        $('.impulse-product-card[data-id="' + id + '"], .impulse-products-table tr[data-id="' + id + '"]').addClass('selected');

        productsState.bulkSelected = [id];

        var product = productsState.products.find(function(p) { return p.id === id; });
        if (product) {
            renderProductEdit(product);
        }
    }
    
    function openNewProduct() {
        productsState.selectedProduct = 0;
        window.setProductsRightTitle('Add Product');
        renderProductEdit({
            id: 0,
            name: '',
            sku: '',
            price: '',
            sale_price: '',
            stock: '',
            status: 'draft',
            type: 'simple',
            attributes: [],
            variations: [],
            categories: [],
            description: ''
        });
    }
    
    function renderProductEdit(product) {
        if (typeof window.storeRightExpand === 'function') window.storeRightExpand();
        var currency = window.Impulse.products.currency || '$';
        var $panel = $('#impulse-products-edit');

        $panel.off('input.bundle click.bundle input.coupon input.gc click.gc');
        clearTimeout(window._bundleSaveTimer);
        window._activeCrudFeature = null;
        var html = '<div class="impulse-product-edit-form" data-id="' + product.id + '">';

        html += '<div class="impulse-form-group">';
        html += '<label>Images</label>';
        html += '<div class="impulse-product-images" id="impulse-product-images">';
        
        var allImages = [];
        if (product.image && product.featured_image) {
            allImages.push({ id: product.featured_image, url: product.image });
        }
        var gallery = product.gallery || [];
        gallery.forEach(function(img) {
            
            if (img.id && String(img.id) === String(product.featured_image)) return;
            allImages.push({ id: img.id, url: img.url });
        });
        allImages.forEach(function(img, idx) {
            html += '<div class="impulse-img-item" data-id="' + img.id + '">';
            html += '<img src="' + img.url + '" alt="">';
            if (idx === 0) html += '<span class="impulse-img-badge">Main</span>';
            html += '<button type="button" class="impulse-img-remove"><svg viewBox="0 0 24 24" width="8" height="8" fill="none" stroke="#999" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>';
            html += '</div>';
        });
        if (allImages.length < 10) {
            html += '<div class="impulse-img-add"><svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" fill="none" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></div>';
        }
        html += '</div>';
        html += '</div>';

        html += '<div class="impulse-form-group">';
        html += '<label>Name</label>';
        html += '<input type="text" name="name" value="' + escapeHtml(product.name || '') + '" placeholder="Product name" class="impulse-autosave-field" autocomplete="off">';
        html += '</div>';

        html += '<div class="impulse-form-row" id="impulse-price-fields"' + (isBundle ? ' style="display:none"' : '') + '>';
        html += '<div class="impulse-form-group">';
        html += '<label>Price</label>';
        html += '<input type="text" inputmode="decimal" name="price" value="' + escapeHtml(product.price || '') + '" placeholder="0.00" class="impulse-autosave-field" autocomplete="off">';
        html += '</div>';
        html += '<div class="impulse-form-group">';
        html += '<label>Sale Price</label>';
        html += '<input type="text" inputmode="decimal" name="sale_price" value="' + escapeHtml(product.sale_price || '') + '" placeholder="—" class="impulse-autosave-field" autocomplete="off">';
        html += '</div>';
        html += '</div>';

        var productType = product.type || 'physical';
        var isSubscription = productType === 'subscription';
        var isBundle = productType === 'bundle';
        var _st = window.Impulse.storeType || 'mixed';
        var typeButtons = [];
        
        if (_st !== 'digital_goods' && _st !== 'subscriptions' && _st !== 'memberships') typeButtons.push({v:'physical', l:'Physical'});
        if (_st !== 'physical_goods') typeButtons.push({v:'digital', l:'Digital'});
        typeButtons.push({v:'subscription', l:'Subscription'});
        typeButtons.push({v:'bundle', l:'Bundle'});
        if (typeButtons.length > 1) {
            html += '<div class="impulse-form-group">';
            html += '<label>Type</label>';
            html += '<div class="impulse-btn-group" style="display:flex;width:100%">';
            typeButtons.forEach(function(t) {
                var isActive = (t.v === 'subscription' ? isSubscription : (t.v === 'bundle' ? isBundle : productType === t.v));
                html += '<button type="button" class="impulse-btn-sm impulse-product-type-btn' + (isActive ? ' active' : '') + '" data-ptype="' + t.v + '" style="flex:1">' + t.l + '</button>';
            });
            html += '</div>';
            html += '<input type="hidden" name="product_type" value="' + productType + '">';
            html += '</div>';
        } else {
            html += '<input type="hidden" name="product_type" value="' + productType + '">';
        }

        var subInterval = product.subscription_interval || 'monthly';
        var subIntervalCount = product.subscription_interval_count || 1;
        var trialDays = product.trial_days || 0;
        html += '<div id="impulse-subscription-fields"' + (isSubscription ? '' : ' style="display:none"') + '>';
        html += '<div class="impulse-form-row">';
        html += '<div class="impulse-form-group">';
        html += '<label>Billing Interval</label>';
        html += '<select name="subscription_interval" class="impulse-autosave-field" style="width:100%;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;padding:0 6px">';
        html += '<option value="weekly"'  + (subInterval === 'weekly'  ? ' selected' : '') + '>Weekly</option>';
        html += '<option value="monthly"' + (subInterval === 'monthly' ? ' selected' : '') + '>Monthly</option>';
        html += '<option value="yearly"'  + (subInterval === 'yearly'  ? ' selected' : '') + '>Yearly</option>';
        html += '</select>';
        html += '</div>';
        html += '<div class="impulse-form-group">';
        html += '<label>Every</label>';
        html += '<input type="number" name="subscription_interval_count" value="' + subIntervalCount + '" min="1" max="12" class="impulse-autosave-field">';
        html += '</div>';
        html += '</div>';
        html += '<div class="impulse-form-group">';
        html += '<label>Trial Days</label>';
        html += '<input type="number" name="trial_days" value="' + trialDays + '" min="0" placeholder="0" class="impulse-autosave-field">';
        html += '</div>';
        html += '</div>';

        var bundleType     = product.bundle_type || 'fixed';
        var bundleDiscType = product.bundle_discount_type || 'percent';
        var bundleDiscVal  = product.bundle_discount_value || 0;
        var bundleMin      = product.bundle_min || 0;
        var bundleMax      = product.bundle_max || 0;
        var bundleProducts = product.bundle_products ? (function(){ try { return JSON.parse(product.bundle_products); } catch(e) { return []; } })() : [];
        var bundleNames    = product.bundle_product_names || {};
        var bundleImages   = product.bundle_product_images || {};
        var isByo          = bundleType === 'build_your_own';
        var bInp = 'height:26px;width:100%;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;font-size:11px;padding:0 8px;box-sizing:border-box';
        html += '<div id="impulse-bundle-fields"' + (isBundle ? '' : ' style="display:none"') + '>';
        html += '<div class="impulse-section-divider" style="margin-top:4px">Bundle</div>';
        html += '<div class="impulse-form-group"><label>Type</label>';
        html += '<div class="impulse-btn-group" style="display:flex;width:100%">';
        html += '<button type="button" class="impulse-btn-sm impulse-bundle-type-btn' + (bundleType === 'fixed' ? ' active' : '') + '" data-btype="fixed" style="flex:1">Fixed</button>';
        html += '<button type="button" class="impulse-btn-sm impulse-bundle-type-btn' + (bundleType === 'build_your_own' ? ' active' : '') + '" data-btype="build_your_own" style="flex:1">Build your own</button>';
        html += '</div><input type="hidden" name="bundle_type" value="' + bundleType + '"></div>';
        html += '<div class="impulse-form-group"><label>Discount</label>';
        html += '<div style="display:flex;width:100%">';
        html += '<div class="impulse-btn-group" style="flex-shrink:0">';
        html += '<button type="button" class="impulse-btn-sm impulse-bundle-disc-btn' + (bundleDiscType === 'percent' ? ' active' : '') + '" data-dtype="percent" style="width:30px;padding:0">%</button>';
        html += '<button type="button" class="impulse-btn-sm impulse-bundle-disc-btn' + (bundleDiscType === 'flat' ? ' active' : '') + '" data-dtype="flat" style="width:30px;padding:0">$</button>';
        html += '</div>';
        html += '<input type="number" name="bundle_discount_value" value="' + parseFloat(bundleDiscVal) + '" min="0" step="0.01" class="impulse-autosave-field" style="flex:1;min-width:0;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-left:none;border-radius:0 3px 3px 0;color:#e0e0e0;font-size:11px;padding:0 8px;box-sizing:border-box">';
        html += '<input type="hidden" name="bundle_discount_type" value="' + bundleDiscType + '">';
        html += '</div></div>';
        html += '<div id="impulse-bundle-picks-row"' + (isByo ? '' : ' style="display:none"') + '>';
        html += '<div class="impulse-form-group"><label>Picks</label>';
        html += '<div style="display:flex;align-items:center;gap:4px;width:100%">';
        html += '<input type="number" name="bundle_min" value="' + bundleMin + '" min="0" class="impulse-autosave-field" style="flex:1;' + bInp + ';text-align:center">';
        html += '<span style="font-size:11px;color:#888;flex-shrink:0">to</span>';
        html += '<input type="number" name="bundle_max" value="' + bundleMax + '" min="0" class="impulse-autosave-field" style="flex:1;' + bInp + ';text-align:center">';
        html += '</div>';
        html += '<div style="font-size:10px;color:#888;margin-top:2px">how many items the customer picks · 0 = no limit</div>';
        html += '</div></div>';
        html += '<div class="impulse-section-divider" style="margin-top:8px">Products in bundle</div>';
        html += '<div id="impulse-bundle-products-list" style="margin-bottom:6px">';
        html += '<input type="hidden" name="bundle_products_json" value="' + escapeHtml(JSON.stringify(bundleProducts)) + '">';
        if (bundleProducts.length) {
            bundleProducts.forEach(function(pid) {
                var pname = bundleNames[pid] || ('Product #' + pid);
                var pimg  = bundleImages[pid] || '';
                html += '<div class="impulse-bundle-chip" data-id="' + pid + '" style="display:flex;align-items:center;gap:6px;height:30px;padding:0 0 0 8px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;margin-bottom:3px;font-size:11px;color:#e0e0e0">';
                if (pimg) html += '<img src="' + pimg + '" style="width:20px;height:20px;object-fit:cover;border-radius:2px;flex-shrink:0">';
                html += '<span style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + escapeHtml(pname) + '</span>';
                html += '<button type="button" class="impulse-bundle-remove-product" data-id="' + pid + '" style="width:26px;height:26px;flex-shrink:0;background:none;border:none;border-left:1px solid #3a3f44;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0" title="Remove"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="#999" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>';
                html += '</div>';
            });
        } else {
            html += '<div style="font-size:11px;color:#888;padding:2px 0">No products yet.</div>';
        }
        html += '</div>';
        html += '<button type="button" id="impulse-bundle-add-product" class="impulse-btn-sm" style="width:100%;margin-bottom:8px">+ Add a Product</button>';
        html += '</div>'; 

        var storeType = window.Impulse.storeType || 'mixed';
        var isDigitalStore = (storeType === 'digital_goods');
        var isDownloadable = isDigitalStore || (product.downloadable == 1);
        var stockDisplay = (window.Impulse.products.stockManagement && !isDownloadable && !isSubscription && !isBundle) ? '' : ' style="display:none"';
        html += '<div class="impulse-form-row" id="impulse-stock-field"' + stockDisplay + '>';
        html += '<div class="impulse-form-group">';
        html += '<label>SKU</label>';
        html += '<input type="text" name="sku" value="' + escapeHtml(product.sku || '') + '" placeholder="SKU-001" class="impulse-autosave-field" autocomplete="off">';
        html += '</div>';
        html += '<div class="impulse-form-group">';
        html += '<label>Stock</label>';
        html += '<input type="text" inputmode="numeric" name="stock" value="' + escapeHtml(product.stock !== null && product.stock !== '' ? product.stock : '') + '" placeholder="∞" class="impulse-autosave-field" autocomplete="off">';
        html += '</div>';
        html += '</div>';

        html += '<div class="impulse-form-group">';
        html += '<label>Categories</label>';
        html += '<div class="impulse-category-buttons" id="impulse-product-categories">';
        html += renderCategoryButtons(productsState.categories, product.categories || []);
        html += '</div>';
        html += '</div>';

        html += '<div class="impulse-form-group">';
        html += '<label>Short Description</label>';
        html += '<textarea name="short_description" rows="2" placeholder="Brief summary..." class="impulse-autosave-field">' + escapeHtml(product.short_description || '') + '</textarea>';
        html += '</div>';

        html += '<div class="impulse-form-group" style="margin-top:4px">';
        html += '<label>Description</label>';
        html += '<textarea name="description" id="impulse-product-description" rows="2" placeholder="Full product description..." class="impulse-autosave-field" style="resize:none">' + escapeHtml(product.description || '') + '</textarea>';
        html += '</div>';

        if (isDigitalStore) {
            
            html += '<div class="impulse-section-divider">Downloads</div>';
            html += '<div id="impulse-downloads-manager">';
            html += '<div id="impulse-downloads-list" style="margin-bottom:6px"></div>';
            html += '<button type="button" id="impulse-add-download" style="width:100%;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#888;font-size:11px;cursor:pointer">+ Add File</button>';
            html += '</div>';
        } else if (storeType === 'mixed') {
            
            html += '<div class="impulse-section-divider">Downloads</div>';
            html += '<div class="impulse-form-group">';
            html += '<div class="impulse-inline-right">';
            html += '<label>Downloadable Product</label>';
            html += '<label class="impulse-toggle" style="position:relative;display:inline-block;width:32px;height:18px;flex-shrink:0">';
            html += '<input type="checkbox" id="impulse-product-downloadable" name="downloadable" value="1"' + (isDownloadable ? ' checked' : '') + '>';
            html += '<span class="impulse-toggle-slider"></span>';
            html += '</label>';
            html += '</div>';
            html += '</div>';
            html += '<div id="impulse-downloads-manager" style="' + (isDownloadable ? '' : 'display:none;') + '">';
            html += '<div id="impulse-downloads-list" style="margin-bottom:6px"></div>';
            html += '<button type="button" id="impulse-add-download" style="width:100%;height:26px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#888;font-size:11px;cursor:pointer">+ Add File</button>';
            html += '</div>';
        }

        
        if (!isSubscription && !isBundle) {
            html += '<div class="impulse-section-divider" style="margin-top:4px">Volume Pricing</div>';
            html += '<div id="impulse-volume-tiers-wrap">';
            html += '<div style="font-size:11px;color:#555;text-align:center;padding:12px 0" id="impulse-volume-loading">Loading...</div>';
            html += '</div>';
            html += '<button type="button" id="impulse-add-volume-tier" class="impulse-btn-sm" style="width:100%;margin-top:6px">+ Add Volume Tier</button>';
        }

        html += '</div>';

        var isPublished = product.status === 'published';
        html += '<div class="impulse-product-save-bar" style="display:flex;gap:6px;margin-top:12px;padding:0 0 12px">';
        if (isPublished) {
            html += '<button type="button" class="impulse-product-save-btn" data-action="update" style="flex:1;height:30px;background:#fff;border:1px solid #fff;border-radius:3px;color:#1d2327;font-size:11px;font-weight:600;cursor:pointer">Update</button>';
        } else {
            html += '<button type="button" class="impulse-product-save-btn" data-action="draft" style="flex:1;height:30px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#999;font-size:11px;cursor:pointer">Save Draft</button>';
            html += '<button type="button" class="impulse-product-save-btn" data-action="publish" style="flex:1;height:30px;background:#fff;border:1px solid #fff;border-radius:3px;color:#1d2327;font-size:11px;font-weight:600;cursor:pointer">Publish</button>';
        }
        html += '</div>';
        
        $panel.html(html);
        
        var $dt = $('#impulse-product-description');
        if ($dt.length) { $dt[0].style.height = 'auto'; $dt[0].style.height = Math.max(52, $dt[0].scrollHeight) + 'px'; }

        
        $(document).off('click.imgAdd').on('click.imgAdd', '.impulse-img-add', function() {
            var $strip = $('#impulse-product-images');
            if ($strip.find('.impulse-img-item').length >= 10) return;
            openMediaLibrary(function(attachment) {
                var item = '<div class="impulse-img-item" data-id="' + attachment.id + '">';
                item += '<img src="' + attachment.url + '" alt="">';
                if ($strip.find('.impulse-img-item').length === 0) item += '<span class="impulse-img-badge">Main</span>';
                item += '<button type="button" class="impulse-img-remove"><svg viewBox="0 0 24 24" width="8" height="8" fill="none" stroke="#999" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>';
                item += '</div>';
                $strip.find('.impulse-img-add').before(item);
                if ($strip.find('.impulse-img-item').length >= 10) $strip.find('.impulse-img-add').hide();
                refreshImageBadges();
            });
        });

        $(document).off('click.imgRemove').on('click.imgRemove', '.impulse-img-remove', function(e) {
            e.stopPropagation();
            $(this).closest('.impulse-img-item').remove();
            var $strip = $('#impulse-product-images');
            $strip.find('.impulse-img-add').show();
            refreshImageBadges();
        });

        $('#impulse-product-images').sortable({
            items: '.impulse-img-item',
            tolerance: 'pointer',
            placeholder: 'impulse-img-item ui-sortable-placeholder',
            update: function() {
                refreshImageBadges();
            }
        });

        function refreshImageBadges() {
            $('#impulse-product-images .impulse-img-item .impulse-img-badge').remove();
            var $first = $('#impulse-product-images .impulse-img-item').first();
            if ($first.length) {
                $first.find('img').after('<span class="impulse-img-badge">Main</span>');
            }
        }

        $(document).off('click.productSave').on('click.productSave', '.impulse-product-save-btn', function() {
            var $form = $('.impulse-product-edit-form');
            if (!$form.length) return;
            var productId = $form.data('id');
            var action = $(this).data('action');
            var status = null;
            if (action === 'draft') status = 'draft';
            else if (action === 'publish') status = 'published';
            
            saveProduct(productId, false, status);
        });

        $('[name="price"],[name="sale_price"]').on('blur', function() {
            var val = $(this).val().replace(',', '.');
            if (val && !isNaN(parseFloat(val))) {
                $(this).val(parseFloat(val).toFixed(2));
            }
        });

        $('[name="stock"]').on('blur', function() {
            var val = $(this).val();
            if (val !== '' && !isNaN(parseInt(val))) {
                $(this).val(Math.max(0, parseInt(val)));
            }
        });

        $('#impulse-product-categories').on('click', '.impulse-category-btn', function() {
            $(this).toggleClass('active');
        });

        var _storeType = window.Impulse.storeType || 'mixed';
        if (_storeType === 'digital_goods' || _storeType === 'mixed') {
            var productId = $('.impulse-product-edit-form').data('id');
            if (productId && $('#impulse-downloads-manager').length) {
                loadProductDownloads(productId);
            }
        }

        var _volProductId = $('.impulse-product-edit-form').data('id');
        if (_volProductId && $('#impulse-volume-tiers-wrap').length) {
            window.loadProductVolumeTiers(_volProductId);
        }

            $(document).off('change.dd').on('change.dd', '#impulse-product-downloadable', function() {
                var checked = this.checked;
                $('#impulse-downloads-manager').toggle(checked);
                
                var isSubscription = $('[name="product_type"]').val() === 'subscription';
                $('#impulse-stock-field').toggle(!checked && !isSubscription && window.Impulse.products.stockManagement);
                $.post(window.Impulse.products.ajaxurl, {
                    action: 'instinctor_toggle_product_downloadable',
                    nonce: window.Impulse.adminNonce,
                    product_id: $('.impulse-product-edit-form').data('id'),
                    downloadable: checked ? '1' : '0'
                });
            });

            $(document).off('click.ddadd').on('click.ddadd', '#impulse-add-download', function() {
                renderDownloadRow(null, $('.impulse-product-edit-form').data('id'));
            });

            $(document).off('click.dddel').on('click.dddel', '.impulse-dl-delete', function() {
                var $row = $(this).closest('.impulse-dl-row');
                var dlId = $row.data('id');
                var pid = $('.impulse-product-edit-form').data('id');
                if (!dlId) { $row.remove(); return; }
                $.post(window.Impulse.products.ajaxurl, {
                    action: 'instinctor_delete_product_download',
                    nonce: window.Impulse.adminNonce,
                    product_id: pid,
                    download_id: dlId
                }, function(r) {
                    if (r.success) loadProductDownloads(pid);
                });
            });

            $(document).off('blur.ddsave').on('blur.ddsave', '.impulse-dl-row input', function() {
                saveDownloadRow($(this).closest('.impulse-dl-row'));
            });

            $(document).off('click.ddupload').on('click.ddupload', '.impulse-dl-upload', function() {
                var $row = $(this).closest('.impulse-dl-row');
                openMediaLibrary(function(att) {
                    $row.find('[name="file_url"]').val(att.url);
                    if (!$row.find('[name="name"]').val()) {
                        $row.find('[name="name"]').val(att.filename || att.title || '');
                    }
                    saveDownloadRow($row);
                });
            });
    }

    function loadProductDownloads(productId) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_get_product_downloads',
            nonce: window.Impulse.adminNonce,
            product_id: productId
        }, function(r) {
            if (!r.success) return;
            var $list = $('#impulse-downloads-list').empty();
            if (r.data.downloads.length === 0) {
                $list.html('<div style="font-size:11px;color:#555;padding:4px 0">No files yet.</div>');
            } else {
                r.data.downloads.forEach(function(dl) {
                    $list.append(buildDownloadRowHtml(dl, productId));
                });
            }
        });
    }

    function buildDownloadRowHtml(dl, productId) {
        var limit   = dl && dl.download_limit !== null ? dl.download_limit : '';
        var expiry  = dl && dl.expiry_days    !== null ? dl.expiry_days    : '';
        var name    = dl ? escapeHtml(dl.name || '') : '';
        var fileUrl = dl ? escapeHtml(dl.file_url || '') : '';
        var id      = dl ? dl.id : '';

        var h = '<div class="impulse-dl-row" data-id="' + id + '" data-product="' + productId + '" style="background:#1a1d21;border:1px solid #2a2e33;border-radius:3px;padding:8px;margin-bottom:6px">';
        h += '<div style="display:flex;gap:4px;margin-bottom:4px">';
        h += '<input type="text" name="name" value="' + name + '" placeholder="File name" style="flex:1;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:0 6px;font-size:11px">';
        h += '<button type="button" class="impulse-dl-delete" style="width:24px;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#555;cursor:pointer;flex-shrink:0" title="Remove"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>';
        h += '</div>';
        h += '<div style="display:flex;gap:4px;margin-bottom:4px">';
        h += '<input type="text" name="file_url" value="' + fileUrl + '" placeholder="File URL" style="flex:1;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:0 6px;font-size:11px">';
        h += '<button type="button" class="impulse-dl-upload" style="width:24px;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#888;cursor:pointer;flex-shrink:0" title="Upload"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg></button>';
        h += '</div>';
        h += '<div style="display:flex;gap:8px">';
        h += '<div style="flex:1"><div style="font-size:10px;color:#555;margin-bottom:2px">Limit</div><input type="number" name="download_limit" value="' + limit + '" placeholder="∞" min="0" style="width:100%;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:0 6px;font-size:11px"></div>';
        h += '<div style="flex:1"><div style="font-size:10px;color:#555;margin-bottom:2px">Expiry (days)</div><input type="number" name="expiry_days" value="' + expiry + '" placeholder="Never" min="0" style="width:100%;height:24px;background:#2a2e33;border:1px solid #3a3f44;border-radius:3px;color:#e0e0e0;padding:0 6px;font-size:11px"></div>';
        h += '</div>';
        h += '</div>';
        return h;
    }

    function renderDownloadRow(dl, productId) {
        $('#impulse-downloads-list').find('.impulse-empty-dd').remove();
        $('#impulse-downloads-list').find('[style*="No files"]').remove();
        var $row = $(buildDownloadRowHtml(dl, productId));
        $('#impulse-downloads-list').append($row);
        $row.find('[name="name"]').trigger('focus');
    }

    function saveDownloadRow($row) {
        var productId = $row.data('product') || $('.impulse-product-edit-form').data('id');
        var name      = $row.find('[name="name"]').val().trim();
        var fileUrl   = $row.find('[name="file_url"]').val().trim();
        if (!name || !fileUrl) return;
        var data = {
            action: 'instinctor_save_product_download',
            nonce: window.Impulse.adminNonce,
            product_id: productId,
            id: $row.data('id') || '',
            name: name,
            file_url: fileUrl,
            download_limit: $row.find('[name="download_limit"]').val(),
            expiry_days: $row.find('[name="expiry_days"]').val()
        };
        $.post(window.Impulse.products.ajaxurl, data, function(r) {
            if (r.success) {
                $row.attr('data-id', r.data.id || $row.data('id'));
            }
        });
    }

    
    function generateAIContent(field) {
        
        var $form = $('.impulse-product-edit-form');
        var productId = $form.data('id');
        
        var context = {
            name: $form.find('[name="name"]').val(),
            short_description: $form.find('[name="short_description"]').val(),
            description: $form.find('[name="description"]').val(),
            price: $form.find('[name="price"]').val(),
            sku: $form.find('[name="sku"]').val()
        };
        
        var categories = [];
        $('#impulse-product-categories .impulse-category-btn.active').each(function() {
            categories.push($(this).text().trim());
        });
        if (categories.length) context.categories = categories;
        
        var $btn = $('.impulse-ai-generate-btn[data-field="' + field + '"]');
        var originalHtml = $btn.html();
        $btn.html('<span class="impulse-spinner"></span>').prop('disabled', true);
        
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_ai_generate_content',
            _wpnonce: window.Impulse.aiNonce || '',
            field: field,
            product_id: productId || 0,
            context: JSON.stringify(context)
        }, function(response) {
            $btn.html(originalHtml).prop('disabled', false);
            if (response.success && response.data && response.data.content) {
                var content = response.data.content;
                if (field === 'name') {
                    $form.find('[name="name"]').val(content);
                } else if (field === 'short_description') {
                    $form.find('[name="short_description"]').val(content);
                } else if (field === 'description') {
                    $form.find('[name="description"]').val(content);
                }
            } else {
                var msg = (response.data && typeof response.data === 'string') ? response.data : 'Failed to generate content';
                showToast(msg, 'error');
            }
        }).fail(function() {
            $btn.html(originalHtml).prop('disabled', false);
            showToast('Failed to generate content', 'error');
        });
    }
    
    function bulkGenerateAIContent() {
        
        var ids = productsState.bulkSelected.slice();
        var count = ids.length;
        
        if (count === 0) {
            showToast('No products selected', 'error');
            return;
        }

        var $btn = $('.impulse-bulk-ai-btn');
        var originalHtml = $btn.html();
        $btn.html('<span class="impulse-spinner"></span> Processing...').prop('disabled', true);
        
        var processed = 0;
        var success = 0;
        var errors = 0;

        function processNext() {
            if (ids.length === 0) {
                
                $btn.html(originalHtml).prop('disabled', false);
                if (success > 0) {
                    loadProductsList();
                    showToast(success + ' product' + (success > 1 ? 's' : '') + ' updated with generated content' + (errors > 0 ? ' (' + errors + ' failed)' : ''));
                } else {
                    showToast('Failed to generate content for selected products', 'error');
                }
                return;
            }
            
            var productId = ids.shift();
            processed++;
            $btn.html('<span class="impulse-spinner"></span> ' + processed + '/' + count);

            var product = productsState.products.find(function(p) { return p.id === productId; });
            if (!product) {
                errors++;
                processNext();
                return;
            }

            var context = {
                name: product.name || '',
                short_description: product.short_description || '',
                description: product.description || '',
                price: product.price || '',
                sku: product.sku || ''
            };
            
            if (product.categories && product.categories.length) {
                context.categories = product.categories.map(function(c) { return c.name || c; });
            }

            $.post(window.Impulse.products.ajaxurl, {
                action: 'instinctor_ai_generate_content',
                _wpnonce: window.Impulse.aiNonce || '',
                field: 'short_description',
                product_id: productId,
                context: JSON.stringify(context)
            }, function(response) {
                if (response.success && response.data.content) {
                    
                    $.post(window.Impulse.products.ajaxurl, {
                        action: 'instinctor_save_product',
                        nonce: window.Impulse.adminNonce,
                        id: productId,
                        short_description: response.data.content
                    }, function(saveResponse) {
                        if (saveResponse.success) {
                            success++;
                        } else {
                            errors++;
                        }
                        processNext();
                    }).fail(function() {
                        errors++;
                        processNext();
                    });
                } else {
                    errors++;
                    processNext();
                }
            }).fail(function() {
                errors++;
                processNext();
            });
        }

        processNext();
    }

    function renderCategoryButtons(categories, selectedIds) {
        var html = '';
        if (!categories || !categories.length) {
            html = '<div class="impulse-no-categories">No categories yet</div>';
            return html;
        }
        
        function renderCats(cats, level) {
            cats.forEach(function(cat) {
                var isSelected = selectedIds.indexOf(cat.id) !== -1;
                var indent = level > 0 ? ' style="margin-left:' + (level * 8) + 'px"' : '';
                html += '<button type="button" class="impulse-category-btn' + (isSelected ? ' active' : '') + '" data-id="' + cat.id + '"' + indent + '>' + escapeHtml(cat.name) + '</button>';
                if (cat.children && cat.children.length) {
                    renderCats(cat.children, level + 1);
                }
            });
        }
        
        renderCats(categories, 0);
        return html;
    }
    
    function renderAiButton(field) {
        var sparklesSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>';
        return '<span class="impulse-ai-wrapper"><button type="button" class="impulse-ai-generate-btn" data-field="' + field + '" data-tip="Generate">' + sparklesSvg + '</button></span>';
    }
    
    function renderAttributesList(attributes) {
        if (!attributes || !attributes.length) {
            return '<div class="impulse-no-attributes">No attributes. Add attributes like Size, Color, etc.</div>';
        }
        var html = '';
        attributes.forEach(function(attr, index) {
            html += '<div class="impulse-attribute-row" data-index="' + index + '">';
            html += '<div class="impulse-attribute-name">' + escapeHtml(attr.name) + '</div>';
            html += '<div class="impulse-attribute-values">' + escapeHtml(attr.values.join(', ')) + '</div>';
            html += '<div class="impulse-attribute-actions">';
            html += '<button type="button" class="impulse-edit-attribute" data-index="' + index + '" title="Edit"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button>';
            html += '<button type="button" class="impulse-delete-attribute" data-index="' + index + '" title="Delete"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg></button>';
            html += '</div>';
            html += '</div>';
        });
        return html;
    }
    
    function renderVariationsList(variations, currency) {
        if (!variations || !variations.length) {
            return '<div class="impulse-no-variations">No variations. Add attributes and click Generate.</div>';
        }
        var html = '<div class="impulse-variations-table">';
        variations.forEach(function(v, index) {
            var attrLabel = v.attributes ? Object.values(v.attributes).join(' / ') : 'Variation ' + (index + 1);
            html += '<div class="impulse-variation-row' + (v.expanded ? ' expanded' : '') + '" data-index="' + index + '">';
            html += '<div class="impulse-variation-header">';
            html += '<span class="impulse-variation-toggle"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg></span>';
            html += '<span class="impulse-variation-label">' + escapeHtml(attrLabel) + '</span>';
            html += '<span class="impulse-variation-price">' + (v.price ? currency + parseFloat(v.price).toFixed(2) : '—') + '</span>';
            html += '<span class="impulse-variation-stock">' + (v.stock !== null && v.stock !== '' ? v.stock : '∞') + '</span>';
            html += '<button type="button" class="impulse-delete-variation" data-index="' + index + '" title="Delete"><svg viewBox="0 0 24 24" width="12" height="12" stroke="currentColor" fill="none" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>';
            html += '</div>';
            html += '<div class="impulse-variation-body">';
            html += '<div class="impulse-form-row">';
            html += '<div class="impulse-form-group"><label>Price</label><input type="number" step="0.01" min="0" name="variation_price_' + index + '" value="' + (v.price || '') + '" placeholder="0.00" class="impulse-variation-field" autocomplete="off"></div>';
            html += '<div class="impulse-form-group"><label>Sale</label><input type="number" step="0.01" min="0" name="variation_sale_' + index + '" value="' + (v.sale_price || '') + '" placeholder="0.00" class="impulse-variation-field" autocomplete="off"></div>';
            html += '</div>';
            html += '<div class="impulse-form-row">';
            html += '<div class="impulse-form-group"><label>Stock</label><input type="number" step="1" min="0" name="variation_stock_' + index + '" value="' + (v.stock !== null && v.stock !== '' ? v.stock : '') + '" placeholder="∞" class="impulse-variation-field" autocomplete="off"></div>';
            html += '<div class="impulse-form-group"><label>SKU</label><input type="text" name="variation_sku_' + index + '" value="' + escapeHtml(v.sku || '') + '" placeholder="SKU" class="impulse-variation-field" autocomplete="off"></div>';
            html += '</div>';
            html += '</div>';
            html += '</div>';
        });
        html += '</div>';
        return html;
    }

    var variableProductState = {
        attributes: [],
        variations: []
    };
    
    function getProductAttributes() {
        return variableProductState.attributes;
    }
    
    function setProductAttributes(attrs) {
        variableProductState.attributes = attrs || [];
    }
    
    function getProductVariations() {
        return variableProductState.variations;
    }
    
    function setProductVariations(vars) {
        variableProductState.variations = vars || [];
    }
    
    function openMediaLibrary(callback) {
        openImglibPicker({ label: 'Select Product Image', simple: true }, function(attachment) {
            callback(attachment);
        });
    }
    
    function trashProduct(id, name) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_trash_product',
            nonce: window.Impulse.adminNonce,
            id: id
        }, function(response) {
            if (response.success) {
                
                if (productsState.selectedProduct === id) {
                    productsState.selectedProduct = null;
                    $('#impulse-products-edit').empty();
                }
                
                loadProductsList();
                loadInventoryStats();

                showToast('"' + name + '" moved to trash', 'success', function() {
                    restoreProduct(id);
                });
            } else {
                showToast('Error trashing product', 'error');
            }
        });
    }
    
    function restoreProduct(id) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_restore_product',
            nonce: window.Impulse.adminNonce,
            id: id
        }, function(response) {
            if (response.success) {
                loadProductsList();
                loadInventoryStats();
                showToast('Product restored');
            }
        });
    }
    
    function duplicateProduct(id) {
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_duplicate_product',
            nonce: window.Impulse.adminNonce,
            id: id
        }, function(response) {
            if (response.success) {
                
                productsState.filters.status = 'all';
                $('.impulse-status-tab').removeClass('active');
                $('.impulse-status-tab[data-status="all"]').addClass('active');
                loadProductsList();
                loadInventoryStats();
                showToast('Product duplicated');
                
                if (response.data && response.data.id) {
                    setTimeout(function() { selectProduct(response.data.id); }, 300);
                }
            } else {
                showToast('Error duplicating product', 'error');
            }
        });
    }
    
    function toggleProductStatus(id) {
        var product = productsState.products.find(function(p) { return p.id === id; });
        if (!product) return;
        
        var newStatus = product.status === 'published' ? 'draft' : 'published';
        
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_update_product_status',
            nonce: window.Impulse.adminNonce,
            id: id,
            status: newStatus
        }, function(response) {
            if (response.success) {
                
                product.status = newStatus;

                var $card = $('.impulse-product-card[data-id="' + id + '"]');
                var $status = $card.find('.impulse-card-status');
                if (newStatus === 'published') {
                    $status.addClass('is-live').attr('title', 'Published - click to unpublish');
                } else {
                    $status.removeClass('is-live').attr('title', 'Draft - click to publish');
                }
                $card.attr('data-status', newStatus);
                
                showToast(newStatus === 'published' ? 'Product is now live' : 'Product set to draft');
            }
        });
    }
    
    function toggleProductFeatured(id) {
        var product = productsState.products.find(function(p) { return p.id === id; });
        if (!product) return;
        
        var newFeatured = !product.is_featured;
        
        $.post(window.Impulse.products.ajaxurl, {
            action: 'instinctor_update_product_featured',
            nonce: window.Impulse.adminNonce,
            id: id,
            featured: newFeatured ? 1 : 0
        }, function(response) {
            if (response.success) {
                product.is_featured = newFeatured;

                var $star = $('.impulse-product-star-btn[data-id="' + id + '"]');
                if (newFeatured) {
                    $star.addClass('is-featured').attr('title', 'Remove from featured');
                    $star.find('svg').attr('fill', 'currentColor');
                    $star.css('color', '#e0e0e0');
                } else {
                    $star.removeClass('is-featured').attr('title', 'Mark as featured');
                    $star.find('svg').attr('fill', 'none');
                    $star.css('color', '#555');
                }
                
                showToast(newFeatured ? 'Added to featured' : 'Removed from featured');
            }
        });
    }
    
    function updateProductField(id, field, value) {
        var data = {
            action: 'instinctor_update_product_field',
            nonce: window.Impulse.adminNonce,
            id: id,
            field: field,
            value: value
        };
        
        $.post(window.Impulse.products.ajaxurl, data, function(response) {
            if (response.success) {
                
                var product = productsState.products.find(function(p) { return p.id === id; });
                if (product) {
                    product[field] = value;
                }
                loadInventoryStats();
            }
        });
    }
    
    function saveInlineEdit($input) {
        var $editable = $input.closest('.impulse-inline-editable');
        var field = $editable.data('field');
        var id = $editable.data('id');
        var value = $input.val().trim();
        var currency = window.Impulse.products.currency || '$';

        if (field === 'price' || field === 'sale_price') {
            value = value.replace(',', '.');
            if (value && !isNaN(parseFloat(value))) {
                value = parseFloat(value).toFixed(2);
            }
        }

        if (field === 'stock') {
            if (value === '' || value === '∞') {
                value = '';
            } else if (!isNaN(parseInt(value))) {
                value = Math.max(0, parseInt(value)).toString();
            }
        }

        var $value = $editable.find('.impulse-editable-value');
        if (field === 'name') {
            $value.text(value || 'Untitled');
        } else if (field === 'price') {
            if (value) {
                $value.text(currency + value);
            } else {
                $value.html('<span class="no-price">Set price</span>');
            }
        } else if (field === 'stock') {
            if (value === '') {
                $value.text('In stock');
            } else {
                $value.text(value + ' in stock');
            }
            
            $editable.removeClass('low out');
            if (value !== '' && parseInt(value) === 0) $editable.addClass('out');
        }

        $input.hide();
        $value.show();

        updateProductField(id, field, value);

        if (productsState.selectedProduct === id) {
            var $formField = $('.impulse-product-edit-form [name="' + field + '"]');
            if ($formField.length) {
                $formField.val(value);
            }
        }
    }
    
    function saveProduct(id, isAutoSave, statusOverride) {
        var $form = $('.impulse-product-edit-form');

        var categories = [];
        $('#impulse-product-categories .impulse-category-btn.active').each(function() {
            categories.push($(this).data('id'));
        });

        var currentProduct = productsState.products.find(function(p) { return p.id === id; });
        var status = statusOverride || (currentProduct ? currentProduct.status : 'draft');

        var allImageIds = [];
        $('#impulse-product-images .impulse-img-item').each(function() {
            var imgId = parseInt($(this).data('id'));
            if (imgId > 0) allImageIds.push(imgId);
        });
        var featuredImage = allImageIds.length > 0 ? allImageIds[0] : '';
        var galleryIds = allImageIds.slice(1);

        var saveData = {
            action: 'instinctor_save_product',
            nonce: window.Impulse.adminNonce,
            id: id,
            name: $form.find('[name="name"]').val(),
            sku: $form.find('[name="sku"]').val(),
            status: status,
            featured_image: featuredImage,
            short_description: $form.find('[name="short_description"]').val(),
            description: $form.find('[name="description"]').val(),
            price: $form.find('[name="price"]').val(),
            sale_price: $form.find('[name="sale_price"]').val(),
            stock: $form.find('[name="stock"]').val(),
            gallery_json: JSON.stringify(galleryIds),
            categories: categories,
            product_type: $form.find('[name="product_type"]').val() || 'physical',
            subscription_interval: $form.find('[name="subscription_interval"]').val() || '',
            subscription_interval_count: $form.find('[name="subscription_interval_count"]').val() || '',
            trial_days: $form.find('[name="trial_days"]').val() || '',
            bundle_type: $form.find('[name="bundle_type"]').val() || '',
            bundle_discount_type: $form.find('[name="bundle_discount_type"]').val() || 'percent',
            bundle_discount_value: $form.find('[name="bundle_discount_value"]').val() || '',
            bundle_min: $form.find('[name="bundle_min"]').val() || '',
            bundle_max: $form.find('[name="bundle_max"]').val() || '',
            bundle_products: $form.find('[name="bundle_products_json"]').val() || '[]'
        };

        $('.impulse-product-save-btn').prop('disabled', true).css('opacity', '0.5');
        
        $.post(window.Impulse.products.ajaxurl, saveData, function(response) {
            $('.impulse-product-save-btn').prop('disabled', false).css('opacity', '');
            
            if (response.success) {
                var verb = statusOverride === 'published' ? 'Product published' : 'Product saved';
                showToast(verb);

                loadProductsList();
                loadInventoryStats();
                loadCategories();

                if (!id && response.data.id) {
                    productsState.selectedProduct = response.data.id;
                    $form.data('id', response.data.id);
                }

                if (statusOverride) {
                    var newStatus = statusOverride;
                    var $bar = $('.impulse-product-save-bar');
                    if (newStatus === 'published') {
                        $bar.html('<button type="button" class="impulse-product-save-btn" data-action="update" style="flex:1;height:30px;background:#fff;border:1px solid #fff;border-radius:3px;color:#1d2327;font-size:11px;font-weight:600;cursor:pointer">Update</button>');
                    }
                }
            } else {
                showToast('Error saving product', 'error');
            }
        }).fail(function() {
            $('.impulse-product-save-btn').prop('disabled', false).css('opacity', '');
            showToast('Error saving product', 'error');
        });
    }

    function showToast(message, type, undoCallback) {
        type = type || 'success';
        
        $('.impulse-toast').remove();
        
        var $toast = $('<div class="impulse-toast"></div>').text(message);
        if (type === 'error') $toast.css('background', '#c0392b');
        if (undoCallback) {
            $toast.append(' <button type="button" class="impulse-toast-undo">Undo</button>');
        }
        
        $('body').append($toast);

        if (undoCallback) {
            $toast.find('.impulse-toast-undo').on('click', function() {
                undoCallback();
                $toast.remove();
            });
        }

        setTimeout(function() {
            $toast.css({ opacity: 0, transition: 'opacity 0.3s' });
            setTimeout(function() { $toast.remove(); }, 300);
        }, undoCallback ? 5000 : 3000);
    }
    
    function escapeHtml(text) {
        if (!text) return '';
        var div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    function ucfirst(str) {
        if (!str) return '';
        return str.charAt(0).toUpperCase() + str.slice(1);
    }

    window.showToast          = showToast;
    window.impulseConfirm = function(msg) { return window.confirm(msg); };
    window.impulsePrompt  = function(msg, def) { return window.prompt(msg, def !== undefined ? def : ''); };
    window.showImpulseToast   = showToast;
    window.openNewProduct    = openNewProduct;
    window.renderProductEdit = renderProductEdit;
    
})(jQuery);

