/**
 * Feedback Admin JavaScript
 */
(function () {
    'use strict';

    let currentProduct = null;
    let currentFeedbackId = null;
    let editingProduct = null;
    let feedbackCache = {}; // Cache feedback per product/filters
    let feedbackItemsMap = {}; // Store feedback items by ID for instant modal open
    let products = [];

    // Helper to get proper nonce for REST API
    function getNonce() {
        return (typeof wpApiSettings !== 'undefined' && wpApiSettings.nonce)
            ? wpApiSettings.nonce
            : chaFeedbackData.nonce;
    }

    document.addEventListener('DOMContentLoaded', init);

    function init() {
        loadProducts();
        bindEvents();
        updatePreviewButton();
        updateEmbedButton();
    }

    /**
     * Update preview button with correct URL
     */
    function updatePreviewButton() {
        const previewBtn = document.getElementById('cha-preview-btn');
        if (!previewBtn) return;
        
        // Always show "View on Frontend" button
        previewBtn.innerHTML = `
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="16" height="16">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
            </svg>
            View on Frontend
        `;
        previewBtn.style.display = 'inline-flex';
        
        if (chaFeedbackData.previewBaseUrl) {
            // Page exists - link to it
            previewBtn.href = chaFeedbackData.previewBaseUrl + '#' + chaFeedbackData.previewHash;
            previewBtn.removeAttribute('data-create-page');
        } else {
            // No page exists - will show confirmation before creating
            previewBtn.href = '#';
            previewBtn.setAttribute('data-create-page', 'true');
        }
    }

    /**
     * Update embed button visibility
     */
    function updateEmbedButton() {
        const embedBtn = document.getElementById('cha-embed-btn');
        if (!embedBtn) return;
        
        // Always show the embed button
        embedBtn.style.display = 'inline-flex';
    }

    /**
     * Fetch preview URL for a specific product
     */
    async function fetchPreviewUrl(productId) {
        const previewBtn = document.getElementById('cha-preview-btn');
        if (!previewBtn || !chaFeedbackData.previewUrlApi) return;

        try {
            const response = await fetch(chaFeedbackData.previewUrlApi + '?product_id=' + productId, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            const data = await response.json();

            if (data.url) {
                chaFeedbackData.previewBaseUrl = data.url;
                previewBtn.href = data.url + '#' + chaFeedbackData.previewHash;
                previewBtn.removeAttribute('data-create-page');
            } else {
                chaFeedbackData.previewBaseUrl = '';
                previewBtn.href = '#';
                previewBtn.setAttribute('data-create-page', 'true');
            }
        } catch (error) {
            console.error('Failed to fetch preview URL:', error);
        }
    }

    /**
     * Handle preview/insert button click
     */
    async function handlePreviewButtonClick(e) {
        const btn = e.target.closest('#cha-preview-btn');
        if (!btn || !btn.hasAttribute('data-create-page')) return;
        
        e.preventDefault();
        
        // Show confirmation modal
        showCreatePageModal(btn);
    }

    /**
     * Show custom modal for page creation confirmation
     */
    function showCreatePageModal(btn) {
        // Remove existing modal if any
        const existingModal = document.getElementById('cha-create-page-modal');
        if (existingModal) existingModal.remove();

        const modal = document.createElement('div');
        modal.id = 'cha-create-page-modal';
        modal.className = 'cha-modal-overlay active';
        modal.innerHTML = `
            <div class="cha-modal cha-modal-sm">
                <div class="cha-modal-header">
                    <h2>Create Release Hub Page</h2>
                    <button type="button" class="cha-modal-close">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                        </svg>
                    </button>
                </div>
                <div class="cha-modal-body" style="display:block;">
                    <p style="margin: 0 0 16px; color: var(--cha-text-secondary); font-size: 14px; line-height: 1.6;">
                        No Release Hub page exists yet.
                    </p>
                    <p style="margin: 0; color: var(--cha-text-secondary); font-size: 14px; line-height: 1.6;">
                        This will create a new page with the <strong>Release Hub block</strong> where visitors can view your releases, feedback, and roadmap.
                    </p>
                </div>
                <div class="cha-modal-footer">
                    <button type="button" class="cha-btn cha-btn-secondary cha-modal-cancel">Cancel</button>
                    <button type="button" class="cha-btn cha-btn-primary cha-modal-confirm">Continue</button>
                </div>
            </div>
        `;

        document.body.appendChild(modal);

        // Bind events
        modal.querySelector('.cha-modal-close').addEventListener('click', () => modal.remove());
        modal.querySelector('.cha-modal-cancel').addEventListener('click', () => modal.remove());
        modal.addEventListener('click', (e) => {
            if (e.target === modal) modal.remove();
        });
        
        modal.querySelector('.cha-modal-confirm').addEventListener('click', async () => {
            modal.remove();
            await createFeedbackPage(btn);
        });
    }

    /**
     * Create the release hub page
     */
    async function createFeedbackPage(btn) {
        // Show loading state
        const originalHtml = btn.innerHTML;
        btn.innerHTML = '<span class="cha-spinner"></span> Creating...';
        btn.style.pointerEvents = 'none';
        
        try {
            const response = await fetch(chaFeedbackData.createPageUrl, {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': getNonce()
                },
                body: JSON.stringify({
                    product_id: currentProduct,
                    tab: chaFeedbackData.previewHash
                })
            });

            const data = await response.json();

            if (response.ok && data.success) {
                // Update button to View mode
                chaFeedbackData.previewBaseUrl = data.page_url.split('#')[0];
                updatePreviewButton();
                
                // Open the new page
                window.open(data.page_url, '_blank');
            } else {
                throw new Error(data.message || 'Failed to create page');
            }
        } catch (error) {
            console.error('Create page error:', error);
            alert('Error: ' + error.message);
            btn.innerHTML = originalHtml;
            btn.style.pointerEvents = '';
        }
    }

    function bindEvents() {
        // Preview button click
        document.getElementById('cha-preview-btn')?.addEventListener('click', handlePreviewButtonClick);
        
        // Embed button click - use local openEmbedModal function
        document.getElementById('cha-embed-btn')?.addEventListener('click', openEmbedModal);
        
        // Search
        const searchInput = document.getElementById('cha-search-input');
        if (searchInput) {
            let debounce;
            searchInput.addEventListener('input', () => {
                clearTimeout(debounce);
                debounce = setTimeout(loadFeedback, 300);
            });
        }

        // Filters
        document.getElementById('cha-status-filter')?.addEventListener('change', loadFeedback);
        document.getElementById('cha-category-filter')?.addEventListener('change', loadFeedback);

        // Modal close
        document.querySelectorAll('.cha-modal-close').forEach(el => {
            el.addEventListener('click', closeModal);
        });

        document.querySelectorAll('.cha-modal-overlay').forEach(el => {
            el.addEventListener('click', (e) => {
                if (e.target.classList.contains('cha-modal-overlay')) {
                    closeModal();
                }
            });
        });

        // Save feedback
        document.getElementById('cha-save-feedback')?.addEventListener('click', saveFeedback);

        // Delete feedback
        document.getElementById('cha-delete-feedback')?.addEventListener('click', deleteFeedback);

        // Status change - update indicator
        document.getElementById('cha-detail-status')?.addEventListener('change', function () {
            updateStatusIndicator(this.value);
        });

        // Add Product
        document.getElementById('cha-add-product-btn')?.addEventListener('click', () => {
            chaAdmin.handleAddProductClick({
                isPremium: chaFeedbackData.isPremium,
                upgradeUrl: chaFeedbackData.upgradeUrl,
                homeUrl: chaFeedbackData.homeUrl,
                adminUrl: chaFeedbackData.adminUrl,
                nonce: getNonce(),
                setEditing: (p) => { editingProduct = p; }
            });
        });
        document.getElementById('cha-product-form')?.addEventListener('submit', handleProductSubmit);

        // Escape key
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') closeModal();
        });
    }

    async function handleProductSubmit(e) {
        e.preventDefault();
        const btn = e.target.querySelector('button[type="submit"]');
        const name = document.getElementById('cha-product-name').value;
        const originalText = btn.innerHTML;

        try {
            btn.innerHTML = '<span class="cha-spinner"></span> Saving...';
            btn.disabled = true;

            const url = editingProduct
                ? `${chaFeedbackData.productsUrl}/${editingProduct.id}`
                : chaFeedbackData.productsUrl;

            const response = await fetch(url, {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': getNonce()
                },
                body: JSON.stringify({ name })
            });

            const data = await response.json();

            if (response.ok && (data.id || data.success)) {
                chaAdmin.closeProductModal();
                loadProducts();
                editingProduct = null;
            } else {
                throw new Error(data.message || 'Failed to create product');
            }
        } catch (error) {
            console.error('Failed to create product:', error);
            alert('Error: ' + error.message);
        } finally {
            if (btn) {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }
        }
    }


    async function loadProducts() {
        try {
            const response = await fetch(chaFeedbackData.productsUrl, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            const data = await response.json();

            // Ensure products is always an array
            products = Array.isArray(data) ? data : [];

            // If not premium, only show one product
            if (!chaFeedbackData.isPremium && products.length > 1) {
                products = products.slice(0, 1);
            }

            const container = document.getElementById('cha-product-tabs');
            if (!container) return;

            if (products.length === 0) {
                renderEmptyState();
                document.getElementById('cha-loading-state').style.display = 'none';
                return;
            }

            // Auto-select first product if none selected
            if (products.length > 0 && !currentProduct) {
                currentProduct = products[0].id;
            }

            renderProductTabs();

            // Load first product
            if (products.length > 0) {
                loadFeedback();
                loadStats();
                fetchPreviewUrl(currentProduct);
            }
        } catch (error) {
            console.error('Failed to load products:', error);
            products = [];
        }
    }

    function renderProductTabs() {
        const container = document.getElementById('cha-product-tabs');
        if (!container) return;

        container.innerHTML = '';

        products.forEach((product) => {
            const tab = document.createElement('button');
            tab.type = 'button';
            tab.className = 'cha-product-tab' + (currentProduct == product.id ? ' active' : '');
            tab.dataset.productId = product.id;
            tab.innerHTML = `
                <div class="cha-product-tab-content">
                    <span class="tab-name">${escapeHtml(product.name)}</span>
                    <div class="cha-product-tab-actions">
                        <button type="button" class="cha-product-action-btn edit" title="Rename Product" data-id="${product.id}">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="12" height="12">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                            </svg>
                        </button>
                        <button type="button" class="cha-product-action-btn delete" title="Delete Product" data-id="${product.id}">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="12" height="12">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                            </svg>
                        </button>
                    </div>
                </div>
            `;

            tab.addEventListener('click', (e) => {
                if (e.target.closest('.cha-product-action-btn')) return;

                document.querySelectorAll('.cha-product-tab').forEach(t => t.classList.remove('active'));
                tab.classList.add('active');
                currentProduct = product.id;
                loadFeedback();
                loadStats();
                fetchPreviewUrl(product.id);
            });

            const editBtn = tab.querySelector('.edit');
            if (editBtn) {
                editBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    openProductModal(product);
                });
            }

            const delBtn = tab.querySelector('.delete');
            if (delBtn) {
                delBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    deleteProduct(product.id);
                });
            }

            container.appendChild(tab);
        });
    }

    /**
     * Generate cache key based on current filters
     */
    function generateFeedbackCacheKey() {
        const status = document.getElementById('cha-status-filter')?.value || '';
        const category = document.getElementById('cha-category-filter')?.value || '';
        const search = document.getElementById('cha-search-input')?.value || '';
        return `${currentProduct || 'all'}_${status}_${category}_${search}`;
    }

    /**
     * Invalidate feedback cache (call after create/update/delete)
     */
    function invalidateFeedbackCache() {
        feedbackCache = {};
    }

    async function loadFeedback(forceRefresh = false) {
        const list = document.getElementById('cha-feedback-list');
        const loading = document.getElementById('cha-loading-state');
        const empty = document.getElementById('cha-empty-state');

        if (!list) return;

        // Generate cache key
        const cacheKey = generateFeedbackCacheKey();

        // Check cache first (unless force refresh)
        if (!forceRefresh && feedbackCache[cacheKey]) {
            renderFeedbackList(feedbackCache[cacheKey]);
            return;
        }

        loading.style.display = 'block';
        list.innerHTML = '';
        empty.style.display = 'none';

        const params = new URLSearchParams();
        if (currentProduct) params.append('product', currentProduct);

        const status = document.getElementById('cha-status-filter')?.value;
        if (status) params.append('status', status);

        const category = document.getElementById('cha-category-filter')?.value;
        if (category) params.append('category', category);

        const search = document.getElementById('cha-search-input')?.value;
        if (search) params.append('search', search);

        try {
            const response = await fetch(`${chaFeedbackData.restUrl}?${params}`, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            const data = await response.json();

            // Store in cache
            feedbackCache[cacheKey] = data;

            loading.style.display = 'none';
            renderFeedbackList(data);

        } catch (error) {
            console.error('Failed to load feedback:', error);
            loading.style.display = 'none';
            empty.style.display = 'block';
        }
    }

    /**
     * Render feedback list from data
     */
    function renderFeedbackList(data) {
        const list = document.getElementById('cha-feedback-list');
        const loading = document.getElementById('cha-loading-state');
        const empty = document.getElementById('cha-empty-state');

        loading.style.display = 'none';
        empty.style.display = 'none';

        // Store items by ID for instant modal open in viewDetail().
        if (data.items && data.items.length) {
            data.items.forEach(item => {
                feedbackItemsMap[item.id] = item;
            });
        }

        // Show limit reached notice for admins
        const existingNotice = document.querySelector('.cha-limit-notice');
        if (existingNotice) existingNotice.remove();

        if (data.is_limit_reached && !data.is_premium) {
            const notice = document.createElement('div');
            notice.className = 'cha-alert cha-alert-warning cha-limit-notice';
            notice.style.marginBottom = '20px';
            notice.innerHTML = `
                <div style="display: flex; align-items: center;">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20" style="margin-right: 8px;">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                    </svg>
                    <span>${chaFeedbackData.i18n.limitReached || 'Feature request limit is reached for free users. Please upgrade to Pro for unlimited feedback.'}</span>
                </div>
            `;
            list.parentNode.insertBefore(notice, list);
        }

        list.innerHTML = data.items.map(item => `
            <tr data-id="${item.id}">
                <td class="cha-col-title">
                    <strong>${escapeHtml(item.title)}</strong>
                    <div class="cha-actions">
                        <button type="button" class="cha-action-btn" onclick="chaFeedback.viewDetail(${item.id})" title="View">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
                            </svg>
                        </button>
                        <a href="${chaFeedbackData.adminUrl}post.php?post=${item.id}&action=edit" class="cha-action-btn" title="Edit">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                            </svg>
                        </a>
                    </div>
                </td>
                <td class="cha-col-category">
                    ${item.category ? `<span class="cha-category-badge">${escapeHtml(item.category.name)}</span>` : '—'}
                </td>
                <td class="cha-col-status">
                    <span class="cha-status-badge ${item.status}">${getStatusLabel(item.status)}</span>
                </td>
                <td class="cha-col-votes">
                    <span class="cha-vote-count">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/>
                        </svg>
                        ${item.upvotes}
                    </span>
                </td>
                <td class="cha-col-date">${formatDate(item.date)}</td>
                <td class="cha-col-author">
                    ${escapeHtml(item.author.name)}
                </td>
            </tr>
        `).join('');
    }

    async function loadStats() {
        try {
            const params = currentProduct ? `?product=${currentProduct}` : '';
            const response = await fetch(`${chaFeedbackData.restUrl}/stats${params}`, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            const stats = await response.json();

            document.getElementById('cha-total-feedback').textContent = stats.total || 0;
            
            // Show upgrade link if limit is reached
            const upgradeLink = document.querySelector('.cha-stat-upgrade-link');
            if (upgradeLink) {
                upgradeLink.style.display = (stats.total >= 20) ? 'block' : 'none';
            }

            document.getElementById('cha-in-review').textContent = stats.by_status?.in_review || 0;
            document.getElementById('cha-in-progress').textContent = stats.by_status?.in_progress || 0;
            document.getElementById('cha-completed').textContent = stats.by_status?.completed || 0;

        } catch (error) {
            console.error('Failed to load stats:', error);
        }
    }

    async function viewDetail(feedbackId) {
        currentFeedbackId = feedbackId;

        try {
            // Reuse cached list data to skip the API round-trip.
            let item = feedbackItemsMap[feedbackId] || null;

            // Fallback: fetch from server if not in the client-side map.
            if (!item) {
                const response = await fetch(`${chaFeedbackData.restUrl}/${feedbackId}`, {
                    credentials: 'same-origin',
                    headers: { 'X-WP-Nonce': getNonce() }
                });
                item = await response.json();
            }

            populateDetailModal(item);

        } catch (error) {
            console.error('Failed to load feedback detail:', error);
            alert('Failed to load feedback details');
        }
    }

    /**
     * Populate the feedback detail modal with item data.
     *
     * @param {Object} item Feedback item data.
     */
    function populateDetailModal(item) {
        // Editable title
        document.getElementById('cha-detail-title-input').value = item.title;

        // Type badge
        const isManual = item.is_manual;
        const typeBadge = document.getElementById('cha-detail-type-badge');
        typeBadge.textContent = isManual ? 'Manual' : 'Feedback';
        typeBadge.classList.toggle('manual', isManual);

        // Author section
        if (item.author) {
            document.getElementById('cha-detail-author-avatar').src = item.author.avatar || '';
            document.getElementById('cha-detail-author-name').textContent = item.author.name || 'Unknown';
        }

        // Posted date
        if (item.date) {
            const date = new Date(item.date);
            const now = new Date();
            const diff = Math.floor((now - date) / (1000 * 60 * 60 * 24));
            let dateText = '';
            if (diff === 0) dateText = 'Posted today';
            else if (diff === 1) dateText = 'Posted yesterday';
            else if (diff < 7) dateText = `Posted ${diff} days ago`;
            else dateText = `Posted on ${date.toLocaleDateString()}`;
            document.getElementById('cha-detail-date').textContent = dateText;
            document.getElementById('cha-detail-created-date').textContent = date.toLocaleDateString('en-US', {
                year: 'numeric',
                month: 'long',
                day: 'numeric'
            });
        }

        // Product badge
        const productBadge = document.getElementById('cha-detail-product-badge');
        if (item.product && item.product.name) {
            document.getElementById('cha-detail-product-name').textContent = item.product.name;
            productBadge.style.display = '';
        } else {
            productBadge.style.display = 'none';
        }

        // Category badge
        const categoryBadge = document.getElementById('cha-detail-category-badge');
        if (item.category && item.category.name) {
            document.getElementById('cha-detail-category-name').textContent = item.category.name;
            categoryBadge.style.display = '';
        } else {
            categoryBadge.style.display = 'none';
        }

        // Editable description
        const contentTextarea = document.getElementById('cha-detail-content');
        contentTextarea.value = item.content || '';

        // Status with indicator
        document.getElementById('cha-detail-status').value = item.status;
        updateStatusIndicator(item.status);

        // Visibility
        document.getElementById('cha-detail-visibility').value = item.visibility;

        // Product dropdown
        const productSelect = document.getElementById('cha-detail-product');
        if (productSelect && item.product) {
            productSelect.value = item.product.id || '';
        }

        // Stats
        document.getElementById('cha-detail-votes').textContent = item.upvotes;
        document.getElementById('cha-detail-comments').textContent = item.comment_count;

        openModal('cha-detail-modal');

        // Initialize Simple Rich Editor for description after paint.
        requestAnimationFrame(() => {
            if (window.ChaSimpleEditor) {
                ChaSimpleEditor.destroy('#cha-detail-content');
                ChaSimpleEditor.init('#cha-detail-content', {
                    minHeight: 150,
                    placeholder: 'Add a description...'
                });
            }
        });
    }

    function updateStatusIndicator(status) {
        const indicator = document.getElementById('cha-detail-status-indicator');
        if (indicator) {
            indicator.className = 'cha-status-indicator ' + status;
        }
    }

    async function saveFeedback() {
        if (!currentFeedbackId) return;

        const title = document.getElementById('cha-detail-title-input').value;

        // Get content from editor if available, otherwise from textarea
        let content;
        const editor = window.ChaSimpleEditor ? ChaSimpleEditor.get('#cha-detail-content') : null;
        if (editor) {
            content = editor.getContent();
        } else {
            content = document.getElementById('cha-detail-content').value;
        }

        const status = document.getElementById('cha-detail-status').value;
        const visibility = document.getElementById('cha-detail-visibility').value;
        const product_id = document.getElementById('cha-detail-product').value;

        try {
            await fetch(`${chaFeedbackData.restUrl}/${currentFeedbackId}`, {
                method: 'PUT',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': getNonce()
                },
                body: JSON.stringify({ title, content, status, visibility, product_id })
            });

            closeModal();
            invalidateFeedbackCache();
            feedbackItemsMap = {}; // Clear cached items so next viewDetail fetches fresh data.
            loadFeedback(true);
            loadStats();

        } catch (error) {
            console.error('Failed to save feedback:', error);
            alert('Failed to save changes');
        }
    }

    async function deleteFeedback() {
        if (!currentFeedbackId) return;
        if (!confirm('Are you sure you want to delete this feedback?')) return;

        try {
            await fetch(`${chaFeedbackData.restUrl}/${currentFeedbackId}`, {
                method: 'DELETE',
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });

            closeModal();
            invalidateFeedbackCache();
            feedbackItemsMap = {}; // Clear cached items after deletion.
            loadFeedback(true);
            loadStats();

        } catch (error) {
            console.error('Failed to delete feedback:', error);
            alert('Failed to delete feedback');
        }
    }

    function openModal(modalId) {
        const modal = document.getElementById(modalId);
        if (modal) {
            modal.classList.add('active');
            document.body.style.overflow = 'hidden';
        }
    }

    function closeModal() {
        document.querySelectorAll('.cha-modal-overlay.active').forEach(modal => {
            modal.classList.remove('active');
        });
        document.body.style.overflow = '';
        currentFeedbackId = null;
    }

    function getStatusLabel(status) {
        return chaFeedbackData.statuses[status] || status;
    }

    function formatDate(dateStr) {
        if (!dateStr) return '—';
        try {
            const date = new Date(dateStr);
            return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
        } catch {
            return dateStr;
        }
    }

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // Public API
    window.chaFeedback = {
        viewDetail,
        loadFeedback,
        loadStats
    };

    function renderEmptyState() {
        const productTabs = document.getElementById('cha-product-tabs');
        const loading = document.getElementById('cha-loading-state');
        const card = document.querySelector('.cha-card');

        // Hide loading spinner
        if (loading) loading.style.display = 'none';

        // Clear product tabs
        if (productTabs) productTabs.innerHTML = 'No products found.';

        // Replace the entire card content with empty state
        if (card) {
            card.innerHTML = `
                <div class="cha-empty-state" style="margin: 40px auto; max-width: 500px; box-shadow: none; background: transparent;">
                    <div class="cha-empty-state-icon">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="48" height="48">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
                        </svg>
                    </div>
                    <h3>No feedback found</h3>
                    <p>Create your first release/product to verify feedback setup or import demo data.</p>
                    <div class="cha-empty-state-actions">
                        <button type="button" class="cha-btn cha-btn-secondary" id="cha-import-demo-btn">
                             Import Demo Data
                        </button>
                    </div>
                </div>
            `;

            const btn = document.getElementById('cha-import-demo-btn');
            if (btn) btn.addEventListener('click', handleImportDemo);
        }
    }

    async function handleImportDemo() {
        const btn = document.getElementById('cha-import-demo-btn');
        if (btn) {
            btn.disabled = true;
            btn.textContent = 'Importing...';
            btn.classList.add('cha-btn-loading');
        }

        try {
            const response = await fetch(chaFeedbackData.importSampleUrl, {
                method: 'POST',
                headers: {
                    'X-WP-Nonce': getNonce(),
                    'Content-Type': 'application/json'
                }
            });

            const data = await response.json();

            if (response.ok) {
                alert('Demo data imported successfully!');
                setTimeout(() => window.location.reload(), 1500);
            } else {
                throw new Error(data.message || 'Import failed');
            }
        } catch (error) {
            console.error('Import error:', error);
            alert('Import error: ' + error.message);
            if (btn) {
                btn.disabled = false;
                btn.textContent = 'Import Demo Data';
                btn.classList.remove('cha-btn-loading');
            }
        }
    }

    // ========== Category Management ==========
    const categoryModal = document.getElementById('cha-category-modal');
    const categoriesListEl = document.getElementById('cha-categories-list');
    const categoriesLoadingEl = document.getElementById('cha-categories-loading');
    const categoriesEmptyEl = document.getElementById('cha-categories-empty');
    let categories = [];

    // Open category modal
    document.getElementById('cha-manage-categories-btn')?.addEventListener('click', openCategoryModal);

    // Close category modal
    categoryModal?.querySelectorAll('.cha-modal-close').forEach(el => {
        el.addEventListener('click', closeCategoryModal);
    });
    categoryModal?.addEventListener('click', (e) => {
        if (e.target.classList.contains('cha-modal-overlay')) closeCategoryModal();
    });

    // Add category
    document.getElementById('cha-add-category-btn')?.addEventListener('click', addCategory);
    document.getElementById('cha-new-category-name')?.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') addCategory();
    });

    function openCategoryModal() {
        if (!chaFeedbackData.isPremium) {
            showCategoryUpgradeModal();
            return;
        }

        if (categoryModal) {
            categoryModal.classList.add('active');
            loadCategories();
        }
    }

    function closeCategoryModal() {
        if (categoryModal) categoryModal.classList.remove('active');
    }

    async function loadCategories() {
        if (!categoriesListEl) return;

        if (categoriesLoadingEl) categoriesLoadingEl.style.display = 'block';
        if (categoriesEmptyEl) categoriesEmptyEl.style.display = 'none';
        categoriesListEl.innerHTML = '';

        try {
            const response = await fetch(`${chaFeedbackData.restUrl.replace('/feedback', '')}/feedback-categories`, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            categories = await response.json();

            if (categoriesLoadingEl) categoriesLoadingEl.style.display = 'none';

            if (!categories.length) {
                if (categoriesEmptyEl) categoriesEmptyEl.style.display = 'block';
                return;
            }

            renderCategories();
        } catch (error) {
            console.error('Failed to load categories:', error);
            if (categoriesLoadingEl) categoriesLoadingEl.style.display = 'none';
        }
    }

    function renderCategories() {
        if (!categoriesListEl) return;

        categoriesListEl.innerHTML = categories.map(cat => `
            <tr data-id="${cat.id}">
                <td>
                    <span class="cat-name">${escapeHtml(cat.name)}</span>
                    <input type="text" class="cat-name-input cha-input" value="${escapeHtml(cat.name)}" style="display: none;">
                </td>
                <td><code>${escapeHtml(cat.slug)}</code></td>
                <td class="cha-col-count">${cat.count}</td>
                <td class="cha-col-actions">
                    <button type="button" class="cha-action-btn cha-cat-edit" title="Edit">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="16" height="16">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
                        </svg>
                    </button>
                    <button type="button" class="cha-action-btn cha-cat-save" title="Save" style="display: none;">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="16" height="16">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
                        </svg>
                    </button>
                    <button type="button" class="cha-action-btn cha-cat-cancel" title="Cancel" style="display: none;">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="16" height="16">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                        </svg>
                    </button>
                    <button type="button" class="cha-action-btn delete cha-cat-delete" title="Delete">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="16" height="16">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
                        </svg>
                    </button>
                </td>
            </tr>
        `).join('');

        // Bind edit/delete actions
        categoriesListEl.querySelectorAll('.cha-cat-edit').forEach(btn => {
            btn.addEventListener('click', () => startEditCategory(btn.closest('tr')));
        });
        categoriesListEl.querySelectorAll('.cha-cat-save').forEach(btn => {
            btn.addEventListener('click', () => saveEditCategory(btn.closest('tr')));
        });
        categoriesListEl.querySelectorAll('.cha-cat-cancel').forEach(btn => {
            btn.addEventListener('click', () => cancelEditCategory(btn.closest('tr')));
        });
        categoriesListEl.querySelectorAll('.cha-cat-delete').forEach(btn => {
            btn.addEventListener('click', () => deleteCategory(btn.closest('tr').dataset.id));
        });
    }

    async function addCategory() {
        const input = document.getElementById('cha-new-category-name');
        if (!input) return;

        const name = input.value.trim();
        if (!name) return;

        const btn = document.getElementById('cha-add-category-btn');
        if (btn) btn.disabled = true;

        try {
            const response = await fetch(`${chaFeedbackData.restUrl.replace('/feedback', '')}/feedback-categories`, {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': getNonce()
                },
                body: JSON.stringify({ name })
            });

            if (!response.ok) {
                const error = await response.json();
                throw new Error(error.message || 'Failed to create category');
            }

            input.value = '';
            loadCategories();
            refreshCategoryFilter();
        } catch (error) {
            alert(error.message);
        } finally {
            if (btn) btn.disabled = false;
        }
    }

    function startEditCategory(row) {
        row.querySelector('.cat-name').style.display = 'none';
        row.querySelector('.cat-name-input').style.display = 'block';
        row.querySelector('.cha-cat-edit').style.display = 'none';
        row.querySelector('.cha-cat-delete').style.display = 'none';
        row.querySelector('.cha-cat-save').style.display = 'inline-flex';
        row.querySelector('.cha-cat-cancel').style.display = 'inline-flex';
        row.querySelector('.cat-name-input').focus();
    }

    function cancelEditCategory(row) {
        const nameSpan = row.querySelector('.cat-name');
        const nameInput = row.querySelector('.cat-name-input');
        nameInput.value = nameSpan.textContent;
        nameSpan.style.display = '';
        nameInput.style.display = 'none';
        row.querySelector('.cha-cat-edit').style.display = '';
        row.querySelector('.cha-cat-delete').style.display = '';
        row.querySelector('.cha-cat-save').style.display = 'none';
        row.querySelector('.cha-cat-cancel').style.display = 'none';
    }

    async function saveEditCategory(row) {
        const id = row.dataset.id;
        const newName = row.querySelector('.cat-name-input').value.trim();
        if (!newName) return;

        try {
            const response = await fetch(`${chaFeedbackData.restUrl.replace('/feedback', '')}/feedback-categories/${id}`, {
                method: 'POST',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': getNonce()
                },
                body: JSON.stringify({ name: newName })
            });

            if (!response.ok) {
                const error = await response.json();
                throw new Error(error.message || 'Failed to update category');
            }

            loadCategories();
            refreshCategoryFilter();
        } catch (error) {
            alert(error.message);
        }
    }

    async function deleteCategory(id) {
        if (!confirm('Are you sure you want to delete this category?')) return;

        try {
            const response = await fetch(`${chaFeedbackData.restUrl.replace('/feedback', '')}/feedback-categories/${id}`, {
                method: 'DELETE',
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });

            if (!response.ok) {
                const error = await response.json();
                throw new Error(error.message || 'Failed to delete category');
            }

            loadCategories();
            refreshCategoryFilter();
        } catch (error) {
            alert(error.message);
        }
    }

    async function refreshCategoryFilter() {
        const filter = document.getElementById('cha-category-filter');
        if (!filter) return;

        try {
            const response = await fetch(`${chaFeedbackData.restUrl.replace('/feedback', '')}/feedback-categories`, {
                credentials: 'same-origin',
                headers: { 'X-WP-Nonce': getNonce() }
            });
            const cats = await response.json();

            const currentValue = filter.value;
            filter.innerHTML = '<option value="">All Categories</option>';
            cats.forEach(cat => {
                const option = document.createElement('option');
                option.value = cat.slug;
                option.textContent = cat.name;
                filter.appendChild(option);
            });
            filter.value = currentValue;
        } catch (error) {
            console.error('Failed to refresh categories:', error);
        }
    }

    // ========== Embed Modal Functions ==========
    let currentEmbedProductId = null;
    let embedTabsInitialized = false;

    /**
     * Open embed modal
     */
    function openEmbedModal() {
        // Check if user has Pro
        if (!chaFeedbackData.isPremium) {
            // Show upgrade modal for free users
            showEmbedUpgradeModal();
            return;
        }

        // Get current product from the active tab
        const activeTab = document.querySelector('.cha-product-tab.active');
        if (activeTab) {
            currentEmbedProductId = activeTab.dataset.id;
        }

        const modal = document.getElementById('cha-embed-modal');
        if (modal) {
            modal.classList.add('active');

            // Hide SDK tab for feedback (only iframe is supported)
            const sdkTab = modal.querySelector('.cha-embed-tab[data-tab="sdk"]');
            const sdkTabContent = modal.querySelector('.cha-embed-tab-content[data-tab="sdk"]');
            if (sdkTab) sdkTab.style.display = 'none';
            if (sdkTabContent) sdkTabContent.style.display = 'none';

            // Ensure iframe tab is active
            const iframeTab = modal.querySelector('.cha-embed-tab[data-tab="iframe"]');
            const iframeTabContent = modal.querySelector('.cha-embed-tab-content[data-tab="iframe"]');
            if (iframeTab) iframeTab.classList.add('active');
            if (iframeTabContent) iframeTabContent.classList.add('active');

            // Initialize tabs only once
            if (!embedTabsInitialized) {
                initEmbedTabs();
                embedTabsInitialized = true;
            }

            generateEmbedCode();
        }
    }

    /**
     * Show Embed Upgrade Modal for Free Users
     */
    function showEmbedUpgradeModal() {
        // Remove existing modal if any
        const existingModal = document.getElementById('cha-embed-upgrade-modal');
        if (existingModal) existingModal.remove();

        const modal = document.createElement('div');
        modal.id = 'cha-embed-upgrade-modal';
        modal.className = 'cha-modal-overlay active';
        modal.innerHTML = `
            <div class="cha-modal cha-upgrade-bg-modal" style="max-width: 600px;">
                <div class="cha-upgrade-modal-header">
                    <button type="button" class="cha-modal-close">&times;</button>
                    <div class="cha-upgrade-modal-icon">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="white" width="32" height="32">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
                        </svg>
                    </div>
                    <h2 class="cha-upgrade-modal-title">Embed Feedback Board</h2>
                    <span class="cha-upgrade-modal-badge">PRO FEATURE</span>
                </div>

                <!-- Content -->
                <div class="cha-upgrade-modal-body">
                    <p class="cha-upgrade-modal-desc">
                        Embed your feedback board directly on external websites using iframe.
                    </p>

                    <!-- Feature Preview -->
                    <div class="cha-upgrade-features">
                        <div class="cha-upgrade-features-grid">
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">Iframe Embed</h4>
                                    <p class="cha-upgrade-feature-desc">Copy & paste code</p>
                                </div>
                            </div>
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/>
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">Custom Branding</h4>
                                    <p class="cha-upgrade-feature-desc">Match your brand aesthetic</p>
                                </div>
                            </div>
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/>
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">In-app widget</h4>
                                    <p class="cha-upgrade-feature-desc">Embed widget in your app</p>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- CTA Button -->
                    <div class="cha-upgrade-cta-wrap">
                        <a href="${chaFeedbackData.upgradeUrl}" class="cha-btn cha-btn-primary cha-upgrade-cta">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
                            </svg>
                            Unlock Embed Feature
                        </a>
                    </div>
                </div>
            </div>
        `;

        document.body.appendChild(modal);

        // Close handlers
        modal.querySelector('.cha-modal-close').addEventListener('click', () => modal.remove());
        modal.addEventListener('click', (e) => {
            if (e.target === modal) modal.remove();
        });
    }

    /**
     * Show Category Upgrade Modal for Free Users
     */
    function showCategoryUpgradeModal() {
        // Remove existing modal if any
        const existingModal = document.getElementById('cha-category-upgrade-modal');
        if (existingModal) existingModal.remove();

        const modal = document.createElement('div');
        modal.id = 'cha-category-upgrade-modal';
        modal.className = 'cha-modal-overlay active';
        
        modal.innerHTML = `
            <div class="cha-modal cha-upgrade-bg-modal" style="max-width: 600px;">
                <div class="cha-upgrade-modal-header">
                    <button type="button" class="cha-modal-close">&times;</button>
                    <div class="cha-upgrade-modal-icon">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="white" width="32" height="32">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
                        </svg>
                    </div>
                    <h2 class="cha-upgrade-modal-title">Manage Categories & Status</h2>
                    <span class="cha-upgrade-modal-badge">PRO FEATURE</span>
                </div>

                <!-- Content -->
                <div class="cha-upgrade-modal-body">
                    <p class="cha-upgrade-modal-desc">
                        Custom categories and statuses allow you to organize feedback more effectively. Add, edit, or delete them to match your workflow.
                    </p>

                    <!-- Feature Preview -->
                    <div class="cha-upgrade-features">
                        <div class="cha-upgrade-features-grid">
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">Unlimited Customization</h4>
                                    <p class="cha-upgrade-feature-desc">Create categories & statuses</p>
                                </div>
                            </div>
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">Edit & Rename</h4>
                                    <p class="cha-upgrade-feature-desc">Full control over names</p>
                                </div>
                            </div>
                            <div class="cha-upgrade-feature">
                                <div class="cha-upgrade-feature-icon">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                                    </svg>
                                </div>
                                <div>
                                    <h4 class="cha-upgrade-feature-title">Quick Delete</h4>
                                    <p class="cha-upgrade-feature-desc">Remove records instantly</p>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- CTA Button -->
                    <div class="cha-upgrade-cta-wrap">
                        <a href="${chaFeedbackData.upgradeUrl}" class="cha-btn cha-btn-primary cha-upgrade-cta">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="20" height="20">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
                            </svg>
                            Upgrade to Premium
                        </a>
                    </div>
                </div>
            </div>
        `;

        document.body.appendChild(modal);

        // Close handlers
        modal.querySelector('.cha-modal-close').addEventListener('click', () => modal.remove());
        modal.addEventListener('click', (e) => {
            if (e.target === modal) modal.remove();
        });
    }

    /**
     * Close embed modal
     */
    function closeEmbedModal() {
        const modal = document.getElementById('cha-embed-modal');
        if (modal) {
            modal.classList.remove('active');
        }
    }

    /**
     * Initialize embed tabs
     */
    function initEmbedTabs() {
        const modal = document.getElementById('cha-embed-modal');
        if (!modal) return;

        const tabs = modal.querySelectorAll('.cha-embed-tab');
        const contents = modal.querySelectorAll('.cha-embed-tab-content');

        tabs.forEach(tab => {
            tab.addEventListener('click', () => {
                const tabName = tab.dataset.tab;

                // Update active tab
                tabs.forEach(t => t.classList.remove('active'));
                tab.classList.add('active');

                // Update active content
                contents.forEach(c => {
                    c.classList.toggle('active', c.dataset.tab === tabName);
                });
            });
        });

        // Height change listener
        document.getElementById('cha-embed-height')?.addEventListener('input', generateEmbedCode);

        // Copy button for iframe code
        document.getElementById('cha-copy-embed')?.addEventListener('click', copyEmbedCode);

        // Bind copy buttons for SDK (if any)
        modal.querySelectorAll('.cha-copy-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                const targetId = btn.dataset.target;
                copyToClipboard(targetId, btn);
            });
        });

        // Bind inline copy buttons
        modal.querySelectorAll('.cha-copy-inline').forEach(btn => {
            btn.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                const code = btn.getAttribute('data-code');
                if (!code) {
                    console.error('No data-code attribute found');
                    return;
                }

                // Use fallback method for copying
                copyTextFallback(code, btn);
            });
        });

        // Close button handlers
        modal.querySelectorAll('.cha-modal-close').forEach(btn => {
            btn.addEventListener('click', closeEmbedModal);
        });

        // Click outside to close
        modal.addEventListener('click', (e) => {
            if (e.target === modal) closeEmbedModal();
        });
    }

    /**
     * Generate embed code
     */
    function generateEmbedCode() {
        const height = document.getElementById('cha-embed-height')?.value || 600;
        // Derive base URL from admin URL to support subdirectory installs.
        const baseUrl = window.location.href.split( '/wp-admin' )[0];
        const embedType = 'feedback';

        const embedUrl = `${baseUrl}/?cha_embed=1&product=${currentEmbedProductId || ''}&type=${embedType}`;

        const iframeCode = `<iframe src="${embedUrl}" width="100%" height="${height}" frameborder="0" style="border: none; border-radius: 8px;"></iframe>`;

        const codeTextarea = document.getElementById('cha-embed-code');
        if (codeTextarea) {
            codeTextarea.value = iframeCode;
        }
    }

    /**
     * Copy embed code to clipboard
     */
    function copyEmbedCode() {
        const codeTextarea = document.getElementById('cha-embed-code');
        if (!codeTextarea) return;

        codeTextarea.select();
        codeTextarea.setSelectionRange(0, 99999);

        // Try modern clipboard API first, fallback to execCommand
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(codeTextarea.value).then(() => {
                showCopySuccess(document.getElementById('cha-copy-embed'));
            }).catch(() => {
                // Fallback
                document.execCommand('copy');
                showCopySuccess(document.getElementById('cha-copy-embed'));
            });
        } else {
            document.execCommand('copy');
            showCopySuccess(document.getElementById('cha-copy-embed'));
        }
    }

    /**
     * Copy to clipboard from a textarea by ID
     *
     * @param {string} textareaId - The ID of the textarea to copy from
     * @param {HTMLElement} btn - The button that was clicked
     */
    function copyToClipboard(textareaId, btn) {
        const textarea = document.getElementById(textareaId);
        if (textarea) {
            textarea.select();
            textarea.setSelectionRange(0, 99999);
            document.execCommand('copy');
            showCopySuccess(btn);
        }
    }

    /**
     * Fallback copy method using temporary textarea
     *
     * @param {string} text - Text to copy
     * @param {HTMLElement} btn - The button that was clicked
     */
    function copyTextFallback(text, btn) {
        const textArea = document.createElement('textarea');
        textArea.value = text;
        textArea.style.position = 'fixed';
        textArea.style.left = '-9999px';
        textArea.style.top = '-9999px';
        document.body.appendChild(textArea);
        textArea.select();
        try {
            document.execCommand('copy');
            const originalText = btn.textContent;
            btn.textContent = 'Copied!';
            setTimeout(() => { btn.textContent = originalText; }, 1500);
        } catch (err) {
            console.error('Copy failed:', err);
        }
        document.body.removeChild(textArea);
    }

    /**
     * Show copy success state on button
     *
     * @param {HTMLElement} btn - The button to update
     */
    function showCopySuccess(btn) {
        if (!btn) return;
        const originalHTML = btn.innerHTML;
        btn.innerHTML = `
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="14" height="14">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
            </svg>
            Copied!
        `;
        setTimeout(() => {
            btn.innerHTML = originalHTML;
        }, 2000);
    }
    
    // ========== Product Modal & Actions ==========
    function openProductModal(product = null) {
        editingProduct = product;
        const productForm = document.getElementById('cha-product-form');
        const modalTitle = document.getElementById('cha-product-modal-title');

        if (productForm) {
            productForm.reset();
            if (product) {
                if (modalTitle) modalTitle.textContent = 'Edit Product';
                productForm.querySelector('#cha-product-name').value = product.name;
            } else {
                if (modalTitle) modalTitle.textContent = 'Add New Product';
            }
        }
        openModal('cha-product-modal');
        setTimeout(() => {
            const nameInput = document.getElementById('cha-product-name');
            if (nameInput) nameInput.focus();
        }, 50);
    }

    function deleteProduct(id) {
        chaAdmin.deleteProduct(id, {
            productsUrl: chaFeedbackData.productsUrl,
            nonce: getNonce(),
            onSuccess: function() {
                if (currentProduct == id) {
                    currentProduct = '';
                }
                loadProducts();
            }
        });
    }

})();

