/**
 * Product Gift Checkbox - Konva Template Renderer
 * Handles dynamic template rendering with user input
 */

jQuery(document).ready(function($) {
    'use strict';

    // Global variables
    var konvaStage = null;
    var konvaLayer = null;
    var currentTemplateData = null;
    var backgroundImage = null;
    var currentTemplateId = null;
    var currentVoucherAmount = 0;
    var previewCouponCode = null; // Store preview coupon code

    /**
     * Decode HTML entities
     */
    function decodeHtmlEntities(text) {
        var textArea = document.createElement('textarea');
        textArea.innerHTML = text;
        return textArea.value;
    }

    /**
     * Format price according to WooCommerce currency settings
     */
    function formatPrice(price) {
        if (!currentTemplateData) return price.toString();

        var symbol = currentTemplateData.currency_symbol || '£';
        // Decode HTML entities like &pound; to £
        symbol = decodeHtmlEntities(symbol);

        var position = currentTemplateData.currency_position || 'right';

        // Remove decimals if price is whole number
        var priceValue = parseFloat(price);
        var formattedPrice = (priceValue % 1 === 0) ? priceValue.toFixed(0) : priceValue.toFixed(2);

        switch(position) {
            case 'left':
                return symbol + formattedPrice;
            case 'right':
                return formattedPrice + symbol;
            case 'left_space':
                return symbol + ' ' + formattedPrice;
            case 'right_space':
                return formattedPrice + ' ' + symbol;
            default:
                return formattedPrice + symbol;
        }
    }

    /**
     * Get voucher amount based on template and product price
     */
    function getVoucherAmount() {
        // If template has fixed price, use it
        if (currentTemplateData && currentTemplateData.price_fe && parseFloat(currentTemplateData.price_fe) > 0) {
            return parseFloat(currentTemplateData.price_fe);
        }

        // Otherwise, get current product price (including variations)
        var productPrice = getCurrentProductPrice();
        return productPrice;
    }

    /**
     * Get current product price (handles variations)
     */
    function getCurrentProductPrice() {
        // First try to get from variation (WooCommerce stores it in hidden input)
        var $variationForm = $('form.variations_form');
        if ($variationForm.length > 0) {
            var variationData = $variationForm.data('product_variations');
            var $variationInputs = $variationForm.find('.variations select');

            // Get selected variation
            var selectedVariation = null;
            if (variationData && variationData.length > 0) {
                var allSelected = true;
                var selectedAttributes = {};

                $variationInputs.each(function() {
                    var $select = $(this);
                    var attrName = $select.attr('name');
                    var attrValue = $select.val();

                    if (!attrValue) {
                        allSelected = false;
                        return false;
                    }
                    selectedAttributes[attrName] = attrValue;
                });

                if (allSelected) {
                    // Find matching variation
                    for (var i = 0; i < variationData.length; i++) {
                        var variation = variationData[i];
                        var match = true;

                        for (var attr in selectedAttributes) {
                            if (variation.attributes[attr] !== selectedAttributes[attr]) {
                                match = false;
                                break;
                            }
                        }

                        if (match) {
                            selectedVariation = variation;
                            break;
                        }
                    }
                }
            }

            // If we found a variation, use its price
            if (selectedVariation) {
                console.log('Using variation price:', selectedVariation.display_price);
                return parseFloat(selectedVariation.display_price) || 0;
            }
        }

        // Fallback: Get from price display in DOM
        var $priceContainer = $('.summary .price');
        var $delPrice = $priceContainer.find('del .woocommerce-Price-amount');
        var $insPrice = $priceContainer.find('ins .woocommerce-Price-amount');

        // Check if on sale
        if ($delPrice.length > 0 && $insPrice.length > 0) {
            var saleText = $insPrice.first().text();
            var price = parseFloat(saleText.replace(/[^0-9.,]/g, '').replace(',', '.')) || 0;
            console.log('Using sale price from DOM:', price);
            return price;
        } else {
            // No sale, get regular price
            var priceText = $priceContainer.find('.woocommerce-Price-amount').first().text();
            if (!priceText) {
                priceText = $('.summary .amount').first().text();
            }
            var price = parseFloat(priceText.replace(/[^0-9.,]/g, '').replace(',', '.')) || 0;
            console.log('Using regular price from DOM:', price);
            return price;
        }
    }

    /**
     * Update voucher amount display
     */
    function updateVoucherAmount() {
        var oldAmount = currentVoucherAmount;
        currentVoucherAmount = getVoucherAmount();

        console.log('Voucher amount updated:', oldAmount, '->', currentVoucherAmount);

        // Update canvas if it exists
        if (konvaLayer) {
            updateTemplateText();
        }

        // Trigger update in parent gift checkbox script
        if (typeof window.wpgvUpdateGiftPrice === 'function') {
            window.wpgvUpdateGiftPrice();
        }
    }

    /**
     * Load and render template when selected
     */
    window.wpgvLoadTemplate = function(templateId) {
        if (!templateId) return;

        // store current template id and notify start
        currentTemplateId = templateId;
        try { $(document).trigger('wpgv_template_load_start', [currentTemplateId]); } catch (e) { }

        // First, generate preview coupon code
        $.ajax({
            url: wpgv_product_gift_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'wpgv_generate_preview_coupon',
                nonce: wpgv_product_gift_ajax.nonce
            },
            success: function(couponResponse) {
                if (couponResponse.success && couponResponse.data) {
                    previewCouponCode = couponResponse.data.coupon_code;
                    console.log('Preview coupon code generated:', previewCouponCode);
                } else {
                    // Fallback to placeholder if generation fails
                    previewCouponCode = 'XXXXXXXXXXXX';
                    console.warn('Failed to generate preview coupon, using placeholder');
                }

                // Now load template data
                loadTemplateData(templateId);
            },
            error: function() {
                // Fallback to placeholder on error
                previewCouponCode = 'XXXXXXXXXXXX';
                console.warn('Error generating preview coupon, using placeholder');
                loadTemplateData(templateId);
            }
        });
    };

    /**
     * Load template data after coupon code is ready
     */
    function loadTemplateData(templateId) {
        $.ajax({
            url: wpgv_product_gift_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'wpgv_get_template_data',
                nonce: wpgv_product_gift_ajax.nonce,
                template_id: templateId
            },
            success: function(response) {
                console.log('Template AJAX response:', response);
                if (response.success && response.data) {
                    currentTemplateData = response.data;
                    console.log('Template data loaded:', currentTemplateData);
                    console.log('JSON data:', currentTemplateData.json);
                    console.log('Company Logo:', currentTemplateData.company_logo);
                    console.log('Company Name:', currentTemplateData.company_name);
                    console.log('Currency:', currentTemplateData.currency);
                    console.log('Currency Symbol:', currentTemplateData.currency_symbol);
                    console.log('Currency Position:', currentTemplateData.currency_position);
                    initKonvaStage();
                } else {
                    console.error('Template data load failed:', response);
                    try { $(document).trigger('wpgv_template_load_error', [currentTemplateId, response]); } catch (e) { }
                }
            },
            error: function(xhr, status, error) {
                console.error('Failed to load template data:', error);
                console.error('XHR:', xhr);
                try { $(document).trigger('wpgv_template_load_error', [currentTemplateId, {xhr: xhr, status: status, error: error}]); } catch (e) { }
            }
        });
    }

    /**
     * Initialize Konva stage
     */
    function initKonvaStage() {
        if (!currentTemplateData) return;

        // Clear existing stage
        if (konvaStage) {
            konvaStage.destroy();
        }

        // Clear container
        var $container = $('#wpgv_template_canvas_container');
        $container.empty();

        // Get original canvas dimensions from JSON template
        var originalWidth = 800; // Default width
        var originalHeight = 566; // Default height

        // Try to parse JSON to get actual dimensions
        if (currentTemplateData.json) {
            try {
                var jsonData = typeof currentTemplateData.json === 'string'
                    ? JSON.parse(currentTemplateData.json)
                    : currentTemplateData.json;

                if (jsonData && jsonData.attrs) {
                    if (jsonData.attrs.width) {
                        originalWidth = jsonData.attrs.width;
                    }
                    if (jsonData.attrs.height) {
                        originalHeight = jsonData.attrs.height;
                    }
                }
            } catch (e) {
                console.error('Error parsing JSON for dimensions:', e);
                // Fall back to orientation-based sizing
                originalWidth = currentTemplateData.is_landscape ? 800 : 600;
                originalHeight = currentTemplateData.is_landscape ? 566 : 848;
            }
        } else {
            // No JSON, use orientation-based sizing
            originalWidth = currentTemplateData.is_landscape ? 800 : 600;
            originalHeight = currentTemplateData.is_landscape ? 566 : 848;
        }

        // Make container responsive using aspect-ratio box (no fixed px width/height)
        var aspectPercent = (originalHeight / originalWidth) * 100;
        $container.css({
            'position': 'relative',
            'width': '100%',
            'padding-top': aspectPercent + '%',
            'overflow': 'hidden'
        });

        // Create stage with original (intrinsic) dimensions, we'll scale to container
        konvaStage = new Konva.Stage({
            container: 'wpgv_template_canvas_container',
            width: originalWidth,
            height: originalHeight
        });

        // Ensure Konva content element covers the aspect-box absolutely
        var $content = $container.find('.konvajs-content');
        if ($content.length) {
            $content.css({
                'position': 'absolute',
                'top': 0,
                'left': 0,
                'width': '100%',
                'height': '100%'
            });
        }

        // Apply scale to fit container width and keep aspect ratio
        function applyKonvaScale() {
            var cw = $container.width();
            if (!cw || !originalWidth) return;
            var scale = cw / originalWidth;
            konvaStage.scale({ x: scale, y: scale });
            // Force redraw
            if (konvaLayer) konvaLayer.draw();

            // Ensure the Konva container and canvases use CSS 100% sizing so they fill the aspect box
            try {
                var stageContainer = konvaStage.container();
                if (stageContainer) {
                    try {
                        if (stageContainer.style) {
                            stageContainer.style.width = '100%';
                            stageContainer.style.height = '100%';
                            stageContainer.style.boxSizing = 'border-box';
                        }
                    } catch (e) {}

                    var canvases = stageContainer.getElementsByTagName('canvas');
                    for (var i = 0; i < canvases.length; i++) {
                        try {
                            canvases[i].style.width = '100%';
                            canvases[i].style.height = '100%';
                            canvases[i].style.display = 'block';
                            canvases[i].style.boxSizing = 'border-box';
                        } catch (e) {}
                    }
                }
            } catch (e) {
                console.warn('wpgv: failed to adjust canvas styles', e);
            }
        }

        // Apply scale once DOM insertion by Konva is guaranteed.
        // Use requestAnimationFrame + forced reflow + a short timeout fallback
        // so the stage/canvas will size correctly on the first click (no DevTools required).
        requestAnimationFrame(function() {
            try {
                // Force layout/read to ensure browser registers the new DOM
                var _force = $container[0].offsetWidth;
            } catch (e) {
                /* noop */
            }
            applyKonvaScale();
            // Safety fallback: apply again after a short delay in case of async insertion
            setTimeout(function() {
                applyKonvaScale();
                if (konvaLayer) konvaLayer.draw();
            }, 60);
        });

        // Recompute on window resize (debounced)
        var _resizeTimer = null;
        $(window).off('resize.wpgvKonva').on('resize.wpgvKonva', function() {
            clearTimeout(_resizeTimer);
            _resizeTimer = setTimeout(function() {
                // Force reflow before applying scale
                try { var _ = $container[0].offsetWidth; } catch (e) {}
                applyKonvaScale();
            }, 120);
        });

        konvaLayer = new Konva.Layer();
        konvaStage.add(konvaLayer);

        // Load background image
        loadBackgroundImage();

        // Show preview container
        $('#wpgv-template-preview-container').slideDown();
    }

    /**
     * Load background image
     */
    function loadBackgroundImage() {
        if (!currentTemplateData || !currentTemplateData.url) {
            console.error('No template URL');
            return;
        }

        var imageObj = new Image();
        imageObj.crossOrigin = 'Anonymous';

        imageObj.onload = function() {
            backgroundImage = new Konva.Image({
                x: 0,
                y: 0,
                image: imageObj,
                width: konvaStage.width(),
                height: konvaStage.height()
            });

            konvaLayer.add(backgroundImage);

            // Calculate initial voucher amount
            currentVoucherAmount = getVoucherAmount();

            // Load and apply JSON template if available
            if (currentTemplateData.json) {
                loadJSONTemplate();
            } else {
                // Fallback: render simple text overlay
                renderSimpleOverlay();
            }

            konvaLayer.draw();
            // Notify that template finished rendering
            try { $(document).trigger('wpgv_template_loaded', [currentTemplateId]); } catch (e) { }
        };

        imageObj.onerror = function() {
            console.error('Failed to load template image:', currentTemplateData.url);
            renderSimpleOverlay();
            try { $(document).trigger('wpgv_template_load_error', [currentTemplateId, {error:'background_image_failed'}]); } catch (e) { }
        };

        imageObj.src = currentTemplateData.url;
    }

    /**
     * Load JSON template and render elements
     */
    function loadJSONTemplate() {
        console.log('loadJSONTemplate called');
        console.log('currentTemplateData.json:', currentTemplateData.json);

        if (!currentTemplateData.json) {
            console.warn('No JSON data, using simple overlay');
            renderSimpleOverlay();
            return;
        }

        try {
            var jsonData = typeof currentTemplateData.json === 'string'
                ? JSON.parse(currentTemplateData.json)
                : currentTemplateData.json;

            console.log('Parsed JSON data:', jsonData);

            if (!jsonData || !jsonData.children) {
                console.warn('Invalid JSON structure, using simple overlay');
                renderSimpleOverlay();
                return;
            }

            // Process each layer
            jsonData.children.forEach(function(layerData) {
                if (layerData.children) {
                    layerData.children.forEach(function(child) {
                        renderKonvaElement(child);
                    });
                }
            });

            konvaLayer.draw();

            // Quick cleanup: detect and remove any accidental white Rect or empty Image
            (function cleanupLayer() {
                try {
                    var nodes = [];

                    // Konva Collection may not expose toArray() in this version — use each()
                    try {
                        if (konvaLayer.getChildren && typeof konvaLayer.getChildren === 'function') {
                            konvaLayer.getChildren().each(function(n) { nodes.push(n); });
                        } else {
                            nodes = konvaLayer.getChildren() || [];
                        }
                    } catch (innerErr) {
                        // Fallback: attempt to treat getChildren() as array-like
                        try { nodes = Array.prototype.slice.call(konvaLayer.getChildren() || []); } catch (e2) { nodes = konvaLayer.getChildren() || []; }
                    }

                    nodes.forEach(function(node) {
                        try {
                            var cls = (typeof node.getClassName === 'function') ? node.getClassName() : (node.className || '');

                            // Remove white rectangles (possible placeholder exported in some templates)
                            if (cls === 'Rect') {
                                var fill = (typeof node.fill === 'function') ? node.fill() : node.fill;
                                if (fill) {
                                    var f = ('' + fill).toLowerCase().replace(/\s+/g, '');
                                    if (f === '#fff' || f === '#ffffff' || f === 'white' || f.indexOf('rgba(255,255,255') === 0) {
                                        console.log('wpgv: removing white Rect placeholder', node);
                                        node.destroy();
                                        return;
                                    }
                                }
                            }

                            // Remove Image nodes that have no loaded image (placeholder canvas filled by browser)
                            if (cls === 'Image') {
                                var img = (typeof node.image === 'function') ? node.image() : node.image;
                                // Check multiple properties that represent unloaded images
                                var isEmptyImage = false;
                                if (!img) isEmptyImage = true;
                                else if (typeof img.naturalWidth !== 'undefined' && img.naturalWidth === 0) isEmptyImage = true;
                                else if (typeof img.width !== 'undefined' && img.width === 0 && img.height === 0) isEmptyImage = true;

                                if (isEmptyImage) {
                                    console.log('wpgv: removing empty Image node', node);
                                    node.destroy();
                                    return;
                                }
                            }
                        } catch (er) {
                            console.error('wpgv: cleanup node error', er);
                        }
                    });

                    // Redraw after cleanup
                    konvaLayer.draw();
                } catch (e) {
                    console.error('wpgv: cleanupLayer error', e);
                }
            })();

            // Attach input listeners to update text
            attachInputListeners();

        } catch (e) {
            console.error('Error parsing JSON template:', e);
            console.error('Raw JSON:', currentTemplateData.json);
            renderSimpleOverlay();
        }
    }

    /**
     * Render Konva element from JSON
     */
    function renderKonvaElement(elementData) {
        if (!elementData || !elementData.className) return;

        var attrs = elementData.attrs || {};
        var className = elementData.className;

        // Handle different element types
        if (className === 'Text') {
            renderTextElement(attrs);
        } else if (className === 'Image') {
            renderImageElement(attrs);
        } else if (className === 'Rect') {
            renderRectElement(attrs);
        } else if (className === 'Circle') {
            renderCircleElement(attrs);
        }
    }

    /**
     * Render text element
     */
    function renderTextElement(attrs) {
        var textConfig = {
            x: attrs.x || 0,
            y: attrs.y || 0,
            text: getTextContent(attrs.id, attrs.text),
            fontSize: attrs.fontSize || 16,
            fontFamily: attrs.fontFamily || 'Arial',
            fill: attrs.fill || '#000000',
            align: attrs.align || 'left',
            width: attrs.width || null,
            height: attrs.height || null,
            rotation: attrs.rotation || 0,
            scaleX: attrs.scaleX || 1,
            scaleY: attrs.scaleY || 1,
            id: attrs.id || null
        };

        // Apply font style
        if (attrs.fontStyle) {
            textConfig.fontStyle = attrs.fontStyle;
        }

        var text = new Konva.Text(textConfig);
        konvaLayer.add(text);
    }

    /**
     * Get text content based on element ID
     */
    function getTextContent(elementId, defaultText) {
        if (!elementId) {
            // Check if defaultText is sample message text - if so and personal message is empty, return empty
            if (defaultText && (defaultText.indexOf('worse by') !== -1 || defaultText.indexOf('Manner before') !== -1)) {
                var personalMsg = $('#wpgv_personal_message').val();
                if (!personalMsg || personalMsg.trim() === '') {
                    return '';
                }
            }
            return defaultText || '';
        }

        // Map element IDs to input fields
        var fieldMap = {
            'giftto_value': function() { return $('#wpgv_recipient_name').val() || defaultText || 'Recipient Name'; },
            'giftto_input': function() { return $('#wpgv_recipient_name').val() || defaultText || 'FIRST & LAST NAME'; },
            'giftfrom_value': function() { return $('#wpgv_your_name').val() || defaultText || 'Your Name'; },
            'giftfrom_input': function() { return $('#wpgv_your_name').val() || defaultText || 'FIRST & LAST NAME'; },
            'giftcard_message': function() { return $('#wpgv_personal_message').val() || ''; },
            'giftcard_des': function() { return $('#wpgv_personal_message').val() || ''; },
            'giftcard_monney': function() {
                if (currentVoucherAmount === 0) {
                    currentVoucherAmount = getVoucherAmount();
                }
                return formatPrice(currentVoucherAmount);
            },
            'giftcard_date_gift': function() {
                return new Date().toLocaleDateString();
            },
            'giftcard_date_gift_input': function() {
                return new Date().toLocaleDateString('en-GB', { day: '2-digit', month: 'long', year: 'numeric' });
            },
            'giftcard_counpon': function() {
                return previewCouponCode || 'XXXXXXXXXXXX'; // Use real preview code instead of placeholder
            },
            'giftcard_counpon_label': function() { return currentTemplateData.counpon || ''; },
            'giftto_label': function() { return currentTemplateData.giftto || ''; },
            'giftfrom_label': function() { return currentTemplateData.giftfrom || ''; },
            'giftcard_monney_label': function() { return currentTemplateData.value_text || ''; },
            'giftcard_date_gift_label': function() { return currentTemplateData.date_of || ''; },
            'gift_title_first': function() { return defaultText || ''; },
            'gift_title_last': function() { return defaultText || ''; },
            'company_name': function() { return currentTemplateData.company_name || defaultText || ''; },
            'gift_title_company': function() { return currentTemplateData.company_name || defaultText || ''; },
            'giftcard_website': function() { return currentTemplateData.web || defaultText || ''; },
            'giftcard_email': function() { return currentTemplateData.email || defaultText || ''; },
            'giftcard_note': function() { return currentTemplateData.leftside_notice || defaultText || ''; },
            'giftcard_expiry': function() { return currentTemplateData.expiryDate || defaultText || ''; }
        };

        if (fieldMap[elementId]) {
            return fieldMap[elementId]();
        }

        // Check if defaultText is sample message text - if so and personal message is empty, return empty
        if (defaultText && (defaultText.indexOf('worse by') !== -1 || defaultText.indexOf('Manner before') !== -1)) {
            var personalMsg = $('#wpgv_personal_message').val();
            if (!personalMsg || personalMsg.trim() === '') {
                return '';
            }
        }

        return defaultText || '';
    }

    /**
     * Render image element
     */
    function renderImageElement(attrs) {
        // Determine image source
        var imageSrc = null;

        // Handle company logo - use from template data
        // Support both 'company_logo' and 'giftcard_logo' ids
        if ((attrs.id === 'company_logo' || attrs.id === 'giftcard_logo') && currentTemplateData.company_logo) {
            imageSrc = currentTemplateData.company_logo;
            console.log('Loading company logo:', imageSrc);
            console.log('Logo attributes from template:', attrs);
        } else if (attrs.src) {
            imageSrc = attrs.src;
        } else {
            // No src available, skip this image - avoid white rectangle
            console.warn('Image element has no src, skipping:', attrs);
            return;
        }

        var imageObj = new Image();
        imageObj.crossOrigin = 'Anonymous';

        imageObj.onload = function() {
            var image = new Konva.Image({
                x: attrs.x || 0,
                y: attrs.y || 0,
                image: imageObj,
                width: attrs.width || imageObj.width,
                height: attrs.height || imageObj.height,
                rotation: attrs.rotation || 0,
                scaleX: attrs.scaleX || 1,
                scaleY: attrs.scaleY || 1,
                id: attrs.id || null,
                name: attrs.name || null
            });

            konvaLayer.add(image);
            konvaLayer.draw();
        };

        imageObj.onerror = function() {
            console.error('Failed to load image:', imageSrc, attrs);
        };

        imageObj.src = imageSrc;
    }

    /**
     * Render rectangle element
     */
    function renderRectElement(attrs) {
        var rect = new Konva.Rect({
            x: attrs.x || 0,
            y: attrs.y || 0,
            width: attrs.width || 100,
            height: attrs.height || 100,
            fill: attrs.fill || null,
            stroke: attrs.stroke || null,
            strokeWidth: attrs.strokeWidth || 0,
            rotation: attrs.rotation || 0,
            scaleX: attrs.scaleX || 1,
            scaleY: attrs.scaleY || 1
        });

        konvaLayer.add(rect);
    }

    /**
     * Render circle element
     */
    function renderCircleElement(attrs) {
        var circle = new Konva.Circle({
            x: attrs.x || 0,
            y: attrs.y || 0,
            radius: attrs.radius || 50,
            fill: attrs.fill || null,
            stroke: attrs.stroke || null,
            strokeWidth: attrs.strokeWidth || 0
        });

        konvaLayer.add(circle);
    }

    /**
     * Render simple text overlay (fallback)
     */
    function renderSimpleOverlay() {
        var centerX = konvaStage.width() / 2;
        var centerY = konvaStage.height() / 2;

        // Recipient name
        var recipientText = new Konva.Text({
            x: 50,
            y: centerY - 100,
            text: 'To: ' + ($('#wpgv_recipient_name').val() || 'Recipient Name'),
            fontSize: 24,
            fontFamily: 'Arial',
            fill: '#000000',
            width: konvaStage.width() - 100,
            align: 'center'
        });
        konvaLayer.add(recipientText);

        // Sender name
        var senderText = new Konva.Text({
            x: 50,
            y: centerY - 60,
            text: 'From: ' + ($('#wpgv_your_name').val() || 'Your Name'),
            fontSize: 18,
            fontFamily: 'Arial',
            fill: '#000000',
            width: konvaStage.width() - 100,
            align: 'center'
        });
        konvaLayer.add(senderText);

        // Message
        var messageText = new Konva.Text({
            x: 50,
            y: centerY,
            text: $('#wpgv_personal_message').val() || '',
            fontSize: 14,
            fontFamily: 'Arial',
            fill: '#333333',
            width: konvaStage.width() - 100,
            align: 'center'
        });
        konvaLayer.add(messageText);

        konvaLayer.draw();
        attachInputListeners();
    }

    /**
     * Attach input listeners to update template in real-time
     */
    function attachInputListeners() {
        $('#wpgv_your_name, #wpgv_recipient_name, #wpgv_personal_message').off('input.wpgv').on('input.wpgv', function() {
            updateTemplateText();
        });

        // Listen for variation changes (WooCommerce event)
        $('form.variations_form').off('found_variation.wpgv').on('found_variation.wpgv', function(event, variation) {
            console.log('Variation found:', variation);
            // Wait for WooCommerce to update the price display
            setTimeout(function() {
                updateVoucherAmount();
            }, 200);
        });

        // Listen for variation reset
        $('form.variations_form').off('reset_data.wpgv').on('reset_data.wpgv', function() {
            console.log('Variation reset');
            setTimeout(function() {
                updateVoucherAmount();
            }, 200);
        });
    }

    /**
     * Update template text when inputs change
     */
    function updateTemplateText() {
        if (!konvaLayer) return;

        // Update text elements
        konvaLayer.find('Text').forEach(function(textNode) {
            var id = textNode.id();
            var newText = getTextContent(id, textNode.text());
            textNode.text(newText);
        });

        konvaLayer.draw();
    }

    /**
     * Get canvas as PNG data URL
     */
    window.wpgvGetCanvasImage = function() {
        if (!konvaStage) {
            console.error('Konva stage not initialized');
            return null;
        }

        try {
            return konvaStage.toDataURL({
                pixelRatio: 2,
                mimeType: 'image/png',
                quality: 1
            });
        } catch (e) {
            console.error('Error generating canvas image:', e);
            return null;
        }
    };

    /**
     * Convert data URL to Blob
     */
    window.wpgvDataURLtoBlob = function(dataurl) {
        var arr = dataurl.split(',');
        var mime = arr[0].match(/:(.*?);/)[1];
        var bstr = atob(arr[1]);
        var n = bstr.length;
        var u8arr = new Uint8Array(n);

        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }

        return new Blob([u8arr], { type: mime });
    };

    /**
     * Get current voucher amount (for external use)
     */
    window.wpgvGetVoucherAmount = function() {
        return currentVoucherAmount || getVoucherAmount();
    };

    /**
     * Update voucher amount (for external use)
     */
    window.wpgvUpdateVoucherAmount = updateVoucherAmount;

    /**
     * Get preview coupon code (for external use)
     */
    window.wpgvGetPreviewCouponCode = function() {
        return previewCouponCode;
    };

});
