/* Bizmart Products Admin JS */
(function($){
    'use strict';

    var data = window.BizmartProductsData || {};

    function t(en, fr, ar) {
        var lang = data.adminLang || (window.BizmartAnalytics && (BizmartAnalytics.admin_lang || BizmartAnalytics.adminLang)) || 'en';
        if (lang === 'ar') {
            var dict = (window.BizmartI18n && BizmartI18n.ar) ? BizmartI18n.ar : null;
            return ar || (dict && dict[en]) || en;
        }
        return lang === 'fr' ? (fr || en) : en;
    }

    window.BizProducts = window.BizProducts || {};

    var BizProducts = window.BizProducts = Object.assign(window.BizProducts, {
        adminLang: data.adminLang || 'en',
        t: t,

        variationCount: 0,
        attributeCount: 1,
        digitalFiles: [],
        simpleGallery: [],
        variableGallery: [],
        tags: {
            simple: [],
            variable: [],
            external: [],
            digital: [],
            grouped: []
        },

        bindEvents: function() {
            $(document).on('click', '.biz-tag-remove', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var $btn = $(this);
                var type = $btn.data('biz-type');
                var tag = $btn.data('biz-tag');

                // Product tags
                if (type && tag !== undefined) {
                    $btn.closest('.biz-tag').remove();
                    BizProducts.removeTag(type, String(tag));
                    return;
                }

                // Attribute value tags
                var $tagEl = $btn.closest('.biz-tag');
                var $row = $tagEl.closest('.biz-attribute-row');
                var rowId = $row.data('id');
                if (rowId) {
                    $tagEl.remove();
                    BizProducts.updateAttributeValues(rowId);
                }
            });

            // Ensure attribute value inputs added later also work
            $(document).on('keypress', '.biz-attribute-values-input', function(e) {
                if (e.key !== 'Enter') return;
                e.preventDefault();

                var tag = $(this).val().trim();
                if (!tag) return;

                var rowId = $(this).closest('.biz-attribute-row').data('id');
                var $container = $('#biz-attribute-values-' + rowId);

                var $tagElement = $('<span>', { class: 'biz-tag' }).text(tag + ' ');
                $tagElement.append($('<span>', { class: 'biz-tag-remove', text: '×' }));
                $container.prepend($tagElement);

                $(this).val('');
                BizProducts.updateAttributeValues(rowId);
            });
        },

        addTag: function(type, tag) {
            tag = (tag || '').trim();
            if (!tag) return;

            if (!this.tags[type]) this.tags[type] = [];
            if (this.tags[type].includes(tag)) return;

            this.tags[type].push(tag);

            var $container = $('#biz-' + type + '-tags-container');
            var $tag = $('<span>', { class: 'biz-tag' }).text(tag + ' ');
            $tag.append(
                $('<span>', {
                    class: 'biz-tag-remove',
                    text: '×',
                    'data-biz-type': type,
                    'data-biz-tag': tag
                })
            );
            $container.prepend($tag);

            $('#biz-' + type + '-tags').val(this.tags[type].join(','));
        },

        removeTag: function(type, tag) {
            if (!this.tags[type]) return;
            this.tags[type] = this.tags[type].filter(function(tg){ return tg !== tag; });
            $('#biz-' + type + '-tags').val(this.tags[type].join(','));
        },

        switchTab: function(tab) {
            $('.biz-tab').removeClass('active');
            $('.biz-tab-content').removeClass('active');
            $('.biz-tab[data-tab="' + tab + '"]').addClass('active');
            $('#biz-tab-' + tab).addClass('active');
        },

        toggleSection: function(sectionId) {
            var $content = $('#' + sectionId);
            var $icon = $content.prev().find('span');
            $content.toggleClass('show');
            $icon.text($content.hasClass('show') ? '▲' : '▼');
        },

        toggleShippingSection: function(isVirtual) {
            var $shippingSection = $('#biz-simple-shipping-section');
            if (isVirtual) $shippingSection.removeClass('show');
            else $shippingSection.addClass('show');
        },

        createCategory: function(type) {
            var categoryName = $('#biz-' + type + '-new-category').val().trim();
            if (!categoryName) {
                alert(t('Please enter a category name', 'Veuillez entrer un nom de catégorie'));
                return;
            }

            $.post(BizmartAnalytics.ajax_url, {
                action: 'bizmart_create_product_category',
                nonce: BizmartAnalytics.nonce,
                name: categoryName
            }, function(response) {
                if (response.success) {
                    var id = String(response.data.id);
                    var name = response.data.name;

                    $('.biz-multiselect').each(function() {
                        var $sel = $(this);
                        if ($sel.attr('id') && $sel.attr('id').includes('categories')) {
                            if ($sel.find('option[value="' + id + '"]').length) return;
                            $sel.append($('<option>', { value: id, text: name }));
                        }
                    });

                    var $current = $('#biz-' + type + '-categories');
                    var currentVal = ($current.val() || []).map(String);
                    if (!currentVal.includes(id)) currentVal.push(id);
                    $current.val(currentVal);

                    $('#biz-' + type + '-new-category').val('');
                    alert(t('Category created successfully!', 'Catégorie créée avec succès!'));
                } else {
                    alert(t('Error: ', 'Erreur: ') + (response.data || ''));
                }
            });
        },

        onExistingAttributeSelect: function(select) {
            var $select = $(select);
            var $row = $select.closest('.biz-attribute-row');
            var attributeSlug = $select.val();

            if (attributeSlug === 'new') {
                $row.find('.attribute-name').show().focus();
                $row.find('.biz-attribute-values-input').prop('disabled', false);
                return;
            }

            if (attributeSlug) {
                var selectedOption = $select.find('option:selected');
                var attributeLabel = selectedOption.data('label') || attributeSlug;

                $row.find('.attribute-name').val(attributeLabel).show();

                $.post(BizmartAnalytics.ajax_url, {
                    action: 'bizmart_get_attribute_terms',
                    nonce: BizmartAnalytics.nonce,
                    attribute_name: attributeSlug
                }, function(response) {
                    if (response.success && response.data.terms && response.data.terms.length > 0) {
                        $row.find('.biz-attribute-values-input').siblings('.biz-tag').remove();

                        response.data.terms.forEach(function(term) {
                            var tag = String(term.name || '');
                            var rowId = $row.data('id');
                            var $container = $row.find('#biz-attribute-values-' + rowId);

                            var $tagEl = $('<span>', { class: 'biz-tag' }).text(tag + ' ');
                            $tagEl.append($('<span>', { class: 'biz-tag-remove', text: '×' }));
                            $container.prepend($tagEl);

                            BizProducts.updateAttributeValues(rowId);
                        });

                        $row.find('.biz-attribute-values-input').prop('disabled', false);
                    }
                });
            } else {
                $row.find('.attribute-name').val('');
                $row.find('.biz-attribute-values-input').siblings('.biz-tag').remove();
                $row.find('.biz-attribute-values-input').prop('disabled', true);
                BizProducts.updateAttributeValues($row.data('id'));
            }
        },

        updateAttributeValues: function(rowId) {
            var $row = $('.biz-attribute-row[data-id="' + rowId + '"]');
            var tags = [];
            $row.find('.biz-tag').each(function() {
                tags.push($(this).contents().first().text().trim());
            });
            $('#biz-attribute-values-hidden-' + rowId).val(tags.join(','));
        },

        addAttribute: function() {
            this.attributeCount++;
            var id = this.attributeCount;

            var existingAttributesOptions = '';
            var existingAttributes = Array.isArray(data.attributeTaxonomies) ? data.attributeTaxonomies : [];

            existingAttributes.forEach(function(attr) {
                existingAttributesOptions += '<option value="' + attr.attribute_name + '" data-label="' + attr.attribute_label + '">' + attr.attribute_label + '</option>';
            });

            var attributeHtml =
                '<div class="biz-attribute-row" data-id="' + id + '">' +
                    '<div class="biz-form-grid-2">' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Select an existing attribute', 'Sélectionner un attribut existant') + '</label>' +
                            '<select class="biz-select existing-attribute-select" onchange="BizProducts.onExistingAttributeSelect(this)">' +
                                '<option value="">-- ' + t('Choose an existing attribute', 'Choisir un attribut existant') + ' --</option>' +
                                existingAttributesOptions +
                                '<option value="new">+ ' + t('Create a new attribute', 'Créer un nouvel attribut') + '</option>' +
                            '</select>' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Or create a new attribute', 'Ou créer un nouvel attribut') + '</label>' +
                            '<input type="text" class="biz-input attribute-name" placeholder="' + t('Attribute name (e.g. Color, Size)', "Nom de l'attribut (ex: Couleur, Taille)") + '" style="display:none;">' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Attribute values', "Valeurs de l'attribut") + '</label>' +
                            '<div class="biz-tag-input" id="biz-attribute-values-' + id + '">' +
                                '<input type="text" class="biz-attribute-values-input" placeholder="' + t('Add a value, press Enter', 'Ajouter une valeur, appuyez sur Entrée') + '">' +
                            '</div>' +
                            '<input type="hidden" class="attribute-values" id="biz-attribute-values-hidden-' + id + '">' +
                            '<small style="color:#6b7280;">' + t('Separate values with commas or add them one by one', 'Séparer les valeurs par des virgules ou ajoutez-les une par une') + '</small>' +
                        '</div>' +
                    '</div>' +
                    '<div class="biz-form-grid-3">' +
                        '<div class="biz-form-group">' +
                            '<label style="display:flex; align-items:center; cursor:pointer;">' +
                                '<span class="biz-switch">' +
                                    '<input type="checkbox" class="attribute-visible" checked>' +
                                    '<span class="biz-slider"></span>' +
                                '</span>' +
                                t('Visible on product page', 'Visible sur la page produit') +
                            '</label>' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label style="display:flex; align-items:center; cursor:pointer;">' +
                                '<span class="biz-switch">' +
                                    '<input type="checkbox" class="attribute-variation" checked>' +
                                    '<span class="biz-slider"></span>' +
                                '</span>' +
                                t('Used for variations', 'Utilisé pour les variations') +
                            '</label>' +
                        '</div>' +
                        '<button type="button" class="biz-btn" onclick="BizProducts.removeAttribute(' + id + ')">' + t('Remove', 'Supprimer') + '</button>' +
                    '</div>' +
                '</div>';

            $('#biz-variable-attributes').append(attributeHtml);
        },

        removeAttribute: function(id) {
            $('.biz-attribute-row[data-id="' + id + '"]').remove();
        },

        addVariation: function() {
            this.variationCount++;
            var id = this.variationCount;

            var variationHtml =
                '<div class="biz-variation-row" id="variation-' + id + '">' +
                    '<div class="biz-variation-header">' +
                        '<h4 class="biz-variation-title">Variation ' + id + '</h4>' +
                        '<button type="button" class="biz-remove-variation" onclick="BizProducts.removeVariation(' + id + ')">&times;</button>' +
                    '</div>' +
                    '<div class="biz-form-grid-3">' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Attributes', 'Attributs') + '</label>' +
                            '<input type="text" class="biz-input variation-attributes" placeholder="' + t('Color: Red, Size: M', 'Couleur: Rouge, Taille: M') + '" data-id="' + id + '">' +
                            '<small style="color:#6b7280;">' + t('Format: Attribute: Value, Attribute: Value', 'Format: Attribut: Valeur, Attribut: Valeur') + '</small>' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Variation SKU', 'SKU Variation') + '</label>' +
                            '<input type="text" class="biz-input variation-sku" placeholder="VAR-' + id + '" data-id="' + id + '">' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Regular price', 'Prix régulier') + '</label>' +
                            '<input type="number" step="0.01" min="0" class="biz-input variation-regular-price" placeholder="0.00" data-id="' + id + '">' +
                        '</div>' +
                    '</div>' +
                    '<div class="biz-form-grid-3">' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Sale price', 'Prix promotionnel') + '</label>' +
                            '<input type="number" step="0.01" min="0" class="biz-input variation-sale-price" placeholder="0.00" data-id="' + id + '">' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Cost price', "Prix d'achat") + '</label>' +
                            '<input type="number" step="0.01" min="0" class="biz-input variation-cost-price" placeholder="0.00" data-id="' + id + '">' +
                        '</div>' +
                        '<div class="biz-form-group">' +
                            '<label>' + t('Stock', 'Stock') + '</label>' +
                            '<input type="number" min="0" step="1" inputmode="numeric" pattern="[0-9]*" class="biz-input variation-stock" placeholder="0" data-id="' + id + '">' +
                        '</div>' +
                    '</div>' +
                    '<div class="biz-form-group" style="grid-column: span 3; border-top: 1px solid #e5e7eb; padding-top: 15px; margin-top: 10px;">' +
                        '<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">' +
                            '<label style="font-weight: 600;">🏷️ ' + t('Variation Barcodes', 'Barcodes de la Variation') + '</label>' +
                            '<div style="display: flex; gap: 8px;">' +
                                '<button type="button" class="biz-btn biz-btn-secondary add-barcode-btn" data-product-type="variation" data-variation-row-id="' + id + '" style="padding: 6px 12px; font-size: 12px;">➕ ' + t('Add Barcode', 'Ajouter') + '</button>' +
                                '<button type="button" class="biz-btn biz-btn-secondary generate-barcode-btn" data-product-type="variation" data-variation-row-id="' + id + '" style="padding: 6px 12px; font-size: 12px;">⚡ ' + t('Generate EAN-13', 'Générer EAN-13') + '</button>' +
                            '</div>' +
                        '</div>' +
                        '<div class="biz-barcodes-grid biz-barcodes-tbody" data-product-type="variation" data-variation-row-id="' + id + '">' +
                            '<div class="biz-no-barcodes-placeholder" style="text-align: center; color: #9ca3af; padding: 20px 0; grid-column: 1 / -1;">' + t('No barcodes configured.', 'Aucun code-barres configuré.') + '</div>' +
                        '</div>' +
                    '</div>' +
                '</div>';

            $('#biz-variations-container').append(variationHtml);
        },

        generateVariations: function() {
            var attributes = [];
            $('.biz-attribute-row').each(function() {
                var name = $(this).find('.attribute-name').val();
                var valuesInput = $(this).find('.attribute-values').val();
                var values = valuesInput ? valuesInput.split(',').map(function(v){ return v.trim(); }).filter(Boolean) : [];
                if (name && values.length > 0) {
                    attributes.push({ name: name, values: values });
                }
            });

            if (attributes.length === 0) {
                alert(t('Please define attributes first', "Veuillez d'abord définir des attributs"));
                return;
            }

            var combinations = [];
            function generateCombos(current, index) {
                if (index === attributes.length) {
                    combinations.push(current.slice());
                    return;
                }
                var attribute = attributes[index];
                attribute.values.forEach(function(value){
                    current.push({ name: attribute.name, value: value });
                    generateCombos(current, index + 1);
                    current.pop();
                });
            }
            generateCombos([], 0);

            $('#biz-variations-container').empty();
            this.variationCount = 0;

            combinations.forEach(function(combo){
                BizProducts.variationCount++;
                var id = BizProducts.variationCount;
                var attrString = combo.map(function(a){ return a.name + ': ' + a.value; }).join(', ');

                var baseSku = $('#biz-variable-sku').val() || 'VAR';
                var baseReg = $('#biz-variable-base-regular').val() || '0.00';
                var baseSale = $('#biz-variable-base-sale').val() || '0.00';
                var baseCost = $('#biz-variable-base-cost').val() || '0.00';

                var variationHtml =
                    '<div class="biz-variation-row" id="variation-' + id + '">' +
                        '<div class="biz-variation-header">' +
                            '<h4 class="biz-variation-title">Variation ' + id + '</h4>' +
                            '<button type="button" class="biz-remove-variation" onclick="BizProducts.removeVariation(' + id + ')">&times;</button>' +
                        '</div>' +
                        '<div class="biz-form-grid-3">' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Attributes', 'Attributs') + '</label>' +
                                '<input type="text" class="biz-input variation-attributes" value="' + attrString.replace(/"/g, '&quot;') + '" data-id="' + id + '" readonly>' +
                            '</div>' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Variation SKU', 'SKU Variation') + '</label>' +
                                '<input type="text" class="biz-input variation-sku" placeholder="' + baseSku + '-' + id + '" data-id="' + id + '">' +
                            '</div>' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Regular price', 'Prix régulier') + '</label>' +
                                '<input type="number" step="0.01" min="0" class="biz-input variation-regular-price" placeholder="' + baseReg + '" data-id="' + id + '">' +
                            '</div>' +
                        '</div>' +
                        '<div class="biz-form-grid-3">' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Sale price', 'Prix promotionnel') + '</label>' +
                                '<input type="number" step="0.01" min="0" class="biz-input variation-sale-price" placeholder="' + baseSale + '" data-id="' + id + '">' +
                            '</div>' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Cost price', "Prix d'achat") + '</label>' +
                                '<input type="number" step="0.01" min="0" class="biz-input variation-cost-price" placeholder="' + baseCost + '" data-id="' + id + '">' +
                            '</div>' +
                            '<div class="biz-form-group">' +
                                '<label>' + t('Stock', 'Stock') + '</label>' +
                                '<input type="number" min="0" step="1" inputmode="numeric" pattern="[0-9]*" class="biz-input variation-stock" placeholder="10" data-id="' + id + '">' +
                            '</div>' +
                        '</div>' +
                        '<div class="biz-form-group" style="grid-column: span 3; border-top: 1px solid #e5e7eb; padding-top: 15px; margin-top: 10px;">' +
                            '<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">' +
                                '<label style="font-weight: 600;">🏷️ ' + t('Variation Barcodes', 'Barcodes de la Variation') + '</label>' +
                                '<div style="display: flex; gap: 8px;">' +
                                    '<button type="button" class="biz-btn biz-btn-secondary add-barcode-btn" data-product-type="variation" data-variation-row-id="' + id + '" style="padding: 6px 12px; font-size: 12px;">➕ ' + t('Add Barcode', 'Ajouter') + '</button>' +
                                    '<button type="button" class="biz-btn biz-btn-secondary generate-barcode-btn" data-product-type="variation" data-variation-row-id="' + id + '" style="padding: 6px 12px; font-size: 12px;">⚡ ' + t('Generate EAN-13', 'Générer EAN-13') + '</button>' +
                                '</div>' +
                            '</div>' +
                            '<div class="biz-barcodes-grid biz-barcodes-tbody" data-product-type="variation" data-variation-row-id="' + id + '">' +
                                '<div class="biz-no-barcodes-placeholder" style="text-align: center; color: #9ca3af; padding: 20px 0; grid-column: 1 / -1;">' + t('No barcodes configured.', 'Aucun code-barres configuré.') + '</div>' +
                            '</div>' +
                        '</div>' +
                    '</div>';

                $('#biz-variations-container').append(variationHtml);
            });

            alert(t(combinations.length + ' variations generated automatically', combinations.length + ' variations générées automatiquement'));
        },

        removeVariation: function(id) {
            $('#variation-' + id).remove();
        },

        openMediaUploader: function(inputId, previewId) {
            if (typeof wp === 'undefined' || !wp.media) {
                alert(t('Media uploader is not available. Please refresh the page.', "Le gestionnaire de médias n'est pas disponible. Veuillez rafraîchir la page."));
                return false;
            }

            var frame = wp.media({
                title: t('Select an image', 'Sélectionner une image'),
                button: { text: t('Use this image', 'Utiliser cette image') },
                multiple: false
            });

            frame.on('select', function() {
                var attachment = frame.state().get('selection').first().toJSON();
                $('#' + inputId).val(attachment.id);
                $('#' + previewId).attr('src', attachment.url).addClass('show');
            });

            frame.open();
            return false;
        },

        openGalleryUploader: function(type) {
            if (typeof wp === 'undefined' || !wp.media) {
                alert(t('Media uploader is not available. Please refresh the page.', "Le gestionnaire de médias n'est pas disponible. Veuillez rafraîchir la page."));
                return false;
            }

            var frame = wp.media({
                title: t('Select images', 'Sélectionner des images'),
                button: { text: t('Add to gallery', 'Ajouter à la galerie') },
                multiple: true
            });

            frame.on('select', function() {
                var attachments = frame.state().get('selection').toJSON();
                attachments.forEach(function(att){ BizProducts.addToGallery(type, att); });
            });

            frame.open();
            return false;
        },

        openFileUploader: function() {
            if (typeof wp === 'undefined' || !wp.media) {
                alert(t('Media uploader is not available. Please refresh the page.', "Le gestionnaire de médias n'est pas disponible. Veuillez rafraîchir la page."));
                return false;
            }

            var frame = wp.media({
                title: t('Add files', 'Ajouter des fichiers'),
                button: { text: t('Add', 'Ajouter') },
                multiple: true,
                library: { type: ['application/pdf', 'application/zip', 'audio/mpeg', 'image/jpeg', 'image/png', 'text/plain'] }
            });

            frame.on('select', function() {
                var attachments = frame.state().get('selection').toJSON();
                attachments.forEach(function(att){ BizProducts.addDigitalFile(att); });
            });

            frame.open();
            return false;
        },

        addToGallery: function(type, attachment) {
            var galleryDiv = $('#biz-' + type + '-gallery');
            var imageId = attachment.id;

            if (!Array.isArray(BizProducts[type + 'Gallery'])) BizProducts[type + 'Gallery'] = [];
            if (BizProducts[type + 'Gallery'].includes(imageId)) return;

            BizProducts[type + 'Gallery'].push(imageId);

            var imageHtml =
                '<div style="position: relative; display: inline-block;">' +
                    '<img src="' + attachment.url + '" class="biz-gallery-image">' +
                    '<button type="button" class="biz-remove-image" onclick="BizProducts.removeFromGallery(\'' + type + '\', ' + imageId + ')">×</button>' +
                '</div>';

            galleryDiv.append(imageHtml);
            $('#biz-' + type + '-gallery-ids').val(BizProducts[type + 'Gallery'].join(','));
        },

        removeFromGallery: function(type, imageId) {
            if (!Array.isArray(BizProducts[type + 'Gallery'])) BizProducts[type + 'Gallery'] = [];
            BizProducts[type + 'Gallery'] = BizProducts[type + 'Gallery'].filter(function(id){ return id !== imageId; });
            $('#biz-' + type + '-gallery-ids').val(BizProducts[type + 'Gallery'].join(','));
            $('button[onclick="BizProducts.removeFromGallery(\'' + type + '\', ' + imageId + ')"]').parent().remove();
        },

        addDigitalFile: function(attachment) {
            var fileId = attachment.id;
            if (this.digitalFiles.some(function(f){ return f.id === fileId; })) return;

            this.digitalFiles.push({
                id: fileId,
                name: attachment.filename || attachment.title,
                url: attachment.url
            });

            this.updateDigitalFilesList();
        },

        updateDigitalFilesList: function() {
            var listDiv = $('#biz-digital-files-list');
            listDiv.empty();

            this.digitalFiles.forEach(function(file, index) {
                var fileHtml =
                    '<div class="biz-file-item">' +
                        '<div class="biz-file-name">' +
                            '<span style="font-size: 20px;">📎</span>' +
                            '<span style="font-size: 14px;">' + String(file.name || '').replace(/</g,'&lt;').replace(/>/g,'&gt;') + '</span>' +
                        '</div>' +
                        '<button type="button" class="biz-remove-variation" onclick="BizProducts.removeDigitalFile(' + index + ')">&times;</button>' +
                    '</div>';
                listDiv.append(fileHtml);
            });

            $('#biz-digital-files').val(JSON.stringify(this.digitalFiles));
        },

        removeDigitalFile: function(index) {
            this.digitalFiles.splice(index, 1);
            this.updateDigitalFilesList();
        },

        populateBarcodes: function($tbody, barcodes, primaryRadioName) {
            if (!barcodes || !barcodes.length) return;
            $tbody.find('.biz-no-barcodes-placeholder').remove();
            barcodes.forEach(function(b) {
                var label = b.label || '';
                var isPrimary = parseInt(b.is_primary, 10) === 1;
                
                var cardHtml = '<div class="biz-barcode-card' + (isPrimary ? ' primary' : '') + '">' +
                    '<button type="button" class="biz-remove-barcode-card remove-barcode-row" style="position: absolute; top: 8px; right: 8px; border: none; background: transparent; cursor: pointer; color: #ef4444; font-size: 16px;">&times;</button>' +
                    '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                        '<label style="font-size: 12px; font-weight: 600; color: #475569;">Barcode Value</label>' +
                        '<input type="text" class="biz-input barcode-value-input" value="' + b.barcode + '" required style="padding: 8px; font-size: 13px;">' +
                        '<input type="hidden" class="barcode-type-select" value="EAN13">' +
                    '</div>' +
                    '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                        '<label style="font-size: 12px; font-weight: 600; color: #475569;">Label (e.g. Unit, Box)</label>' +
                        '<input type="text" class="biz-input barcode-label-input" value="' + label + '" style="padding: 8px; font-size: 13px;">' +
                    '</div>' +
                    '<div style="display: flex; align-items: center; justify-content: space-between; margin-top: 12px; border-top: 1px solid #e2e8f0; padding-top: 12px;">' +
                        '<label style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; cursor: pointer; font-weight: 500; color: #475569;">' +
                            '<input type="radio" name="' + primaryRadioName + '" class="barcode-primary-radio" ' + (isPrimary ? 'checked' : '') + '>' +
                            'Primary' +
                        '</label>' +
                        '<button type="button" class="biz-btn print-barcode-btn" style="padding: 6px 10px; font-size: 12px; display: inline-flex; align-items: center; gap: 4px; background: #fff; color: #374151; border: 1px solid #cbd5e1;">🖨️ Print</button>' +
                    '</div>' +
                '</div>';
                $tbody.append(cardHtml);
            });
        },

        serializeBarcodes: function($tbody) {
            var list = [];
            if (!$tbody || !$tbody.length) return list;
            $tbody.find('.biz-barcode-card').each(function() {
                var barcode = $(this).find('.barcode-value-input').val();
                var format = $(this).find('.barcode-type-select').val() || 'EAN13';
                var label = $(this).find('.barcode-label-input').val();
                var isPrimary = $(this).find('.barcode-primary-radio').is(':checked') ? 1 : 0;
                if (barcode) {
                    list.push({
                        barcode: barcode,
                        barcode_format: format,
                        label: label,
                        is_primary: isPrimary
                    });
                }
            });
            return list;
        },

        createSimpleProduct: function(btnEl) { this.saveProduct('simple', 'publish', btnEl); },
        createVariableProduct: function(btnEl) { this.saveProduct('variable', 'publish', btnEl); },
        createGroupedProduct: function(btnEl) { this.saveProduct('grouped', 'publish', btnEl); },
        createExternalProduct: function(btnEl) { this.saveProduct('external', 'publish', btnEl); },
        createDigitalProduct: function(btnEl) { this.saveProduct('digital', 'publish', btnEl); },

        saveProduct: function(type, status, btnEl) {
            // EDIT MODE (critical)
            // The Bizmart UI fills the creation form when editing an existing product.
            // To update (not create a duplicate), we MUST send the existing product ID.
            // Also, do NOT auto-generate SKU in edit mode.
            var editId = 0;
            try {
                editId = parseInt(($('#bizmart-edit-product-id').val() || '0'), 10) || 0;
            } catch (e) { editId = 0; }
            var isEdit = editId > 0;

            var productData = {};

            switch(type) {
                case 'simple':
                    productData = {
                        id: isEdit ? editId : 0,
                        name: $('#biz-simple-name').val(),
                        sku: $('#biz-simple-sku').val(),
                        regular_price: $('#biz-simple-regular-price').val(),
                        sale_price: $('#biz-simple-sale-price').val() || '',
                        cost_price: $('#biz-simple-cost-price').val() || '',
                        short_description: $('#biz-simple-short-description').val(),
                        description: $('#biz-simple-description').val(),
                        categories: $('#biz-simple-categories').val() || [],
                        tags: this.tags.simple,
                        image_id: $('#biz-simple-image-id').val() || 0,
                        gallery_ids: this.simpleGallery,
                        manage_stock: $('#biz-simple-manage-stock').is(':checked') ? 1 : 0,
                        stock_status: $('#biz-simple-stock-status').val(),
                        stock_quantity: $('#biz-simple-stock-quantity').val() || 0,
                        backorders: $('#biz-simple-backorders').val(),
                        sold_individually: $('#biz-simple-sold-individually').val() === 'yes' ? 1 : 0,
                        weight: $('#biz-simple-weight').val() || '',
                        length: $('#biz-simple-length').val() || '',
                        width: $('#biz-simple-width').val() || '',
                        height: $('#biz-simple-height').val() || '',
                        shipping_class: $('#biz-simple-shipping-class').val() || '',
                        virtual: $('#biz-simple-virtual').is(':checked') ? 1 : 0,
                        cross_sell_ids: ($('#biz-simple-cross-sells').val() || '').split(',').map(function(s){ return s.trim(); }).filter(Boolean),
                        upsell_ids: ($('#biz-simple-upsells').val() || '').split(',').map(function(s){ return s.trim(); }).filter(Boolean),
                        purchase_note: $('#biz-simple-purchase-note').val(),
                        menu_order: $('#biz-simple-menu-order').val() || 0,
                        status: status,
                        comment_status: $('#biz-simple-reviews').val(),
                        barcodes: this.serializeBarcodes($('.biz-barcodes-tbody[data-product-type="simple"]'))
                    };

                    if (!productData.name) {
                        alert(t('Please enter a product name', 'Veuillez saisir un nom de produit'));
                        return;
                    }
                    // Only auto-generate SKU when creating a new product.
                    if (!productData.sku && !isEdit) {
                        productData.sku = String(productData.name)
                            .toUpperCase()
                            .replace(/[^A-Z0-9]/g, '')
                            .substring(0, 12) || ('BIZ-' + Date.now());
                        $('#biz-simple-sku').val(productData.sku);
                    }
                    if (!productData.regular_price) productData.regular_price = '';
                    break;

                case 'variable':
                    function parseVariationAttributesString(str) {
                        var out = {};
                        if (!str) return out;
                        String(str).split(',').forEach(function(part){
                            var p = String(part || '').trim();
                            if (!p) return;
                            var idx = p.indexOf(':');
                            if (idx === -1) return;
                            var key = p.slice(0, idx).trim();
                            var val = p.slice(idx + 1).trim();
                            if (!key) return;
                            out[key] = val;
                        });
                        return out;
                    }

                    var attributes = [];
                    $('.biz-attribute-row').each(function() {
                        var name = $(this).find('.attribute-name').val();
                        var valuesInput = $(this).find('.attribute-values').val();
                        var values = valuesInput ? valuesInput.split(',').map(function(v){ return v.trim(); }).filter(Boolean) : [];
                        var visible = $(this).find('.attribute-visible').is(':checked');
                        var variation = $(this).find('.attribute-variation').is(':checked');

                        if (name && values.length > 0) {
                            attributes.push({
                                name: name,
                                options: values,
                                visible: visible,
                                variation: variation
                            });
                        }
                    });

                    var variations = [];
                    $('.biz-variation-row').each(function() {
                        var $row = $(this);
                        var existingVarId = 0;
                        try {
                            existingVarId = parseInt(($row.attr('data-variation-id') || '0'), 10) || 0;
                        } catch (e) { existingVarId = 0; }

                        // Attributes may come from:
                        // - create-mode rows: .variation-attributes (string like "Color: Red, Size: M")
                        // - edit-mode rows: data-combo JSON or .variation-attributes-display
                        var attrStringVal = $row.find('.variation-attributes').val() || $row.find('.variation-attributes-display').val() || '';

                        // EDIT MODE rows (rendered by admin/products.php) store attributes in data-combo JSON.
                        if (existingVarId > 0) {
                            var attrsObj = {};
                            var comboRaw = $row.attr('data-combo') || '';
                            if (comboRaw) {
                                try {
                                    var combo = JSON.parse(comboRaw);
                                    if (Array.isArray(combo)) {
                                        combo.forEach(function(p){
                                            if (p && p.name) attrsObj[String(p.name)] = (p.value != null ? String(p.value) : '');
                                        });
                                    }
                                } catch (e) {
                                    // If parsing fails, keep attrsObj empty (we still allow save to avoid blocking edits).
                                }
                            }

                            if (!Object.keys(attrsObj).length && attrStringVal) {
                                attrsObj = parseVariationAttributesString(attrStringVal);
                            }

                            variations.push({
                                id: existingVarId,
                                attributes: attrsObj,
                                sku: $row.find('.variation-sku').val(),
                                regular_price: $row.find('.variation-regular-price').val(),
                                sale_price: $row.find('.variation-sale-price').val() || '',
                                cost_price: $row.find('.variation-cost-price').val() || '',
                                stock_quantity: $row.find('.variation-stock').val() || 0,
                                barcodes: BizProducts.serializeBarcodes($row.find('.biz-barcodes-tbody[data-product-type="variation"]'))
                            });
                            return;
                        }

                        // CREATE MODE rows: keep legacy behavior (only submit variations when SKU is filled).
                        var attrsFromString = parseVariationAttributesString(attrStringVal);
                        if (!Object.keys(attrsFromString).length) return;

                        variations.push({
                            attributes: attrsFromString,
                            sku: $row.find('.variation-sku').val(),
                            regular_price: $row.find('.variation-regular-price').val(),
                            sale_price: $row.find('.variation-sale-price').val() || '',
                            cost_price: $row.find('.variation-cost-price').val() || '',
                            stock_quantity: $row.find('.variation-stock').val() || 0,
                            barcodes: BizProducts.serializeBarcodes($row.find('.biz-barcodes-tbody[data-product-type="variation"]'))
                        });
                    });

                    productData = {
                        id: isEdit ? editId : 0,
                        name: $('#biz-variable-name').val(),
                        sku: $('#biz-variable-sku').val(),
                        short_description: $('#biz-variable-short-description').val(),
                        description: $('#biz-variable-description').val(),
                        categories: $('#biz-variable-categories').val() || [],
                        tags: this.tags.variable,
                        image_id: $('#biz-variable-image-id').val() || 0,
                        attributes: attributes,
                        variations: variations,
                        base_regular_price: $('#biz-variable-base-regular').val() || '',
                        base_sale_price: $('#biz-variable-base-sale').val() || '',
                        base_cost_price: $('#biz-variable-base-cost').val() || '',
                        status: status
                    };

                    if (!productData.name || (!productData.sku && !isEdit)) {
                        alert(t('Please fill in the product name and SKU', 'Veuillez remplir le nom et le SKU du produit'));
                        return;
                    }
                    if (attributes.length === 0) {
                        alert(t('Please define at least one attribute', 'Veuillez définir au moins un attribut'));
                        return;
                    }
                    // Only enforce "at least one variation" on create.
                    // On edit, existing variations may be managed in WooCommerce; we must not block saving.
                    if (!isEdit && variations.length === 0) {
                        alert(t('Please create at least one variation', 'Veuillez créer au moins une variation'));
                        return;
                    }
                    break;

                case 'grouped':
                    productData = {
                        id: isEdit ? editId : 0,
                        name: $('#biz-grouped-name').val(),
                        sku: $('#biz-grouped-sku').val(),
                        description: $('#biz-grouped-description').val(),
                        categories: $('#biz-grouped-categories').val() || [],
                        image_id: $('#biz-grouped-image-id').val() || 0,
                        grouped_products: $('#biz-grouped-products').val() || [],
                        status: status
                    };

                    if (!productData.name || !productData.sku) {
                        alert(t('Please fill in the group name and SKU', 'Veuillez remplir le nom et le SKU du groupe'));
                        return;
                    }
                    if (productData.grouped_products.length === 0) {
                        alert(t('Please select at least one product to include in the group', 'Veuillez sélectionner au moins un produit à inclure dans le groupe'));
                        return;
                    }
                    break;

                case 'external':
                    productData = {
                        id: isEdit ? editId : 0,
                        name: $('#biz-external-name').val(),
                        sku: $('#biz-external-sku').val(),
                        product_url: $('#biz-external-url').val(),
                        button_text: $('#biz-external-button').val(),
                        regular_price: $('#biz-external-price').val() || '',
                        sale_price: $('#biz-external-sale-price').val() || '',
                        cost_price: $('#biz-external-cost-price').val() || '',
                        categories: $('#biz-external-categories').val() || [],
                        description: $('#biz-external-description').val(),
                        image_id: $('#biz-external-image-id').val() || 0,
                        status: status
                    };

                    if (!productData.name || !productData.sku || !productData.product_url || !productData.button_text) {
                        alert(t('Please fill in all required fields', 'Veuillez remplir tous les champs obligatoires'));
                        return;
                    }
                    break;

                case 'digital':
                    productData = {
                        id: isEdit ? editId : 0,
                        name: $('#biz-digital-name').val(),
                        sku: $('#biz-digital-sku').val(),
                        regular_price: $('#biz-digital-price').val(),
                        sale_price: $('#biz-digital-sale-price').val() || '',
                        cost_price: $('#biz-digital-cost-price').val() || '',
                        description: $('#biz-digital-description').val(),
                        categories: $('#biz-digital-categories').val() || [],
                        image_id: $('#biz-digital-image-id').val() || 0,
                        download_files: this.digitalFiles,
                        download_limit: $('#biz-digital-download-limit').val() || '',
                        download_expiry: $('#biz-digital-download-expiry').val() || '',
                        virtual: 1,
                        downloadable: 1,
                        status: status
                    };

                    if (!productData.name) {
                        alert(t('Please enter a product name', 'Veuillez saisir un nom de produit'));
                        return;
                    }
                    // Only auto-generate SKU when creating a new product.
                    if (!productData.sku && !isEdit) {
                        productData.sku = String(productData.name)
                            .toUpperCase()
                            .replace(/[^A-Z0-9]/g, '')
                            .substring(0, 12) || ('BIZ-' + Date.now());
                        $('#biz-digital-sku').val(productData.sku);
                    }
                    if (!productData.regular_price) productData.regular_price = '';

                    if (productData.download_files.length === 0) {
                        alert(t('Please add at least one downloadable file', 'Veuillez ajouter au moins un fichier téléchargeable'));
                        return;
                    }
                    break;
            }

            // Ensure update payload includes the existing product ID.
            if (isEdit) {
                productData.id = editId;
            }

            var $btn = btnEl ? $(btnEl) : $('button[onclick^="BizProducts.create' + type.charAt(0).toUpperCase() + type.slice(1) + 'Product"]');
            var originalText = $btn.html();
            if ($btn.length) $btn.prop('disabled', true).html('<span class="biz-loading"></span> ' + (isEdit ? t('Updating...', 'Mise à jour...') : t('Creating...', 'Création...')));

            var ajaxUrl = (window.BizProducts && BizProducts.ajaxUrl) ? BizProducts.ajaxUrl :
                           ((window.BizmartProductsData && BizmartProductsData.ajaxUrl) ? BizmartProductsData.ajaxUrl :
                           ((window.BizmartAnalytics && BizmartAnalytics.ajax_url) ? BizmartAnalytics.ajax_url : (window.ajaxurl || '')));

            var requestNonce = (window.BizProducts && BizProducts.nonce) ? BizProducts.nonce :
                               ((window.BizmartProductsData && BizmartProductsData.nonce) ? BizmartProductsData.nonce :
                               ((window.BizmartAnalytics && BizmartAnalytics.nonce) ? BizmartAnalytics.nonce : ''));

            $.post(ajaxUrl, {
                action: 'bizmart_create_' + type + '_product',
                nonce: requestNonce,
                data: JSON.stringify(productData)
            }, function(response) {
                if ($btn.length) $btn.prop('disabled', false).html(originalText);

                if (response.success) {
                    var alertHtml =
                        '<div class="biz-alert biz-alert-success">' +
                            '<strong>✅ ' + (isEdit ? t('Product updated successfully!', 'Produit mis à jour avec succès!') : t('Product created successfully!', 'Produit créé avec succès!')) + '</strong><br>' +
                            String(response.data.name || '') + ' (' + String(response.data.sku || '') + ')<br>' +
                            '<small><a href="' + response.data.edit_link + '" target="_blank">' + t('Edit product', 'Modifier le produit') + '</a> | ' +
                            '<a href="' + response.data.view_link + '" target="_blank">' + t('View product', 'Voir le produit') + '</a></small>' +
                        '</div>';

                    $('.biz-products-main').prepend(alertHtml);
                    // Do not reset the form on update; user is editing an existing product.
                    if (!isEdit) BizProducts.resetForm(type);

                    setTimeout(function(){ window.location.reload(); }, 2000);

                    setTimeout(function(){
                        $('.biz-alert').fadeOut(300, function(){ $(this).remove(); });
                    }, 5000);
                } else {
                    var msg = response.data;
                    if (msg && typeof msg === 'object' && msg.message) msg = msg.message;
                    alert(t('Error: ', 'Erreur: ') + (msg || t('An error occurred', 'Une erreur est survenue')));
                }
            }).fail(function(xhr, statusText, error) {
                if ($btn.length) $btn.prop('disabled', false).html(originalText);
                alert(t('Server connection error: ', 'Erreur de connexion au serveur: ') + error);
            });
        },

        resetForm: function(type) {
            var form = $('#biz-form-' + type)[0];
            if (form) form.reset();

            switch(type) {
                case 'simple':
                    $('#biz-simple-stock-quantity-group').hide();
                    $('#biz-simple-image-preview').removeClass('show').attr('src', '');
                    $('#biz-simple-image-id').val('');
                    this.simpleGallery = [];
                    $('#biz-simple-gallery').empty();
                    this.tags.simple = [];
                    $('#biz-simple-tags').val('');
                    $('#biz-simple-tags-container .biz-tag').remove();
                    $('#biz-simple-shipping-section').removeClass('show');
                    break;

                case 'variable':
                    $('#biz-variations-container').empty();
                    this.variationCount = 0;
                    this.attributeCount = 1;
                    $('#biz-variable-attributes').empty();

                    // Keep same reset behavior as legacy page
                    var defaultAttr =
                        '<div class="biz-attribute-row" data-id="1">' +
                            '<div class="biz-form-grid-2">' +
                                '<div class="biz-form-group">' +
                                    '<label>' + t('Attribute name', "Nom de l'attribut") + '</label>' +
                                    '<input type="text" class="biz-input attribute-name" placeholder="' + t('e.g. Color, Size', 'ex: Couleur, Taille') + '">' +
                                '</div>' +
                                '<div class="biz-form-group">' +
                                    '<label>' + t('Values', 'Valeurs') + '</label>' +
                                    '<input type="text" class="biz-input attribute-values" placeholder="' + t('e.g. Red, Blue, Green (comma-separated)', 'ex: Rouge, Bleu, Vert (séparées par des virgules)') + '">' +
                                '</div>' +
                            '</div>' +
                            '<div class="biz-form-grid-3">' +
                                '<div class="biz-form-group">' +
                                    '<label style="display:flex; align-items:center; cursor:pointer;">' +
                                        '<span class="biz-switch">' +
                                            '<input type="checkbox" class="attribute-visible" checked>' +
                                            '<span class="biz-slider"></span>' +
                                        '</span>' +
                                        t('Visible on product page', 'Visible sur la page produit') +
                                    '</label>' +
                                '</div>' +
                                '<div class="biz-form-group">' +
                                    '<label style="display:flex; align-items:center; cursor:pointer;">' +
                                        '<span class="biz-switch">' +
                                            '<input type="checkbox" class="attribute-variation" checked>' +
                                            '<span class="biz-slider"></span>' +
                                        '</span>' +
                                        t('Used for variations', 'Utilisé pour les variations') +
                                    '</label>' +
                                '</div>' +
                                '<button type="button" class="biz-btn" onclick="BizProducts.addAttribute()">+ ' + t('Add attribute', 'Ajouter attribut') + '</button>' +
                            '</div>' +
                        '</div>';

                    $('#biz-variable-attributes').html(defaultAttr);
                    $('#biz-variable-image-preview').removeClass('show').attr('src', '');
                    $('#biz-variable-image-id').val('');
                    this.tags.variable = [];
                    $('#biz-variable-tags').val('');
                    $('#biz-variable-tags-container .biz-tag').remove();
                    break;

                case 'digital':
                    this.digitalFiles = [];
                    $('#biz-digital-files-list').empty();
                    $('#biz-digital-files').val('');
                    $('#biz-digital-image-preview').removeClass('show').attr('src', '');
                    $('#biz-digital-image-id').val('');
                    break;

                case 'grouped':
                    $('#biz-grouped-image-preview').removeClass('show').attr('src', '');
                    $('#biz-grouped-image-id').val('');
                    break;

                case 'external':
                    $('#biz-external-image-preview').removeClass('show').attr('src', '');
                    $('#biz-external-image-id').val('');
                    break;
            }
        }
    });

    // Init (on products admin page)
    $(document).ready(function(){
        BizProducts.bindEvents();

        // Grouped products picker: scalable AJAX search (Select2)
        (function initGroupedProductsSelect2(){
            var $sel = $('#biz-grouped-products');
            if (!$sel.length) return;
            if (!$.fn.select2) return;

            var ajaxUrl = (window.BizmartAnalytics && BizmartAnalytics.ajax_url) ? BizmartAnalytics.ajax_url : (window.ajaxurl || '');
            var nonce = (window.BizmartAnalytics && BizmartAnalytics.nonce) ? BizmartAnalytics.nonce : '';
            if (!ajaxUrl) return;

            // Avoid double init
            if ($sel.data('select2')) return;

            $sel.select2({
                width: '100%',
                placeholder: BizProducts.t('Search products…', 'Rechercher des produits…'),
                closeOnSelect: false,
                ajax: {
                    url: ajaxUrl,
                    dataType: 'json',
                    delay: 250,
                    data: function(params){
                        return {
                            action: 'bizmart_search_simple_products_select2',
                            nonce: nonce,
                            q: params.term || '',
                            page: params.page || 1
                        };
                    },
                    processResults: function(resp, params){
                        params.page = params.page || 1;
                        var payload = (resp && resp.success) ? resp.data : (resp && resp.data ? resp.data : resp);
                        var results = (payload && payload.results) ? payload.results : [];
                        var more = !!(payload && payload.pagination && payload.pagination.more);
                        return {
                            results: results,
                            pagination: { more: more }
                        };
                    },
                    cache: true
                },
                minimumInputLength: 1
            });
        })();

        // Tag inputs
        ['simple', 'variable', 'external', 'digital', 'grouped'].forEach(function(type){
            $('#biz-' + type + '-tags-input').on('keypress', function(e){
                if (e.key === 'Enter') {
                    e.preventDefault();
                    BizProducts.addTag(type, $(this).val());
                    $(this).val('');
                }
            });
        });

        // Toggle stock qty
        $('#biz-simple-manage-stock').on('change', function(){
            if ($(this).is(':checked')) $('#biz-simple-stock-quantity-group').show();
            else $('#biz-simple-stock-quantity-group').hide();
        });

        // Auto SKU simple
        $('#biz-simple-name').on('blur', function(){
            if ($('#biz-simple-sku').val() !== '') return;
            var name = $(this).val();
            if (!name) return;
            var sku = name.toUpperCase().replace(/[^A-Z0-9]/g, '').substring(0, 10);
            $('#biz-simple-sku').val(sku);
        });

        // Hide shipping by default
        $('#biz-simple-shipping-section').removeClass('show');

        // Open advanced by default
        setTimeout(function(){
            $('#biz-simple-advanced').addClass('show');
            $('#biz-simple-advanced').prev().find('span').text('▲');
        }, 100);

        // Barcode Actions Bindings
        $(document).on('click', '.add-barcode-btn', function(e) {
            e.preventDefault();
            var type = $(this).data('product-type'); 
            var varId = $(this).data('variation-row-id') || '';
            
            var $tbody = type === 'simple' 
                ? $('.biz-barcodes-tbody[data-product-type="simple"]')
                : $('.biz-barcodes-tbody[data-product-type="variation"][data-variation-row-id="' + varId + '"]');
            
            $tbody.find('.biz-no-barcodes-placeholder').remove();
            
            var primaryRadioName = type === 'simple' ? 'barcode_primary_simple' : 'barcode_primary_var_' + varId;
            
            var cardHtml = '<div class="biz-barcode-card">' +
                '<button type="button" class="biz-remove-barcode-card remove-barcode-row" style="position: absolute; top: 8px; right: 8px; border: none; background: transparent; cursor: pointer; color: #ef4444; font-size: 16px;">&times;</button>' +
                '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                    '<label style="font-size: 12px; font-weight: 600; color: #475569;">Barcode Value</label>' +
                    '<input type="text" class="biz-input barcode-value-input" value="" required style="padding: 8px; font-size: 13px;">' +
                    '<input type="hidden" class="barcode-type-select" value="EAN13">' +
                '</div>' +
                '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                    '<label style="font-size: 12px; font-weight: 600; color: #475569;">Label (e.g. Unit, Box)</label>' +
                    '<input type="text" class="biz-input barcode-label-input" value="" style="padding: 8px; font-size: 13px;">' +
                '</div>' +
                '<div style="display: flex; align-items: center; justify-content: space-between; margin-top: 12px; border-top: 1px solid #e2e8f0; padding-top: 12px;">' +
                    '<label style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; cursor: pointer; font-weight: 500; color: #475569;">' +
                        '<input type="radio" name="' + primaryRadioName + '" class="barcode-primary-radio">' +
                        'Primary' +
                    '</label>' +
                    '<button type="button" class="biz-btn print-barcode-btn" style="padding: 6px 10px; font-size: 12px; display: inline-flex; align-items: center; gap: 4px; background: #fff; color: #374151; border: 1px solid #cbd5e1;">🖨️ Print</button>' +
                '</div>' +
            '</div>';
            
            $tbody.append(cardHtml);
            
            var $radios = $tbody.find('.barcode-primary-radio');
            if ($radios.length === 1 || !$radios.filter(':checked').length) {
                $radios.first().prop('checked', true).trigger('change');
            }
        });

        $(document).on('click', '.remove-barcode-row', function(e) {
            e.preventDefault();
            var $card = $(this).closest('.biz-barcode-card');
            var $tbody = $card.parent();
            var wasChecked = $card.find('.barcode-primary-radio').is(':checked');
            
            $card.remove();
            
            if (wasChecked) {
                var $newPrimary = $tbody.find('.barcode-primary-radio').first();
                if ($newPrimary.length) {
                    $newPrimary.prop('checked', true).trigger('change');
                }
            }
            
            if ($tbody.find('.biz-barcode-card').length === 0) {
                var placeholderHtml = '<div class="biz-no-barcodes-placeholder" style="text-align: center; color: #9ca3af; padding: 20px 0; grid-column: 1 / -1;">No barcodes added yet.</div>';
                $tbody.append(placeholderHtml);
            }
        });

        $(document).on('click', '.generate-barcode-btn', function(e) {
            e.preventDefault();
            var type = $(this).data('product-type');
            var varId = $(this).data('variation-row-id') || '';
            var $btn = $(this);
            
            var $tbody = type === 'simple' 
                ? $('.biz-barcodes-tbody[data-product-type="simple"]')
                : $('.biz-barcodes-tbody[data-product-type="variation"][data-variation-row-id="' + varId + '"]');
            
            $btn.prop('disabled', true).text('Loading...');
            
            var ajaxUrl = (window.BizProducts && BizProducts.ajaxUrl) ? BizProducts.ajaxUrl :
                           ((window.BizmartProductsData && BizmartProductsData.ajaxUrl) ? BizmartProductsData.ajaxUrl :
                           ((window.BizmartAnalytics && BizmartAnalytics.ajax_url) ? BizmartAnalytics.ajax_url : (window.ajaxurl || '')));

            var nonce = (window.BizProducts && BizProducts.nonce) ? BizProducts.nonce :
                        ((window.BizmartProductsData && BizmartProductsData.nonce) ? BizmartProductsData.nonce :
                        ((window.BizmartAnalytics && BizmartAnalytics.nonce) ? BizmartAnalytics.nonce : ''));
            
            $.post(ajaxUrl, {
                action: 'bizmart_generate_barcode',
                nonce: nonce
            }, function(response) {
                $btn.prop('disabled', false).html('⚡ Generate EAN-13');
                if (response.success && response.data && response.data.barcode) {
                    $tbody.find('.biz-no-barcodes-placeholder').remove();
                    var primaryRadioName = type === 'simple' ? 'barcode_primary_simple' : 'barcode_primary_var_' + varId;
                    
                    var cardHtml = '<div class="biz-barcode-card primary">' +
                        '<button type="button" class="biz-remove-barcode-card remove-barcode-row" style="position: absolute; top: 8px; right: 8px; border: none; background: transparent; cursor: pointer; color: #ef4444; font-size: 16px;">&times;</button>' +
                        '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                            '<label style="font-size: 12px; font-weight: 600; color: #475569;">Barcode Value</label>' +
                            '<input type="text" class="biz-input barcode-value-input" value="' + response.data.barcode + '" required style="padding: 8px; font-size: 13px;">' +
                            '<input type="hidden" class="barcode-type-select" value="EAN13">' +
                        '</div>' +
                        '<div class="biz-form-group" style="margin-bottom: 12px;">' +
                            '<label style="font-size: 12px; font-weight: 600; color: #475569;">Label (e.g. Unit, Box)</label>' +
                            '<input type="text" class="biz-input barcode-label-input" value="Auto Generated" style="padding: 8px; font-size: 13px;">' +
                        '</div>' +
                        '<div style="display: flex; align-items: center; justify-content: space-between; margin-top: 12px; border-top: 1px solid #e2e8f0; padding-top: 12px;">' +
                            '<label style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; cursor: pointer; font-weight: 500; color: #475569;">' +
                                '<input type="radio" name="' + primaryRadioName + '" class="barcode-primary-radio">' +
                                'Primary' +
                            '</label>' +
                            '<button type="button" class="biz-btn print-barcode-btn" style="padding: 6px 10px; font-size: 12px; display: inline-flex; align-items: center; gap: 4px; background: #fff; color: #374151; border: 1px solid #cbd5e1;">🖨️ Print</button>' +
                        '</div>' +
                    '</div>';
                    
                    $tbody.append(cardHtml);
                    var $radios = $tbody.find('.barcode-primary-radio');
                    if ($radios.length === 1 || !$radios.filter(':checked').length) {
                        $radios.first().prop('checked', true).trigger('change');
                    }
                } else {
                    alert('Error generating barcode: ' + (response.data || 'Unknown error'));
                }
            }).fail(function() {
                $btn.prop('disabled', false).html('⚡ Generate EAN-13');
                alert('Connection error while generating barcode.');
            });
        });

        $(document).on('click', '.print-barcode-btn', function(e) {
            e.preventDefault();
            var barcodeVal = $(this).closest('.biz-barcode-card').find('.barcode-value-input').val();
            if (!barcodeVal) {
                alert('Please enter a barcode value first before printing.');
                return;
            }
            var printUrl = 'admin.php?page=bizmart-barcode-printer&barcode=' + encodeURIComponent(barcodeVal);
            window.open(printUrl, '_blank');
        });

        // Toggle card background color on primary barcode change
        $(document).on('change', '.barcode-primary-radio', function() {
            var radioName = $(this).attr('name');
            $('input[name="' + radioName + '"]').each(function() {
                var $card = $(this).closest('.biz-barcode-card');
                if ($(this).is(':checked')) {
                    $card.addClass('primary');
                } else {
                    $card.removeClass('primary');
                }
            });
        });
    });


    /* ─── Stock Alerts Quick Update ─── */
function BizmartQuickUpdateStock(btn, productId) {
    const $btn = jQuery(btn);
    const $container = $btn.closest('tr, .biz-panic-card');
    const $input = $container.find('.biz-quick-qty-input');
    const newQty = $input.val();
    
    const originalContent = $btn.html();
    $btn.prop('disabled', true).html('<span class="biz-loading" style="width:12px; height:12px; border-width:2px;"></span>');

    jQuery.post(BizmartProductsData.ajaxUrl, {
        action: 'bizmart_quick_update_stock',
        nonce: BizmartProductsData.nonce,
        id: productId,
        qty: newQty
    }, function(response) {
        $btn.prop('disabled', false).html(originalContent);
        if (response.success) {
            $container.find('.biz-current-qty').text(response.data.qty);
            $btn.css('background', '#22c55e');
            setTimeout(() => {
                $btn.css('background', '#3b82f6');
                if (response.data.qty > 5) {
                    $container.fadeOut(500, function() { $(this).remove(); });
                }
            }, 1000);
        } else {
            alert('Error: ' + (response.data || 'Unknown error'));
        }
    });
}
window.BizmartQuickUpdateStock = BizmartQuickUpdateStock;

})(jQuery);
