(function($) {
    'use strict';
    
    var chatInitialized = false;
    var chatNonce = '';
    var ajaxurl = '';
    var currentConvId = null;
    var currentConv = null;
    var pollInterval = null;
    var listPollInterval = null;
    var saveTimeout = null;
    var _chatTeamData = []; 
    

    
    
    $(document).on('impulse:workspace:chat', function() {
        if (!chatInitialized) {
            chatNonce = window.Impulse.chat ? window.Impulse.chat.nonce : '';
            ajaxurl = window.Impulse.chat ? window.Impulse.chat.ajaxurl : '';
            initChatWorkspace();
            chatInitialized = true;
        }
    });

    
    if (window.Impulse && window.Impulse.workspace === 'chat') {
        $(document).ready(function() {
            chatNonce = window.Impulse.chat ? window.Impulse.chat.nonce : '';
            ajaxurl = window.Impulse.chat ? window.Impulse.chat.ajaxurl : '';
            initChatWorkspace();
            chatInitialized = true;
        });
    }


    
    


    $(document).on('click', '#impulse-chat-test-email', testEmail);
    $(document).on('click', '#impulse-chat-test-sms', testSms);
    $(document).on('click', '#impulse-chat-test-whatsapp', testWhatsapp);
    $(document).on('change', '#impulse-chat-ai_enabled', function() {

        

        
        if (this.checked) {
            $('#impulse-instagent-config').slideDown(150);
            $('#impulse-instagent-escalate').slideDown(150);
        } else {
            $('#impulse-instagent-config').slideUp(150);
            $('#impulse-instagent-escalate').slideUp(150);
        }
        saveSettings();
    });
    $(document).on('input', '#impulse-ai-handoff-timeout', function() { $('#impulse-ai-handoff-val').text($(this).val() + 's'); });
    $(document).on('change', '#impulse-ai-handoff-timeout', saveSettings);
    var _aiHandoffTimer, _aiInfoTimer;
    $(document).on('input', '#impulse-ai-handoff-msg', function() { clearTimeout(_aiHandoffTimer); _aiHandoffTimer = setTimeout(saveSettings, 800); });
    $(document).on('input', '#impulse-ai-store-info', function() { clearTimeout(_aiInfoTimer); _aiInfoTimer = setTimeout(saveSettings, 800); });
    
    $(document).on('change', '#impulse-chat-attachments, #impulse-chat-screenshots, #impulse-chat-collect_name, #impulse-chat-collect_phone, #impulse-chat-collect_email', saveSettings);
    
    var _notifInputTimer;
    $(document).on('input', '#impulse-chat-email_address, #impulse-chat-sms_number, #impulse-chat-whatsapp_number', function() {
        clearTimeout(_notifInputTimer); _notifInputTimer = setTimeout(saveSettings, 800);
    });


    
    
    $(document).on('click', '.impulse-chat-conv-item', function() {
        if (!chatInitialized) {
            chatNonce = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.nonce   : '';
            ajaxurl   = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.ajaxurl : '';
            initChatWorkspace();
            chatInitialized = true;
        }
        var id = $(this).data('id');
        if (currentConvId === id) {
            deselectConversation();
        } else {
            openConversation(id);
        }
    });

    function initChatWorkspace() {
        
        (function() {
            var $ws = $('.impulse-chat-workspace');
            if (!$ws.length) return;
            var dragging = null, startX = 0, startW = 0;

            $('.impulse-chat-resize-handle').on('mousedown', function(e) {
                e.preventDefault();
                dragging = $(this).data('edge');
                startX = e.clientX;
                var prop = dragging === 'left' ? '--chat-left-w' : '--chat-right-w';
                startW = parseInt(getComputedStyle($ws[0]).getPropertyValue(prop)) || 280;
                $(this).addClass('active');
                $('body').css({ cursor: 'col-resize', userSelect: 'none' });
            });

            $(document).on('mousemove.chatResize', function(e) {
                if (!dragging) return;
                var delta = e.clientX - startX;
                var newW;
                if (dragging === 'left') {
                    newW = Math.max(200, Math.min(500, startW + delta));
                    $ws[0].style.setProperty('--chat-left-w', newW + 'px');
                } else {
                    newW = Math.max(200, Math.min(600, startW - delta));
                    $ws[0].style.setProperty('--chat-right-w', newW + 'px');
                }
            });

            $(document).on('mouseup.chatResize', function() {
                if (!dragging) return;
                $('.impulse-chat-resize-handle.active').removeClass('active');
                $('body').css({ cursor: '', userSelect: '' });
                dragging = null;
            });
        })();

        
        $(document).on('change', '.impulse-chat-summary-toggle input[type="checkbox"]', function(e) {
            var detailsId = $(this).data('opens');
            if (detailsId && this.checked) {
                var $details = $('#' + detailsId);
                if ($details.length && !$details.prop('open')) {
                    $details.prop('open', true);
                }
            }
        });
        
        
        $(document).on('toggle', '.impulse-card-details', function(e) {
            if (this.open) {
                var $details = $(this);
                var $panel = $details.closest('.impulse-chat-right-content');
                if ($panel.length) {
                    setTimeout(function() {
                        var panelHeight = $panel.height();
                        var detailsTop = $details.position().top;
                        var detailsHeight = $details.outerHeight();
                        var scrollTarget = detailsTop - (panelHeight / 2) + (detailsHeight / 2);
                        $panel.animate({ scrollTop: $panel.scrollTop() + scrollTarget }, 300);
                    }, 50);
                }
            }
        });
        
        
        $(document).on('click', '.impulse-chat-summary-toggle', function(e) {
            e.stopPropagation();
        });
        
        
        $(document).on('click', '.impulse-chat-summary-toggle input[data-pro="true"]:disabled', function(e) {
            e.preventDefault();
            window.showToast('This feature is available in Pro version only.', 'info');
        });
        
        
        $(document).on('click', '.impulse-chat-pos-btn', function() {
            var $btn = $(this);
            var val = $btn.data('value');
            $('.impulse-chat-pos-btn').removeAttr('data-active');
            $btn.attr('data-active', 'true');
            $('#impulse-chat-position').val(val).trigger('change');
        });

        
        function hexToRgb(hex) {
            hex = hex.replace('#','');
            if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
            return { r: parseInt(hex.substr(0,2),16), g: parseInt(hex.substr(2,2),16), b: parseInt(hex.substr(4,2),16) };
        }
        function tintOnWhite(hex, opacity) {
            var c = hexToRgb(hex);
            var r = Math.round(c.r * opacity + 255 * (1 - opacity));
            var g = Math.round(c.g * opacity + 255 * (1 - opacity));
            var b = Math.round(c.b * opacity + 255 * (1 - opacity));
            return '#' + [r,g,b].map(function(v){ return ('0'+v.toString(16)).slice(-2); }).join('');
        }
        function applyBrandColors(color) {
            $('#impulse-chat-color_button').val(color);
        }
        $(document).on('impulse:color-changed', function(e, data) {
            if (!$(data.swatch).is('#impulse-chat-brand-swatch')) return;
            applyBrandColors(data.color);
        });
        
        $(document).on('change input', '#impulse-chat-color_button', function() {
            var color = $(this).val();
            if (/^#[0-9A-Fa-f]{6}$/.test(color)) saveSettings();
        });



        
        $('#impulse-chat-send-reply').on('click', sendReply);
        $('#impulse-chat-reply-input').on('keydown', function(e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendReply();
            }
        });
        
        
        $('#impulse-chat-reply-input').on('input', function() {
            if (!currentConvId) return;
            var val = $(this).val();
            try {
                if (val) {
                    localStorage.setItem('instinctor_chat_draft_' + currentConvId, val);
                } else {
                    localStorage.removeItem('instinctor_chat_draft_' + currentConvId);
                }
            } catch(e) {}
        });
        
        
        $('#impulse-chat-reply-input').on('input', function() {
            var val = $(this).val();
            if (val === '/') {
                openSlashMenu('');
            } else if (val.charAt(0) === '/' && val.length > 1) {
                openSlashMenu(val.slice(1));
            } else {
                closeSlashMenu();
            }
        });
        
        
        $('#impulse-chat-reply-input').on('keydown', function(e) {
            var $menu = $('#impulse-chat-slash-menu');
            if (!$menu.is(':visible')) return;
            var $items = $menu.find('.impulse-chat-slash-item');
            var $active = $items.filter('.active');
            if (e.key === 'ArrowDown') {
                e.preventDefault();
                if ($active.length && $active.next('.impulse-chat-slash-item').length) {
                    $active.removeClass('active');
                    $active.next('.impulse-chat-slash-item').addClass('active');
                } else {
                    $active.removeClass('active');
                    $items.first().addClass('active');
                }
            } else if (e.key === 'ArrowUp') {
                e.preventDefault();
                if ($active.length && $active.prev('.impulse-chat-slash-item').length) {
                    $active.removeClass('active');
                    $active.prev('.impulse-chat-slash-item').addClass('active');
                } else {
                    $active.removeClass('active');
                    $items.last().addClass('active');
                }
            } else if (e.key === 'Enter') {
                var $active = $menu.find('.impulse-chat-slash-item.active');
                if ($active.length) {
                    e.preventDefault();
                    var msg = $active.data('message');
                    $('#impulse-chat-reply-input').val(msg).focus();
                    try { localStorage.removeItem('instinctor_chat_draft_' + currentConvId); } catch(e2) {}
                    closeSlashMenu();
                }
            } else if (e.key === 'Escape') {
                closeSlashMenu();
                $(this).val('');
            }
        });
        
        
        $('#impulse-chat-slash-input').on('input', function() {
            renderSlashItems($(this).val());
        });
        
        
        $(document).on('click', '.impulse-chat-slash-item', function() {
            var msg = $(this).data('message');
            $('#impulse-chat-reply-input').val(msg).focus();
            try { localStorage.removeItem('instinctor_chat_draft_' + currentConvId); } catch(e) {}
            closeSlashMenu();
        });
        
        
        $(document).on('click.slashmenu', function(e) {
            if (!$(e.target).closest('#impulse-chat-slash-menu, #impulse-chat-reply-input').length) {
                closeSlashMenu();
            }
        });
        
        $(document).on('click', '.impulse-chat-quick-reply', function(e) {
            if ($(e.target).closest('.impulse-qr-remove-btn, .impulse-qr-drag').length) return;
            
            if ($(e.target).closest('.impulse-qr-text').prop('contentEditable') === 'true') return;
            var msg = $(this).data('message');
            $('#impulse-chat-reply-input').val(msg).focus();
        });

        
        $(document).on('dblclick', '.impulse-qr-text', function(e) {
            e.stopPropagation();
            var $text = $(this);
            $text.data('original', $text.text().trim());
            $text.attr('contenteditable', 'true').focus();
            
            var range = document.createRange();
            var sel = window.getSelection();
            range.selectNodeContents($text[0]);
            range.collapse(false);
            sel.removeAllRanges();
            sel.addRange(range);
        });

        $(document).on('blur', '.impulse-qr-text', function() {
            var $text = $(this);
            $text.removeAttr('contenteditable');
            var $row = $text.closest('.impulse-chat-quick-reply');
            var newText = $text.text().trim();
            var original = $text.data('original') || '';
            if (!newText) { $text.text(original); return; }
            if (newText === original) return;
            var index = $row.data('index');
            var cat   = $row.data('cat') || '';
            $row.data('message', newText);
            $.post(ajaxurl, {
                action: 'instinctor_chat_update_quick_action',
                index: index,
                message: newText,
                category: cat,
                nonce: chatNonce
            }, function(response) {
                if (response.success) {
                    renderQuickReplies(response.data.quick_actions);
                } else {
                    window.showToast((typeof response.data === 'string' ? response.data : null) || 'Error saving reply', 'error');
                    $text.text(original); 
                }
            }).fail(function() {
                window.showToast('Error saving reply', 'error');
                $text.text(original); 
            });
        });

        $(document).on('keydown', '.impulse-qr-text', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $(this).blur();
            } else if (e.key === 'Escape') {
                e.preventDefault();
                var $text = $(this);
                $text.text($text.data('original') || '');
                $text.blur();
            }
        });

        
        $(document).on('click', '.impulse-qr-remove-btn', function(e) {
            e.stopPropagation();
            e.preventDefault();
            var $btn = $(e.target).closest('.impulse-qr-remove-btn');
            var index = parseInt($btn.data('index'), 10);
            if (isNaN(index)) return;
            $btn.prop('disabled', true).css('opacity', '0.5');
            $.post(ajaxurl, {
                action: 'instinctor_chat_delete_quick_action',
                index: index,
                nonce: chatNonce
            }, function(response) {
                if (response.success) {
                    renderQuickReplies(response.data.quick_actions || []);
                } else {
                    $btn.prop('disabled', false).css('opacity', '');
                }
            }).fail(function() {
                $btn.prop('disabled', false).css('opacity', '');
            });
        });
        
        
        $(document).on('dragstart', '.impulse-chat-quick-reply', function(e) {
            if ($(e.target).is('.impulse-qr-text') || $(e.target).closest('.impulse-qr-text').length) {
                e.preventDefault(); return;
            }
            dragSrcIndex = $(this).data('index');
            $(this).addClass('impulse-qr-dragging');
            e.originalEvent.dataTransfer.effectAllowed = 'move';
            
            e.originalEvent.dataTransfer.setData('text/plain', String(dragSrcIndex));
        });
        $(document).on('dragend', '.impulse-chat-quick-reply', function() {
            $(this).removeClass('impulse-qr-dragging');
            $('.impulse-chat-quick-reply').removeClass('impulse-qr-drag-over');
        });
        $(document).on('dragover', '.impulse-chat-quick-reply', function(e) {
            e.preventDefault();
            e.originalEvent.dataTransfer.dropEffect = 'move';
            $('.impulse-chat-quick-reply').removeClass('impulse-qr-drag-over');
            $(this).addClass('impulse-qr-drag-over');
        });
        $(document).on('dragleave', '.impulse-chat-quick-reply', function() {
            $(this).removeClass('impulse-qr-drag-over');
        });
        $(document).on('drop', '.impulse-chat-quick-reply', function(e) {
            e.preventDefault();
            e.stopPropagation();
            var targetIndex = $(this).data('index');
            if (dragSrcIndex === null || dragSrcIndex === targetIndex) return;
            
            var replies = [];
            $('#impulse-chat-quick-replies .impulse-chat-quick-reply').each(function() {
                replies.push($(this).data('message'));
            });
            
            var moved = replies.splice(dragSrcIndex, 1)[0];
            replies.splice(targetIndex, 0, moved);
            dragSrcIndex = null;
            
            $.post(ajaxurl, {
                action: 'instinctor_chat_save_quick_actions',
                quick_actions: replies,
                nonce: chatNonce
            }, function(response) {
                if (response.success) renderQuickReplies(response.data.quick_actions);
            });
        });

        
        $(document).on('click', '.impulse-chat-note-btn', function(e) {
            e.stopPropagation();
            var convId = $(this).data('id');
            var $card  = $('.impulse-chat-conv-item[data-id="' + convId + '"]');
            var $existing = $card.next('.impulse-chat-note-panel');

            if ($existing.length) {
                $existing.remove();
                return;
            }

            
            $('.impulse-chat-note-panel').remove();

            var $panel = $('<div class="impulse-chat-note-panel">' +
                '<textarea placeholder="Admin note — internal only, not visible to visitors..." rows="3"></textarea>' +
                '<div class="impulse-chat-note-panel-footer">' +
                '<button type="button" class="impulse-btn-sm" style="height:22px;padding:0 10px;font-size:10px">Save</button>' +
                '</div></div>');

            $card.after($panel);
            var $ta = $panel.find('textarea').focus();

            
            $.post(ajaxurl, {
                action: 'instinctor_chat_get_visitor_note',
                conversation_id: convId,
                nonce: chatNonce
            }, function(r) {
                if (r.success && r.data.note) $ta.val(r.data.note);
            });

            
            $panel.find('button').on('click', function() {
                var note = $ta.val().trim();
                var $btn = $(this).prop('disabled', true).text('…');
                $.post(ajaxurl, {
                    action: 'instinctor_chat_save_visitor_note',
                    conversation_id: convId,
                    note: note,
                    nonce: chatNonce
                }, function(r) {
                    $btn.prop('disabled', false).text('Save');
                    if (r.success) {
                        var hasNote = note.length > 0;
                        $card.find('.impulse-chat-note-btn').toggleClass('has-note', hasNote).attr('title', hasNote ? 'Edit note' : 'Add note');
                        $panel.remove();
                        window.showToast(hasNote ? 'Note saved' : 'Note cleared');
                    } else {
                        window.showToast(r.data || 'Failed to save note', 'error');
                    }
                }).fail(function() {
                    $btn.prop('disabled', false).text('Save');
                    window.showToast('Network error', 'error');
                });
            });
        });

        
        $(document).on('click.notepanel', function(e) {
            if (!$(e.target).closest('.impulse-chat-note-panel, .impulse-chat-note-btn').length) {
                $('.impulse-chat-note-panel').remove();
            }
        });
        
        
        $('#impulse-chat-new-quick-reply').one('focus', function() {
            $(this).removeAttr('readonly');
        });
        $('#impulse-chat-add-quick-reply').on('click', addQuickReply);
        $('#impulse-chat-new-quick-reply').on('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                addQuickReply();
            }
        });
        

        $(document).on('click', '.impulse-chat-left-tab', function() {
            var tab = $(this).data('left-tab');
            $('.impulse-chat-left-tab').removeClass('active');
            $(this).addClass('active');
            $('.impulse-chat-left-pane').hide();
            $('#impulse-chat-pane-' + tab).show();
            if (tab === 'history') {
                var hasItems = $('#impulse-chat-closed-conversations .impulse-chat-conv-item').length > 0;
                loadClosedConversations(!hasItems);
            }
        });

        $('#impulse-chat-close-conv').on('click', closeConversation);
        
        

        $('#impulse-chat-delete-conv').on('click', deleteConversation);
        

        $('#impulse-chat-close-all').on('click', closeAllConversations);
        $('#impulse-chat-delete-all').on('click', deleteAllConversations);
        

        
        var $chatToggle = $('#impulse-chat-toggle');
        var chatIsOn = $chatToggle.data('enabled') == '1';
        $chatToggle.toggleClass('chat-toggle-on', chatIsOn).toggleClass('chat-toggle-off', !chatIsOn);
        
        
        initSettingsAutoSave();
        

        
        


        

        
        $(document).on('mouseenter', '.impulse-tooltip-wrap', function() {
            $(this).find('.impulse-tooltip').show();
        }).on('mouseleave', '.impulse-tooltip-wrap', function() {
            $(this).find('.impulse-tooltip').hide();
        });
        
        
        
        startListPolling();
    }
    
    
    $(document).on('click', '.impulse-chat-history-item', function() {
        var histId = $(this).data('hist-id');
        openHistoryOverlay(histId);
    });
    
    function openHistoryOverlay(convId) {
        $.post(ajaxurl, {
            action: 'instinctor_chat_get_conversation',
            conversation_id: convId,
            nonce: chatNonce
        }, function(response) {
            if (!response.success) return;
            var conv = response.data.conversation;
            var messages = response.data.messages || [];
            
            var date = conv && conv.created_at ? formatTime(conv.created_at) : '';
            var titleText = (conv && conv.visitor_name ? escapeHtml(conv.visitor_name) + ' — ' : '') + date;
            
            var lockSvg = '<svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><\/svg>';
            var backSvg = '<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/><\/svg>';
            
            var visitorBubble = window.Impulse.chat.settings.color_visitor_bubble || '#3a3f44';
            var agentBubble   = window.Impulse.chat.settings.color_agent_bubble   || '#f0f0f0';
            
            var msgsHtml = '';
            messages.forEach(function(msg) {
                var senderType = msg.sender || msg.sender_type;
                var isNote = msg.is_note == 1;
                if (isNote) {
                    msgsHtml += '<div class="impulse-chat-message note"><div class="impulse-chat-message-bubble">' + lockSvg + '<span>' + escapeHtml(msg.message) + '<\/span><\/div></div>';
                    return;
                }
                var messageText = (msg.message || '').replace(/^\[Via (sms|whatsapp)\]\s*/i, '');
                var imageMatch  = messageText.match(/\[image\](.*?)\[\/image\]/);
                var fileMatch   = messageText.match(/\[file\](.*?)\|(.*?)\[\/file\]/);
                var messageContent;
                if (imageMatch) {
                    messageContent = '<img src="' + imageMatch[1] + '" style="max-width:200px;border-radius:6px;cursor:pointer;display:block;" onclick="window.open(this.src)">';
                } else if (fileMatch) {
                    messageContent = '<a href="' + fileMatch[1] + '" target="_blank" style="color:inherit;text-decoration:none;">' + escapeHtml(fileMatch[2]) + '<\/a>';
                } else {
                    messageContent = escapeHtml(messageText);
                }
                var bubbleColor = senderType === 'visitor' ? visitorBubble : agentBubble;
                var textColor   = getContrastColor(bubbleColor);
                msgsHtml += '<div class="impulse-chat-message ' + senderType + '">' +
                    '<div class="impulse-chat-message-bubble" style="background:' + bubbleColor + ';color:' + textColor + '">' +
                    messageContent + '<\/div><\/div>';
            });
            
            var overlay = '<div class="impulse-chat-history-overlay" id="impulse-history-overlay">' +
                '<div class="impulse-chat-history-overlay-header">' +
                '<button class="impulse-chat-history-back" id="impulse-history-back">' + backSvg + '<\/button>' +
                '<span class="impulse-chat-history-overlay-title">' + titleText + '<\/span>' +
                '<\/div>' +
                '<div class="impulse-chat-history-overlay-messages" id="impulse-history-messages">' +
                msgsHtml +
                '<\/div><\/div>';
            
            $('.impulse-chat-right-content').append(overlay);
            var $msgs = $('#impulse-history-messages');
            $msgs.scrollTop($msgs[0].scrollHeight);
        });
    }
    
    $(document).on('click', '#impulse-history-back', function() {
        $('#impulse-history-overlay').remove();
    });
    

    function openConversation(id) {
        currentConvId = id;

        
        var $ta = $('#impulse-chat-reply-input');
        
        $('.impulse-chat-conv-item').removeClass('active');
        $('.impulse-chat-conv-item[data-id="' + id + '"]').addClass('active').removeClass('unread');
        
        $('#impulse-chat-no-selection').hide();
        $('#impulse-chat-active').show();
        $('#impulse-chat-typing-row').hide();
        $('#impulse-chat-slash-menu').hide();
        $('#impulse-history-overlay').remove();
        
        
        $('#impulse-chat-reply-input').attr('placeholder', 'Type your reply...');
        $('#impulse-chat-send-reply').text('Send');
        
        
        var draft = '';
        try { draft = localStorage.getItem('instinctor_chat_draft_' + id) || ''; } catch(e) {}
        $ta.val(draft);
        
        
        loadConversation(id);
        startPolling();
    }
    
    function loadConversation(id) {
        $.post(ajaxurl, {
            action: 'instinctor_chat_get_conversation',
            conversation_id: id,
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                currentConv = response.data.conversation;

                if (currentConv.status === 'closed') {
                    var $activeItem = $('#impulse-chat-conversations .impulse-chat-conv-item[data-id="' + id + '"]');
                    if ($activeItem.length) {
                        moveConvItemToHistory(id);
                        deselectConversation();
                        window.showToast('Conversation closed');
                        return;
                    }
                }
                renderConversation(response.data.conversation, response.data.messages);
                
                if (response.data.visitor_is_typing) {
                    $('#impulse-chat-typing-row').show();
                } else {
                    $('#impulse-chat-typing-row').hide();
                }
            }
        });
    }
    
    function renderConversation(conv, messages) {
        
        $('#impulse-chat-visitor-name').text(conv.visitor_name || 'Visitor');
        $('#impulse-chat-visitor-status').text(conv.status)
            .removeClass('status-active status-closed')
            .addClass('status-' + conv.status);
        
        
        var email = conv.visitor_email || '';
        var phone = conv.visitor_phone || '';
        $('#impulse-chat-info-email').text(email);
        $('#impulse-chat-info-phone').text(phone);
        $('#impulse-chat-info-row-email').toggle(email !== '');
        $('#impulse-chat-info-row-phone').toggle(phone !== '');
        
        
        var $pageRow = $('#impulse-chat-visitor-page');
        if (conv.page_url) {
            var displayUrl = conv.page_url.replace(/^https?:\/\/[^\/]+/, '').replace(/\/$/, '') || '/';
            if (displayUrl.length > 50) displayUrl = displayUrl.substring(0, 47) + '...';
            $pageRow.html('<a href="' + escapeHtml(conv.page_url) + '" target="_blank" title="' + escapeHtml(conv.page_url) + '">' + escapeHtml(displayUrl) + '<\/a>');
            $pageRow.show();
        } else {
            $pageRow.hide();
        }
        
        
        renderCart(conv.cart_data);

        
        renderClaimBar(conv);

        
        renderMessages(messages);

        
        renderInstAgentPanel(conv);
    }

    function renderClaimBar(conv) {
        var $bar      = $('#impulse-chat-claim-bar');
        var $label    = $('#impulse-chat-claim-label');
        var $claim    = $('#impulse-chat-btn-claim');
        var $takeover = $('#impulse-chat-btn-takeover');
        var $release  = $('#impulse-chat-btn-release');

        var meId      = window.Impulse && window.Impulse.chat ? parseInt(window.Impulse.chat.currentUserId || 0) : 0;
        var ownerId   = conv.assigned_agent_id ? parseInt(conv.assigned_agent_id) : 0;
        var ownerName = conv.assigned_agent_name || '';

        $bar.show().removeClass('mine other unclaimed');
        $claim.hide(); $takeover.hide(); $release.hide();

        if (!ownerId) {
            $bar.addClass('unclaimed');
            $label.text('Unassigned — Smart chat may be responding');
            $claim.show();
        } else if (ownerId === meId) {
            $bar.addClass('mine');
            $label.text('You are handling this conversation');
            $release.show();
        } else {
            $bar.addClass('other');
            $label.text('Assigned to ' + (ownerName || 'another agent'));
            $takeover.show();
        }
    }

    function sendClaim(claimAction) {
        if (!currentConvId) return;
        $.post(ajaxurl, {
            action: 'instinctor_chat_claim',
            conversation_id: currentConvId,
            claim_action: claimAction,
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                if (currentConv) {
                    currentConv.assigned_agent_id   = response.data.assigned_agent_id;
                    currentConv.assigned_agent_name = response.data.assigned_agent_name;
                    renderClaimBar(currentConv);
                }
                window.showToast(claimAction === 'release' ? 'Conversation released' : 'Conversation claimed');
            } else {
                window.showToast(response.data || 'Failed', 'error');
            }
        });
    }
    
    function renderInstAgentPanel(conv) {
        var aiEnabled = $('#impulse-chat-ai_enabled').is(':checked');
        var $panel    = $('#impulse-instagent-panel');
        var $body     = $('#impulse-instagent-body');
        var $badge    = $('#impulse-instagent-status-badge');

        if (!aiEnabled) {
            $panel.hide();
            return;
        }

        $panel.show();

        
        var hs = conv.handoff_status || '';
        if (hs === 'pending' || hs === 'followup_sent') {
            $badge.text('Handoff').removeClass('active inactive').addClass('handoff');
        } else if (conv.assigned_agent_id) {
            $badge.text('Standby').removeClass('active handoff').addClass('inactive');
        } else {
            $badge.text('Active').removeClass('inactive handoff').addClass('active');
        }

        
        var rows = [];

        var email = conv.visitor_email || '';
        var name  = conv.visitor_name  || '';

        if (name)  rows.push(['Customer', escapeHtml(name)]);
        if (email) rows.push(['Email', escapeHtml(email)]);

        
        var orderCount   = parseInt(conv.order_count   || 0);
        var totalSpent   = parseFloat(conv.total_spent  || 0);
        var lastOrderStatus = conv.last_order_status || '';
        var lastOrderNum    = conv.last_order_number || '';

        if (email) {
            rows.push(['divider']);
            if (orderCount > 0) {
                rows.push(['Orders', orderCount]);
                rows.push(['Lifetime spend', '$' + totalSpent.toFixed(2)]);
            }
            if (lastOrderNum) {
                rows.push(['Last order', '#' + lastOrderNum + (lastOrderStatus ? ' (' + lastOrderStatus + ')' : '')]);
            }
            if (orderCount === 0 && !lastOrderNum) {
                rows.push(['Store data', email ? 'Will load on smart chat reply' : 'No email — data unavailable']);
            }
        } else {
            rows.push(['Store data', 'No email collected yet']);
        }

        var html = '';
        rows.forEach(function(r) {
            if (r[0] === 'divider') {
                html += '<div class="impulse-instagent-divider"></div>';
            } else {
                html += '<div class="impulse-instagent-row">'
                      + '<span class="impulse-instagent-label">' + r[0] + '</span>'
                      + '<span class="impulse-instagent-value">' + r[1] + '</span>'
                      + '</div>';
            }
        });

        $body.html(html || '<span class="impulse-instagent-empty">No data.</span>');
    }

    function renderCart(cartJson) {
        var $container = $('#impulse-chat-info-cart');
        var $row = $('#impulse-chat-info-row-cart');
        
        if (!cartJson) {
            $row.hide();
            $container.text('');
            updateVisitorInfoVisibility();
            return;
        }
        
        try {
            var cart = typeof cartJson === 'string' ? JSON.parse(cartJson) : cartJson;
            
            if (!cart.items || cart.items.length === 0) {
                $row.hide();
                $container.text('');
                updateVisitorInfoVisibility();
                return;
            }
            
            var parts = cart.items.map(function(item) {
                return item.qty + '× ' + escapeHtml(item.name);
            });
            var total = cart.total_formatted || ('$' + parseFloat(cart.total || 0).toFixed(2));
            $container.text(parts.join(', ') + ' — ' + total);
            $row.show();
        } catch (e) {
            $row.hide();
        }
        updateVisitorInfoVisibility();
    }
    
    function updateVisitorInfoVisibility() {
        var hasAny = $('#impulse-chat-info-row-email:visible, #impulse-chat-info-row-phone:visible, #impulse-chat-info-row-cart:visible').length > 0;
        $('#impulse-chat-visitor-info').toggle(hasAny);
    }
    
    function renderMessages(messages) {
        var lockSvg = '<svg class="impulse-chat-note-icon" viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><\/svg>';
        var visitorBubble = window.Impulse.chat.settings.color_visitor_bubble || '#3a3f44';
        var agentBubble   = window.Impulse.chat.settings.color_agent_bubble   || '#f0f0f0';
        var html = '';

        
        var senders = messages.map(function(m) {
            var isNote = m.is_note == 1 || m.is_note === '1' || m.is_note === true;
            return isNote ? null : (m.sender || m.sender_type);
        });

        messages.forEach(function(msg, i) {
            var time = formatTime(msg.created_at);
            var senderType = msg.sender || msg.sender_type;
            var isNote = msg.is_note == 1 || msg.is_note === '1' || msg.is_note === true;
            if (isNote) {
                html += '<div class="impulse-chat-message note">' +
                    '<div class="impulse-chat-message-bubble">' + lockSvg + '<span>' + escapeHtml(msg.message) + '<\/span><\/div>' +
                    '<div class="impulse-chat-message-meta"><span class="impulse-chat-note-label">Note<\/span><span>' + time + '<\/span><\/div><\/div>';
                return;
            }
            var groupClass = '';
            if (senders[i - 1] === senderType) groupClass += ' grouped-above';
            if (senders[i + 1] === senderType) groupClass += ' grouped-below';

            var isViaSms = msg.message.indexOf('[Via sms]') === 0 || msg.message.indexOf('[Via whatsapp]') === 0;
            var messageText = msg.message.replace(/^\[Via (sms|whatsapp)\]\s*/i, '');
            var imageMatch = messageText.match(/\[image\](.*?)\[\/image\]/);
            var fileMatch  = messageText.match(/\[file\](.*?)\|(.*?)\[\/file\]/);
            var messageContent = '';
            if (imageMatch) {
                messageContent = '<img src="' + imageMatch[1] + '" style="max-width:200px;border-radius:6px;cursor:pointer;" onclick="window.open(this.src)">';
            } else if (fileMatch) {
                messageContent = '<a href="' + fileMatch[1] + '" target="_blank" style="color:inherit;text-decoration:none;">' + escapeHtml(fileMatch[2]) + '<\/a>';
            } else {
                messageContent = escapeHtml(messageText);
            }
            var bubbleColor = senderType === 'visitor' ? visitorBubble : agentBubble;
            var textColor   = getContrastColor(bubbleColor);
            html += '<div class="impulse-chat-message ' + senderType + groupClass + '">' +
                '<div class="impulse-chat-message-bubble" style="background:' + bubbleColor + ';color:' + textColor + '">' +
                messageContent + '<\/div>' +
                '<div class="impulse-chat-message-meta">' +
                (isViaSms ? '<span class="impulse-chat-via-badge">' + (msg.message.match(/\[Via (\w+)\]/i)?.[1] || 'SMS') + '<\/span>' : '') +
                '<span>' + time + '<\/span><\/div><\/div>';
        });
        var $container = $('#impulse-chat-messages');
        $container.html(html);
        $container.scrollTop($container[0].scrollHeight);
    }
    
    function sendReply() {
        var message = $('#impulse-chat-reply-input').val().trim();
        if (!message || !currentConvId) return;
        
        var $btn = $('#impulse-chat-send-reply');
        $btn.prop('disabled', true).text('Sending...');
        
        $.post(ajaxurl, {
            action: 'instinctor_chat_admin_reply',
            conversation_id: currentConvId,
            message: message,
            nonce: chatNonce
        }, function(response) {
            $btn.prop('disabled', false).text('Send');
            
            if (response.success) {
                $('#impulse-chat-reply-input').val('');
                try { localStorage.removeItem('instinctor_chat_draft_' + currentConvId); } catch(e) {}
                loadConversation(currentConvId);
            } else {
                window.showToast(response.data || 'Failed to send', 'error');
            }
        }).fail(function() {
            $btn.prop('disabled', false).text('Send');
            window.showToast('Network error', 'error');
        });
    }
    
    
    $(document).on('click', '#impulse-chat-btn-claim',    function() { sendClaim('claim'); });
    $(document).on('click', '#impulse-chat-btn-takeover', function() { sendClaim('takeover'); });
    $(document).on('click', '#impulse-chat-btn-release',  function() { sendClaim('release'); });

    function addQuickReply() {
        var message = $('#impulse-chat-new-quick-reply').val().trim();
        if (!message) return;
        $.post(ajaxurl, {
            action: 'instinctor_chat_add_quick_action',
            message: message,
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                $('#impulse-chat-new-quick-reply').val('');
                renderQuickReplies(response.data.quick_actions);
            }
        });
    }
    
    var dragSrcIndex = null;
    
    function renderQuickReplies(replies) {
        var gripIcon  = '<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 5h16"/><path d="M4 12h16"/><path d="M4 19h16"/></svg>';
        var closeIcon = '<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>';

        var html = '';
        replies.forEach(function(r, i) {
            var text = (typeof r === 'string') ? r : (r.text || r);
            html += '<div class="impulse-chat-quick-reply" data-index="' + i + '" data-message="' + escapeHtml(text) + '" draggable="true">' +
                    '<span class="impulse-qr-drag" title="Drag to reorder">' + gripIcon + '</span>' +
                    '<span class="impulse-qr-text" spellcheck="false">' + escapeHtml(text) + '</span>' +
                    '<button type="button" class="impulse-qr-remove-btn" data-index="' + i + '" title="Remove">' + closeIcon + '</button>' +
                    '</div>';
        });
        $('#impulse-chat-quick-replies').html(html);

        if ($('#impulse-chat-slash-menu').is(':visible')) {
            renderSlashItems($('#impulse-chat-slash-input').val());
        }
    }
    
    
    var _slashReplies = []; 
    
    function openSlashMenu(filter) {
        _slashReplies = [];
        $('#impulse-chat-quick-replies .impulse-chat-quick-reply').each(function() {
            _slashReplies.push($(this).data('message'));
        });
        if (_slashReplies.length === 0) return;
        renderSlashItems(filter);
        $('#impulse-chat-slash-menu').show();
        $('#impulse-chat-slash-input').val(filter);
    }

    function closeSlashMenu() {
        $('#impulse-chat-slash-menu').hide();
        $('#impulse-chat-slash-input').val('');
    }

    function renderSlashItems(filter) {
        var q = (filter || '').toLowerCase().trim();
        var filtered = q
            ? _slashReplies.filter(function(t) { return t.toLowerCase().indexOf(q) >= 0; })
            : _slashReplies;

        if (filtered.length === 0) {
            $('#impulse-chat-slash-list').html('<div class="impulse-chat-slash-empty">No replies match</div>');
            return;
        }

        var html = '';
        filtered.forEach(function(text) {
            html += '<div class="impulse-chat-slash-item" data-message="' + escapeHtml(text) + '">' + escapeHtml(text) + '</div>';
        });

        var $list = $('#impulse-chat-slash-list');
        $list.html(html);
        $list.find('.impulse-chat-slash-item').first().addClass('active');
    }
    
    function deselectConversation() {
        stopPolling();
        $('.impulse-chat-conv-item').removeClass('active');
        currentConvId = null;
        currentConv = null;
        $('#impulse-chat-active').hide();
        $('#impulse-chat-no-selection').show();
    }

    function closeConversation() {
        if (!currentConvId) return;

        var closingId = currentConvId;


        $.post(ajaxurl, {
            action: 'instinctor_chat_close',
            conversation_id: closingId,
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                moveConvItemToHistory(closingId);
                deselectConversation();
                window.showToast('Conversation closed');
            }
        });
    }

    function moveConvItemToHistory(convId) {
        var $item = $('.impulse-chat-conv-item[data-id="' + convId + '"]').first();
        if (!$item.length) return;
        
        var name    = $item.find('.impulse-chat-conv-name').text().trim();
        var preview = $item.find('.impulse-chat-conv-preview').text().trim();
        var historyHtml = '<div class="impulse-chat-conv-item closed" data-id="' + convId + '">' +
            '<div class="impulse-chat-conv-info">' +
            '<div class="impulse-chat-conv-name">' + escapeHtml(name) + '</div>' +
            '<div class="impulse-chat-conv-preview">' + escapeHtml(preview) + '</div>' +
            '</div></div>';
        var $history = $('#impulse-chat-closed-conversations');
        $history.find('.impulse-chat-empty-state').remove();
        $history.prepend(historyHtml);
        $item.remove();
        
        if ($('#impulse-chat-conversations .impulse-chat-conv-item').length === 0) {
            $('#impulse-chat-conversations').html('<div class="impulse-chat-empty-state"><svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><p>No conversations</p></div>');
        }
        
        $('.impulse-chat-left-tab').removeClass('active');
        $('.impulse-chat-left-tab[data-left-tab="history"]').addClass('active');
        $('.impulse-chat-left-pane').hide();
        $('#impulse-chat-pane-history').show();
    }
    
    

    function deleteConversation() {
        if (!currentConvId) return;
        
        
        $.post(ajaxurl, {
            action: 'instinctor_chat_delete',
            conversation_id: currentConvId,
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                $('.impulse-chat-conv-item[data-id="' + currentConvId + '"]').remove();
                if ($('#impulse-chat-conversations .impulse-chat-conv-item').length === 0) {
                    $('#impulse-chat-conversations').html('<div class="impulse-chat-empty-state"><svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><p>No conversations</p></div>');
                }
                deselectConversation();
                window.showToast('Conversation deleted');
            }
        });
    }
    
    function closeAllConversations() {
        $.post(ajaxurl, {
            action: 'instinctor_chat_close_all',
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                
                $('#impulse-chat-conversations .impulse-chat-conv-item').each(function() {
                    moveConvItemToHistory($(this).data('id'));
                });
                deselectConversation();
                window.showToast('All conversations closed');
            }
        });
    }
    
    function deleteAllConversations() {
        $.post(ajaxurl, {
            action: 'instinctor_chat_delete_all',
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                $('#impulse-chat-conversations').html('<div class="impulse-chat-empty-state"><svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><p>No conversations</p></div>');
                deselectConversation();
                window.showToast('All conversations deleted');
            }
        });
    }
    
    function toggleChatEnabled() {
        var $btn = $('#impulse-chat-toggle');
        var isEnabled = $btn.data('enabled') === 1 || $btn.data('enabled') === '1';
        var newValue = isEnabled ? '0' : '1';
        
        var url = (window.Impulse && window.Impulse.chat && window.Impulse.chat.ajaxurl)
            ? window.Impulse.chat.ajaxurl
            : (window.ajaxurl || '/wp-admin/admin-ajax.php');
        var nonce = (window.Impulse && window.Impulse.chat && window.Impulse.chat.nonce)
            ? window.Impulse.chat.nonce
            : '';
        
        if (!nonce) {
            window.showToast && window.showToast('Chat nonce not available — please reload the page.', 'error');
            return;
        }
        
        $btn.prop('disabled', true);
        
        $.post(url, {
            action: 'instinctor_chat_toggle_enabled',
            nonce: nonce,
            enabled: newValue
        }, function(response) {
            if (response && response.success) {
                var on = newValue === '1';
                $btn.data('enabled', newValue).text(on ? 'Chat Enabled' : 'Chat Disabled');
                $btn.toggleClass('chat-toggle-on', on).toggleClass('chat-toggle-off', !on);
                if (window.Impulse && window.Impulse.chat && window.Impulse.chat.settings) {
                    window.Impulse.chat.settings.enabled = newValue;
                }
                
                if (on) {
                    if ($('#impulse-chat-toggle-footer').css('display') !== 'none') {
                        
                    } else {
                        showPageSettings && showPageSettings();
                    }
                } else {
                    $('#impulse-chat-toggle-footer').hide();
                }
                showSaveStatus('Saved');
            } else {
                window.showToast && window.showToast('Chat toggle failed.', 'error');
                console.error('Chat toggle failed - success:', response && response.success, '| data:', response && response.data, '| full:', JSON.stringify(response));
            }
        }).fail(function(xhr, status, error) {
            window.showToast && window.showToast('Chat toggle AJAX error.', 'error');
            console.error('Chat toggle AJAX error:', xhr.responseText);
        }).always(function() {
            $btn.prop('disabled', false);
        });
    }

    
    $(document).ready(function() {
        $(document).on('click', '#impulse-chat-toggle', toggleChatEnabled);
        
        var $btn = $('#impulse-chat-toggle');
        var on = $btn.data('enabled') == '1';
        $btn.toggleClass('chat-toggle-on', on).toggleClass('chat-toggle-off', !on);

        

    });
    
    function initSettingsAutoSave() {
        
        $('.impulse-chat-right input[type="text"], .impulse-chat-right input[type="email"], .impulse-chat-right input[type="tel"], .impulse-chat-right textarea').on('input', function() {
            debouncedSaveSettings();
        });
        
        
        
        $('.impulse-chat-right input[type="checkbox"]').on('change', function() {
            saveSettings();
            if ($(this).is('#impulse-chat-screenshots, #impulse-chat-attachments')) {
                
            }
        });
        

        

        
        $(document).off('input.chatcolor change.chatcolor').on('input.chatcolor change.chatcolor', '.impulse-chat-color-cell input[type="hidden"], #impulse-chat-color_button, #impulse-chat-color_header, #settings-chat-panel input.impulse-color-text', function() {

            

            

            
            var id = $(this).attr('id') || $(this).attr('name') || '';
            var val = $(this).val();
            console.log('[chat-autosave] handler fired', { id: id, val: val });
            debouncedSaveSettings();
            console.log('[chat-autosave] debouncedSave queued');

            
            try {
                var iframe = document.getElementById('impulse-iframe');
                console.log('[chat-autosave] iframe found?', !!iframe, 'contentWindow?', !!(iframe && iframe.contentWindow));
                if (iframe && iframe.contentWindow) {
                    iframe.contentWindow.postMessage({
                        type: 'instinctor-chat-config-changed',
                        color: { id: id, value: val }
                    }, '*');
                    console.log('[chat-autosave] postMessage sent');
                }
            } catch(_e) {
                console.log('[chat-autosave] postMessage threw', _e);
            }
        });
        

        function initChatColorPickers() {
            
            $('.impulse-chat-right .impulse-color-row').each(function() {
                var $row = $(this);
                if ($row.find('.impulse-color-picker').length) return; 
                
                var $swatch = $row.find('.impulse-color-swatch');
                var $input = $row.find('input.impulse-color-text');
                var value = $input.val() || '#000000';
                
                
                var r = parseInt(value.substr(1,2), 16) || 0;
                var g = parseInt(value.substr(3,2), 16) || 0;
                var b = parseInt(value.substr(5,2), 16) || 0;
                var hexVal = value;
                
                
                var max = Math.max(r, g, b), min = Math.min(r, g, b);
                var h = 0, s = 0, v = max / 255;
                var d = max - min;
                s = max === 0 ? 0 : d / max;
                if (max !== min) {
                    switch (max) {
                        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                        case g: h = (b - r) / d + 2; break;
                        case b: h = (r - g) / d + 4; break;
                    }
                    h /= 6;
                }
                var hue = Math.round(h * 360);
                var sat = Math.round(s * 100);
                var val = Math.round(v * 100);
                var hueColor = 'hsl('+hue+',100%,50%)';
                var alphaGradient = 'linear-gradient(to right, transparent, '+hexVal+')';
                
                
                var picker = '<div class="impulse-color-picker" data-hue="'+hue+'" data-sat="'+sat+'" data-val="'+val+'" data-alpha="100">';
                picker += '<div class="impulse-picker-gradient" style="background-color:'+hueColor+'">';
                picker += '<div class="impulse-picker-cursor" style="left:'+sat+'%;top:'+(100-val)+'%"></div>';
                picker += '</div>';
                picker += '<div class="impulse-picker-sliders">';
                picker += '<div class="impulse-picker-slider-row">';
                picker += '<div class="impulse-picker-hue"><div class="impulse-picker-thumb" style="left:'+((hue/360)*100)+'%"></div></div></div>';
                picker += '<div class="impulse-picker-slider-row">';
                picker += '<div class="impulse-picker-alpha" style="--alpha-gradient:'+alphaGradient+'"><div class="impulse-picker-thumb" style="left:100%"></div></div></div>';
                picker += '</div>';
                picker += '<div class="impulse-picker-tools">';
                picker += '<div class="impulse-picker-hex"><input type="text" value="' + hexVal + '" placeholder="#000000"></div>';
                picker += '<button type="button" class="impulse-picker-eyedropper" title="Pick from screen"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m2 22 1-1h3l9-9"/><path d="M3 21v-3l9-9"/><path d="m15 6 3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l.4.4a2.1 2.1 0 1 1-3 3l-3.8-3.8a2.1 2.1 0 1 1 3-3l.4.4Z"/></svg></button>';
                picker += '</div></div>';
                
                
                $swatch.after(picker);
            });
        }
        
        
        initChatColorPickers();
        
        
        $(document).on('impulse:workspace:chat', initChatColorPickers);
        
        
        $('.impulse-chat-right input[type="range"]').on('input', function() {
            impulseSliderTrack(this);
            var suffix = '';
            if (this.name === 'widget_height') suffix = 'px';
            var $valueSpan = $(this).closest('.impulse-setting-row, .impulse-slider-row, .impulse-slider-with-unit').find('.impulse-slider-value');
            if ($valueSpan.length) {
                $valueSpan.text(this.value + suffix);
            } else {
                $(this).closest('.impulse-slider-compact').find('span').text(this.value + suffix);
            }
            debouncedSaveSettings();
        });
    }
    
    function debouncedSaveSettings() {
        clearTimeout(saveTimeout);
        saveTimeout = setTimeout(saveSettings, 500);
    }
    
    function saveSettings() {
        showSaveStatus('Saving...');
        var _nonce = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.nonce : '';
        var _ajax = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.ajaxurl : (window.ajaxurl || '');
        
        $.post(_ajax, {
            action: 'instinctor_chat_save_settings',
            nonce: _nonce,
            enabled: $('#impulse-chat-toggle').data('enabled') == '1' ? '1' : '0',
            title: $('#impulse-chat-title').val(),
            greeting: $('#impulse-chat-greeting').val(),
            online_text: $('#impulse-chat-online_text').val(),
            position: $('#impulse-chat-position').val(),
            avatar: $('#impulse-chat-avatar').val(),
            show_online: $('#impulse-chat-show_online').is(':checked') ? '1' : '0',
            sound_enabled: $('#impulse-chat-sound_enabled').is(':checked') ? '1' : '0',
            screenshots: $('#impulse-chat-screenshots').is(':checked') ? '1' : '0',
            attachments: $('#impulse-chat-attachments').is(':checked') ? '1' : '0',
            widget_height: $('#impulse-chat-widget_height').val(),
            bubble_opacity: $('#impulse-chat-bubble_opacity').val(),
            color_button: $('#impulse-chat-color_button').val(),
            color_input_border: $('#impulse-chat-color_input_border').val(),
            input_border_width: $('#impulse-chat-input_border_width').val(),
            collect_name: $('#impulse-chat-collect_name').is(':checked') ? '1' : '0',
            collect_email: $('#impulse-chat-collect_email').is(':checked') ? '1' : '0',
            collect_phone: $('#impulse-chat-collect_phone').is(':checked') ? '1' : '0',
            email_address: $('#impulse-chat-email_address').val(),
            email_include_cart: $('#impulse-chat-email_include_cart').is(':checked') ? '1' : '0',
            sms_number: $('#impulse-chat-sms_number').val(),
            whatsapp_number: $('#impulse-chat-whatsapp_number').val(),
            ai_enabled: $('#impulse-chat-ai_enabled').is(':checked') ? '1' : '0',
            ai_store_info: $('#impulse-ai-store-info').val() || '',
            ai_tone: 'friendly',
            handoff_timeout: $('#impulse-ai-handoff-timeout').val() || '5',
            handoff_message: $('#impulse-ai-handoff-msg').val() || '',
            chat_greeting_text:  $('#impulse-chat-greeting_text').val() || '',
            chat_greeting_color: $('#impulse-chat-greeting_color').val() || '#ffffff'
        }, function(response) {
            showSaveStatus(response.success ? 'Saved' : 'Error');
        }).fail(function() {
            showSaveStatus('Error');
        });
    }
    

    function testEmail() {
        var $btn = $('#impulse-chat-test-email');
        var email = $('#impulse-chat-email_address').val();
        var _nonce = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.nonce : '';
        var _ajax = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.ajaxurl : (window.ajaxurl || '');

        if (!email) {
            window.showToast('Please enter an email address', 'error');
            return;
        }
        $btn.prop('disabled', true).text('Sending...');
        $.post(_ajax, {
            action: 'instinctor_chat_test_notification',
            nonce: _nonce,
            channel: 'email',
            to: email
        }, function(response) {
            $btn.prop('disabled', false).text('Test');
            if (response.success) {
                window.showToast('Test email sent to ' + email, 'success');
            } else {
                var err = (response.data && typeof response.data === 'object') ? (response.data.error || response.data.message || JSON.stringify(response.data)) : (response.data || 'Unknown error');
                window.showToast('Email failed: ' + err, 'error');
            }
        }).fail(function(xhr, status, error) {
            $btn.prop('disabled', false).text('Test');
            window.showToast('Request failed: ' + error, 'error');
        });
    }

    function testSms() {
        var $btn = $('#impulse-chat-test-sms');
        var number = $('#impulse-chat-sms_number').val();
        var _nonce = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.nonce : '';
        var _ajax = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.ajaxurl : (window.ajaxurl || '');
        if (!number) {
            window.showToast('Please enter an SMS number', 'error');
            return;
        }
        $btn.prop('disabled', true).text('Sending...');
        $.post(_ajax, {
            action: 'instinctor_chat_test_notification',
            nonce: _nonce,
            channel: 'sms',
            to: number
        }, function(response) {
            $btn.prop('disabled', false).text('Test');
            if (response.success) {
                window.showToast('Test SMS sent to ' + number, 'success');
            } else {
                var err = (response.data && typeof response.data === 'object') ? (response.data.error || response.data.message || JSON.stringify(response.data)) : (response.data || 'Unknown error');
                window.showToast('SMS failed: ' + err, 'error');
            }
        }).fail(function(xhr, status, error) {
            $btn.prop('disabled', false).text('Test');
            window.showToast('Request failed: ' + error, 'error');
        });
    }

    function testWhatsapp() {
        var $btn = $('#impulse-chat-test-whatsapp');
        var number = $('#impulse-chat-whatsapp_number').val();
        var _nonce = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.nonce : '';
        var _ajax = (window.Impulse && window.Impulse.chat) ? window.Impulse.chat.ajaxurl : (window.ajaxurl || '');
        if (!number) {
            window.showToast('Please enter a WhatsApp number', 'error');
            return;
        }
        $btn.prop('disabled', true).text('Sending...');
        $.post(_ajax, {
            action: 'instinctor_chat_test_notification',
            nonce: _nonce,
            channel: 'whatsapp',
            to: number
        }, function(response) {
            $btn.prop('disabled', false).text('Test');
            if (response.success) {
                window.showToast('Test WhatsApp sent to ' + number, 'success');
            } else {
                var err = (response.data && typeof response.data === 'object') ? (response.data.error || response.data.message || JSON.stringify(response.data)) : (response.data || 'Unknown error');
                window.showToast('WhatsApp failed: ' + err, 'error');
            }
        }).fail(function(xhr, status, error) {
            $btn.prop('disabled', false).text('Test');
            window.showToast('Request failed: ' + error, 'error');
        });
    }
    
    
    function renderAgents(agents) {
        var html = '';
        if (!agents || agents.length === 0) {
            html = '';
        } else {
            agents.forEach(function(agent) {
                html += '<div class="impulse-chat-agent-item">' +
                    '<img src="' + (agent.avatar || 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM2NjYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjAgMjF2LTJhNCA0IDAgMCAwLTQtNEg4YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjEyIiBjeT0iNyIgcj0iNCIvPjwvc3ZnPg==') + '" style="width:24px;height:24px;border-radius:50%;object-fit:cover;flex-shrink:0;background:#2a2e33">' +
                    '<div class="impulse-chat-agent-info"><div class="impulse-chat-agent-name">' + escapeHtml(agent.display_name) + '</div>' +
                    '<div class="impulse-chat-agent-details">' + escapeHtml(agent.email || '') + '</div></div>' +
                    '<span class="impulse-chat-agent-remove" data-id="' + agent.id + '">&times;</span></div>';
            });
        }
        $('#impulse-chat-agents-list').html(html);
        
        populateAgentSelect(agents);
    }

    function populateAgentSelect(currentAgents) {
        var currentIds = (currentAgents || []).map(function(a) { return String(a.user_id || a.id); });
        var $sel = $('#impulse-chat-agent-select');
        $sel.empty().append('<option value="">Add from team...</option>');
        if (!_chatTeamData.length) {
            
            $.post(ajaxurl, { action: 'instinctor_get_team', nonce: window.Impulse.adminNonce }, function(r) {
                if (r.success) {

                    
                    _chatTeamData = (r.data.available && r.data.available.length)
                        ? r.data.available
                        : (r.data.team || []);
                    populateAgentSelect(currentAgents);
                }
            });
            return;
        }
        _chatTeamData.forEach(function(member) {
            var name = member.display_name || member.name || member.email || '';
            var email = member.email || '';
            var id = String(member.id || member.ID || '');
            if (id && currentIds.indexOf(id) === -1) {
                $sel.append('<option value="' + id + '" data-name="' + escapeHtml(name) + '" data-email="' + escapeHtml(email) + '">'
                    + escapeHtml(name || email) + '</option>');
            }
        });
    }

    
    
    function startPolling() {
        stopPolling();
        pollInterval = setInterval(function() {
            if (currentConvId) {
                loadConversation(currentConvId);
            }
        }, 5000);
    }
    
    function stopPolling() {
        if (pollInterval) {
            clearInterval(pollInterval);
            pollInterval = null;
        }
    }
    
    function startListPolling() {
        listPollInterval = setInterval(function() {
            $.post(ajaxurl, {
                action: 'instinctor_chat_get_conversations',
                nonce: chatNonce
            }, function(response) {
                if (response.success) {
                    updateConversationsList(response.data.conversations);
                }
            });
        }, 10000);
    }
    
    function waitingLabel(conv) {
        if (conv.last_sender !== 'visitor') return '';
        var updated = conv.updated_at ? new Date(conv.updated_at.replace(' ', 'T')) : null;
        if (!updated) return '';
        var mins = Math.floor((Date.now() - updated.getTime()) / 60000);
        var label = mins < 1 ? 'just now' : mins < 60 ? mins + 'm' : Math.floor(mins / 60) + 'h';
        return '<span class="impulse-chat-waiting">' + label + '</span>';
    }

    function updateConversationsList(conversations) {
        var $list = $('#impulse-chat-conversations');

        if (!conversations || conversations.length === 0) {
            $list.html('<div class="impulse-chat-empty-state"><svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><p>No conversations</p></div>');
            return;
        }

        var html = '';
        conversations.forEach(function(conv) {
            var isActive = currentConvId == conv.id;
            var isUnread = conv.unread_count > 0 && !isActive;
            var hasNote  = !!(conv.visitor_note);
            var noteSvg  = '<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/><\/svg>';

            html += '<div class="impulse-chat-conv-item ' + (isActive ? 'active' : '') + ' ' + (isUnread ? 'unread' : '') + '" data-id="' + conv.id + '" data-email="' + escapeHtml(conv.visitor_email || '') + '" data-phone="' + escapeHtml(conv.visitor_phone || '') + '">' +
                '<div class="impulse-chat-conv-info">' +
                '<div class="impulse-chat-conv-name">' +
                escapeHtml(conv.visitor_name || 'Visitor') +
                (conv.assigned_agent_name ? '<span class="impulse-chat-agent-badge">' + escapeHtml(conv.assigned_agent_name) + '</span>' : '') +
                waitingLabel(conv) +
                '</div>' +
                '<div class="impulse-chat-conv-preview">' + escapeHtml((conv.last_message || '').substring(0, 40)) + '</div></div>' +
                '<button type="button" class="impulse-chat-note-btn' + (hasNote ? ' has-note' : '') + '" data-id="' + conv.id + '" title="' + (hasNote ? 'Edit note' : 'Add note') + '">' + noteSvg + '</button>' +
                '</div>';
        });

        $list.html(html);
    }

    function loadClosedConversations(showLoading) {
        var $list = $('#impulse-chat-closed-conversations');
        if (showLoading !== false) {
            $list.html('<div class="impulse-chat-empty-state"><p style="color:#555">Loading...</p></div>');
        }
        $.post(ajaxurl, {
            action: 'instinctor_chat_get_conversations',
            status: 'closed',
            nonce: chatNonce
        }, function(response) {
            if (response.success) {
                updateClosedConversationsList(response.data.conversations || []);
            }
        });
    }

    function updateClosedConversationsList(conversations) {
        var $list = $('#impulse-chat-closed-conversations');
        if (!conversations || conversations.length === 0) {
            $list.html('<div class="impulse-chat-empty-state"><svg viewBox="0 0 24 24" width="36" height="36" stroke="currentColor" fill="none" stroke-width="1.5" opacity="0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg><p>No closed conversations</p></div>');
            return;
        }
        var html = '';
        conversations.forEach(function(conv) {
            var isActive = currentConvId == conv.id;
            html += '<div class="impulse-chat-conv-item closed ' + (isActive ? 'active' : '') + '" data-id="' + conv.id + '">' +
                '<div class="impulse-chat-conv-info">' +
                '<div class="impulse-chat-conv-name">' + escapeHtml(conv.visitor_name || 'Visitor') + '</div>' +
                '<div class="impulse-chat-conv-preview">' + escapeHtml((conv.last_message || '').substring(0, 40)) + '</div>' +
                '</div></div>';
        });
        $list.html(html);
    }

    function showSaveStatus(text) {
        $('#impulse-chat-save-status').text(text);
    }
    
    function showToast(message, type) {
        type = type || 'success';
        var $toast = $('<div class="impulse-toast impulse-toast-' + type + '">' + escapeHtml(message) + '</div>');
        $('body').append($toast);
        setTimeout(function() { $toast.addClass('show'); }, 10);
        setTimeout(function() { $toast.removeClass('show'); }, 3000);
        setTimeout(function() { $toast.remove(); }, 3500);
    }
    
    function formatTime(datetime) {
        if (!datetime) return '';
        
        var normalized = String(datetime).replace(' ', 'T');
        var date = new Date(normalized);
        if (isNaN(date.getTime())) return '';
        var now = new Date();
        var diffMs = now - date;
        var diffDays = Math.floor(diffMs / 86400000);
        if (diffDays >= 1) {
            return date.toLocaleDateString([], {month:'short', day:'numeric'}) + ' ' +
                   date.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'});
        }
        return date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
    }
    
    function escapeHtml(text) {
        if (!text) return '';
        var div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    function getContrastColor(hexColor) {
        if (!hexColor) return '#000000';
        var hex = hexColor.replace('#', '');
        var r = parseInt(hex.substr(0, 2), 16);
        var g = parseInt(hex.substr(2, 2), 16);
        var b = parseInt(hex.substr(4, 2), 16);
        var luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
        return luminance > 0.5 ? '#000000' : '#ffffff';
    }
    
})(jQuery);

