/**
 * Ticaga Live Chat Widget - Enhanced Version
 * Embeddable real-time chat widget using Laravel Reverb WebSockets
 *
 * Features:
 * - Queue position display
 * - Business hours detection with offline form
 * - Chat ratings
 * - Proactive chat triggers
 * - Chat history for logged-in users
 */
(function() {
    'use strict';

    // Get configuration from script tag attributes
    const currentScript = document.currentScript;
    const config = {
        apiUrl: currentScript.getAttribute('data-api-url') || '/api/chat',
        widgetKey: currentScript.getAttribute('data-widget-key'),
        userId: currentScript.getAttribute('data-user-id') || null, // Laravel authenticated user ID
        // Extract host from apiUrl if not explicitly set
        wsHost: currentScript.getAttribute('data-ws-host') || (() => {
            try {
                const apiUrl = currentScript.getAttribute('data-api-url');
                if (apiUrl) {
                    return new URL(apiUrl).hostname;
                }
            } catch (e) {}
            return window.location.hostname;
        })(),
        wsPort: currentScript.getAttribute('data-ws-port') || '8080',
        wsScheme: currentScript.getAttribute('data-ws-scheme') || 'https',
        position: currentScript.getAttribute('data-position') || 'bottom-right',
        themeColor: currentScript.getAttribute('data-theme-color') || '#3B82F6',
        widgetIcon: currentScript.getAttribute('data-widget-icon') || 'chat',
        widgetTitle: currentScript.getAttribute('data-widget-title') || 'Chat with us',
        welcomeMessage: currentScript.getAttribute('data-welcome-message') || 'Hi! How can we help you today?',
        proactiveDelay: parseInt(currentScript.getAttribute('data-proactive-delay') || '0'), // seconds
        proactivePages: currentScript.getAttribute('data-proactive-pages') || '', // comma-separated URL patterns
    };

    /**
     * Build an API URL with the widget key appended as a query parameter.
     */
    function buildApiUrl(path) {
        const normalizedPath = path.startsWith('/') ? path : `/${path}`;
        const separator = normalizedPath.includes('?') ? '&' : '?';
        return `${config.apiUrl}${normalizedPath}${separator}widget_key=${encodeURIComponent(config.widgetKey)}`;
    }

    // Validate required config
    if (!config.widgetKey) {
        console.error('Ticaga Live Chat: widget-key is required');
        return;
    }

    // State
    let state = {
        sessionId: null,
        isOpen: false,
        isConnected: false,
        isOnline: false,  // Default to offline until config loads
        messages: [],
        agentTyping: false,
        guestTyping: false,
        typingTimeout: null,
        echo: null,
        queuePosition: null,
        chatEnded: false,
        sessionStartedAt: null,
        rating: null,
        widgetConfig: null,
        reverbAppKey: null,  // Store Reverb app key from config endpoint
        initialized: false,  // Track if widget has finished initializing
        unreadCount: 0,
    };

    /**
     * Load external scripts dynamically
     */
    function loadScript(src) {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = src;
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }

    /**
     * Initialize the chat widget
     */
    async function init() {
        try {
            // Fetch widget configuration (includes Reverb app key)
            await fetchWidgetConfig();

            // Only initialize WebSocket if we have a valid Reverb app key
            if (state.widgetConfig && state.widgetConfig.websocket && state.widgetConfig.websocket.key) {
                // Load Pusher library first (only if not already loaded)
                if (typeof window.Pusher === 'undefined') {
                    await loadScript('https://js.pusher.com/8.2.0/pusher.min.js');
                }

                // Then load Laravel Echo (only if not already loaded)
                if (typeof window.Echo === 'undefined') {
                    await loadScript('https://cdn.jsdelivr.net/npm/laravel-echo@1.16.1/dist/echo.iife.js');
                }

                // Initialize Echo with proper Reverb app key (not widget key!)
                // Use custom broadcasting auth endpoint that allows guest users (no auth required)
                const authEndpoint = `${config.apiUrl}/broadcasting/auth?widget_key=${encodeURIComponent(config.widgetKey)}`;

                console.log('[LiveChat] Initializing Echo:', {
                    wsHost: config.wsHost,
                    wsPort: config.wsPort,
                    forceTLS: config.wsScheme === 'https',
                    authEndpoint: authEndpoint,
                    echoAlreadyExists: typeof window.Echo !== 'undefined',
                });

                // Create our own Echo instance (don't overwrite window.Echo if it exists)
                const EchoClass = window.Echo.constructor || window.Echo;
                state.echo = new EchoClass({
                    broadcaster: 'reverb',
                    key: state.widgetConfig.websocket.key,  // Use Reverb app key from config
                    wsHost: config.wsHost,
                    wsPort: config.wsPort,
                    wssPort: config.wsPort,
                    forceTLS: config.wsScheme === 'https',
                    enabledTransports: ['ws', 'wss'],
                    disableStats: true,
                    authEndpoint: authEndpoint,  // Point to correct auth endpoint
                    auth: {
                        headers: {
                            'X-Requested-With': 'XMLHttpRequest',
                            'X-Widget-Key': config.widgetKey,
                        }
                    },
                    authorizer: (channel, options) => {
                        return {
                            authorize: (socketId, callback) => {
                                fetch(options.authEndpoint, {
                                    method: 'POST',
                                    credentials: 'include',
                                    headers: {
                                        'Content-Type': 'application/json',
                                        'X-Requested-With': 'XMLHttpRequest',
                                        'X-Widget-Key': config.widgetKey,
                                    },
                                    body: JSON.stringify({
                                        socket_id: socketId,
                                        channel_name: channel.name,
                                    })
                                })
                                .then(response => response.json())
                                .then(data => callback(null, data))
                                .catch(error => callback(error));
                            }
                        };
                    }
                });
            } else {
                console.warn('Ticaga Live Chat: Reverb not configured, real-time features disabled');
            }

            // Render widget UI
            renderWidget();

            // Check for existing session in localStorage
            const savedSessionId = localStorage.getItem('ticaga_chat_session_id');
            if (savedSessionId) {
                await resumeSession(savedSessionId);
            }

            // Setup proactive chat
            if (config.proactiveDelay > 0) {
                setupProactiveChat();
            }

            // Mark as initialized
            state.initialized = true;

            console.log('Ticaga Live Chat: initialized successfully', {
                isOnline: state.isOnline,
                widgetConfigLoaded: !!state.widgetConfig
            });
        } catch (error) {
            console.error('Ticaga Live Chat: initialization failed', error);
            state.initialized = true; // Mark as initialized even if failed, to prevent blocking
        }
    }

    /**
     * Fetch widget configuration from server
     */
    async function fetchWidgetConfig() {
        try {
            const previousOnlineStatus = state.isOnline;

            const response = await fetch(buildApiUrl('/widget/config'), {
                credentials: 'include',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                }
            });
            if (response.ok) {
                state.widgetConfig = await response.json();
                state.isOnline = state.widgetConfig.is_online;

                // If widget already rendered and online status changed, refresh the chat window
                if (state.elements && state.elements.chatWindow && previousOnlineStatus !== state.isOnline) {
                    console.log('[LiveChat] Online status changed, refreshing chat window', {
                        was: previousOnlineStatus,
                        now: state.isOnline
                    });
                    const chatWindow = state.elements.shadow.querySelector('.chat-window');
                    if (chatWindow) {
                        chatWindow.innerHTML = getChatWindowHTML();
                        attachEventListeners();
                    }
                }
            }
        } catch (error) {
            console.error('Failed to fetch widget config:', error);
        }
    }

    /**
     * Setup proactive chat trigger
     */
    function setupProactiveChat() {
        // Check if current page matches proactive pages pattern
        if (config.proactivePages) {
            const patterns = config.proactivePages.split(',').map(p => p.trim());
            const currentUrl = window.location.pathname;
            const matches = patterns.some(pattern => {
                if (pattern.includes('*')) {
                    const regex = new RegExp(pattern.replace(/\*/g, '.*'));
                    return regex.test(currentUrl);
                }
                return currentUrl.includes(pattern);
            });

            if (!matches) return;
        }

        // Don't show if chat was already dismissed
        if (sessionStorage.getItem('ticaga_chat_dismissed')) {
            return;
        }

        // Trigger after delay
        setTimeout(() => {
            if (!state.isOpen && !state.sessionId) {
                toggleChat();
                // Add a subtle notification badge
                const bubble = state.elements.bubble;
                if (bubble) {
                    bubble.style.animation = 'pulse 2s infinite';
                }
            }
        }, config.proactiveDelay * 1000);
    }

    /**
     * Render the widget UI
     */
    function renderWidget() {
        // Detect viewport size at initialization
        const minDimension = Math.min(window.innerWidth, window.innerHeight);
        const isMobile = minDimension <= 640;

        console.log('[LiveChat] Rendering widget - Device type:', isMobile ? 'Mobile' : 'Desktop/Tablet');

        // MOBILE RENDERING: Minimal container, no bubble, controlled via header button
        if (isMobile) {
            console.log('[LiveChat] Mobile detected - Widget UI disabled, use header button to open chat');

            // Create minimal container for chat window only
            const container = document.createElement('div');
            container.id = 'ticaga-chat-widget';
            container.style.cssText = `
                position: fixed;
                left: 0;
                right: 0;
                bottom: 0;
                top: 0;
                z-index: 9999;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                display: none;
                pointer-events: none;
            `;
            document.body.appendChild(container);

            // Create shadow DOM for style isolation
            const shadow = container.attachShadow({ mode: 'open' });

            // Add styles
            const style = document.createElement('style');
            style.textContent = getStyles();
            shadow.appendChild(style);

            // Create chat window only (no bubble)
            const chatWindow = document.createElement('div');
            chatWindow.className = 'chat-window hidden';
            chatWindow.innerHTML = getChatWindowHTML();
            shadow.appendChild(chatWindow);

            // Store references (no bubble on mobile)
            const unreadBadge = shadow.getElementById('chat-unread-badge');
            state.elements = { shadow, bubble: null, chatWindow, container, unreadBadge };

            // Attach event listeners
            attachEventListeners();

            // Apply responsive styles
            applyResponsiveLayout();
            window.addEventListener('resize', applyResponsiveLayout);

            return; // Exit early for mobile
        }

        // DESKTOP/TABLET RENDERING: Full widget with bubble
        console.log('[LiveChat] Desktop/Tablet detected - Full widget with bubble');

        // Determine if position is top or bottom
        const isBottom = config.position.includes('bottom');
        const isRight = config.position.includes('right');

        // Create container
        const container = document.createElement('div');
        container.id = 'ticaga-chat-widget';
        container.style.cssText = `
            position: fixed;
            ${isRight ? 'right: 20px;' : 'left: 20px;'}
            ${isBottom ? 'bottom: 20px;' : 'top: 20px;'}
            z-index: 9999;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            display: flex;
            flex-direction: ${isBottom ? 'column-reverse' : 'column'};
            align-items: ${isRight ? 'flex-end' : 'flex-start'};
            gap: 20px;
        `;
        document.body.appendChild(container);

        // Create shadow DOM for style isolation
        const shadow = container.attachShadow({ mode: 'open' });

        // Add styles
        const style = document.createElement('style');
        style.textContent = getStyles();
        shadow.appendChild(style);

        // Create chat bubble with configured icon
        const bubble = document.createElement('div');
        bubble.className = 'chat-bubble';
        bubble.innerHTML = `
            ${getIconSvg(config.widgetIcon)}
            <span class="chat-unread-badge" id="chat-unread-badge">0</span>
        `;
        bubble.addEventListener('click', toggleChat);
        shadow.appendChild(bubble);

        // Create chat window
        const chatWindow = document.createElement('div');
        chatWindow.className = 'chat-window hidden';
        chatWindow.innerHTML = getChatWindowHTML();
        shadow.appendChild(chatWindow);

        // Store references
        const unreadBadge = shadow.getElementById('chat-unread-badge');
        state.elements = { shadow, bubble, chatWindow, container, unreadBadge };

        // Attach event listeners
        attachEventListeners();

        // Apply responsive styles
        applyResponsiveLayout();
        window.addEventListener('resize', applyResponsiveLayout);
    }

    /**
     * Ensure the widget feels native on smaller screens.
     */
    function applyResponsiveLayout() {
        if (!state.elements || !state.elements.container) {
            return;
        }

        const { container, chatWindow, bubble } = state.elements;
        const minDimension = Math.min(window.innerWidth, window.innerHeight);
        const isFullScreen = minDimension <= 640;
        const viewportHeight = (window.visualViewport && window.visualViewport.height)
            ? window.visualViewport.height
            : window.innerHeight;
        const isBottom = config.position.includes('bottom');
        const isRight = config.position.includes('right');

        // Hide bubble on mobile (users will use header button instead)
        // Show bubble on desktop
        if (bubble) {
            bubble.style.display = isFullScreen ? 'none' : '';
        }

        // Only apply fullscreen layout when chat is actually open
        if (isFullScreen && state.isOpen) {
            container.style.left = '0';
            container.style.right = '0';
            container.style.bottom = '0';
            container.style.top = '0';
            container.style.width = '100vw';
            container.style.height = '100vh';
            container.style.gap = '0';
            container.style.alignItems = 'stretch';
            container.style.flexDirection = 'column';

            chatWindow.style.width = '100vw';
            chatWindow.style.height = `${viewportHeight}px`;
            chatWindow.style.maxHeight = `${viewportHeight}px`;
            chatWindow.style.borderRadius = '0';
            chatWindow.style.boxShadow = 'none';
        } else {
            // Normal positioning (desktop or mobile with chat closed)
            if (isRight) {
                container.style.right = '20px';
                container.style.left = '';
                container.style.alignItems = 'flex-end';
            } else {
                container.style.left = '20px';
                container.style.right = '';
                container.style.alignItems = 'flex-start';
            }

            if (isBottom) {
                container.style.bottom = '20px';
                container.style.top = '';
                container.style.flexDirection = 'column-reverse';
            } else {
                container.style.top = '20px';
                container.style.bottom = '';
                container.style.flexDirection = 'column';
            }

            container.style.width = '';
            container.style.height = '';
            container.style.gap = '20px';

            // On mobile, make chat window fullscreen when open
            if (isFullScreen) {
                chatWindow.style.width = '100vw';
                chatWindow.style.height = `${viewportHeight}px`;
                chatWindow.style.maxHeight = `${viewportHeight}px`;
                chatWindow.style.borderRadius = '0';
                chatWindow.style.boxShadow = 'none';
            } else {
                chatWindow.style.width = '380px';
                chatWindow.style.height = '580px';
                chatWindow.style.maxHeight = 'calc(100vh - 100px)';
                chatWindow.style.borderRadius = '12px';
                chatWindow.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.15)';
            }

            if (bubble) {
                // Reset bubble size (visibility already handled above)
                bubble.style.width = '60px';
                bubble.style.height = '60px';
                bubble.style.fontSize = '';
            }
        }
    }

    /**
     * Get CSS styles (with new additions for ratings and queue)
     */
    function getStyles() {
        return `
            * {
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }

            @keyframes pulse {
                0%, 100% { transform: scale(1); }
                50% { transform: scale(1.1); }
            }

            .chat-bubble {
                width: 60px;
                height: 60px;
                background: ${config.themeColor};
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                transition: transform 0.2s, box-shadow 0.2s;
                color: white;
            }

            chat-bubble {
                position: relative;
            }

            .chat-unread-badge {
                position: absolute;
                top: 4px;
                right: 4px;
                min-width: 18px;
                height: 18px;
                padding: 0 4px;
                border-radius: 9999px;
                background: #ef4444;
                color: #fff;
                font-size: 11px;
                display: none;
                align-items: center;
                justify-content: center;
                line-height: 1;
            }

            .chat-messages-wrapper {
                position: relative;
                flex: 1;
                display: flex;
                flex-direction: column;
                min-height: 0;
                overflow: hidden;
            }

            .chat-messages {
                flex: 1;
                overflow-y: auto;
                padding: 16px;
                background: #f9fafb;
                display: flex;
                flex-direction: column;
                min-height: 0;
            }

            .new-messages-button {
                position: absolute;
                left: 50%;
                transform: translateX(-50%);
                bottom: 8px;
                padding: 4px 10px;
                font-size: 12px;
                border-radius: 9999px;
                background: #4f46e5;
                color: white;
                border: none;
                display: none;
                align-items: center;
                gap: 4px;
                box-shadow: 0 4px 10px rgba(79, 70, 229, 0.35);
                cursor: pointer;
            }

            .new-messages-button:hover {
                background: #4338ca;
            }

            .typing-indicator {
                display: flex;
                gap: 4px;
                padding: 10px 14px;
                background: white;
                border-radius: 12px;
                width: fit-content;
            }

            .typing-indicator span {
                width: 8px;
                height: 8px;
                background: #9ca3af;
                border-radius: 9999px;
                animation: typingBlink 1.4s infinite both;
            }

            .typing-indicator span:nth-child(2) {
                animation-delay: .2s;
            }

            .typing-indicator span:nth-child(3) {
                animation-delay: .4s;
            }

            @keyframes typingBlink {
                0% { opacity: .2; transform: translateY(0); }
                20% { opacity: 1; transform: translateY(-2px); }
                100% { opacity: .2; transform: translateY(0); }
            }

            .chat-bubble:hover {
                transform: scale(1.05);
                box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
            }

            .chat-window {
                width: 380px;
                height: 580px;
                max-height: calc(100vh - 100px);
                background: white;
                border-radius: 12px;
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
                display: flex;
                flex-direction: column;
                overflow: hidden;
                transition: opacity 0.3s, transform 0.3s;
            }

            .chat-window.hidden {
                display: none;
            }

            .chat-header {
                background: ${config.themeColor};
                color: white;
                padding: 16px;
                display: flex;
                justify-content: space-between;
                align-items: center;
                flex-shrink: 0;
            }

            .chat-header h3 {
                font-size: 16px;
                font-weight: 600;
            }

            .chat-header button {
                background: none;
                border: none;
                color: white;
                font-size: 24px;
                cursor: pointer;
                padding: 0;
                width: 30px;
                height: 30px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .chat-header-actions {
                display: flex;
                align-items: center;
                gap: 8px;
            }

            #chat-status-text {
                font-size: 12px;
                opacity: 0.85;
                margin-top: 4px;
            }

            #end-chat-btn {
                border: 1px solid rgba(255, 255, 255, 0.5);
                border-radius: 9999px;
                padding: 4px 12px;
                font-size: 12px;
                font-weight: 600;
                background: rgba(255, 255, 255, 0.15);
                color: white;
                cursor: pointer;
                transition: background 0.2s;
                width: auto;
                height: auto;
                display: inline-flex;
                align-items: center;
                justify-content: center;
            }

            #end-chat-btn:hover {
                background: rgba(255, 255, 255, 0.3);
            }

            #end-chat-btn.hidden {
                display: none;
            }

            #chat-content {
                flex: 1;
                display: flex;
                flex-direction: column;
                overflow: hidden;
                min-height: 0;
            }

            .queue-banner {
                background: #FEF3C7;
                color: #92400E;
                padding: 10px 16px;
                text-align: center;
                font-size: 12px;
                border-bottom: 1px solid #FCD34D;
            }

            .queue-banner strong {
                font-weight: 600;
            }

            .offline-banner {
                background: #FEE2E2;
                color: #991B1B;
                padding: 10px 16px;
                text-align: center;
                font-size: 12px;
                border-bottom: 1px solid #FCA5A5;
            }

            .chat-messages {
                flex: 1;
                overflow-y: auto;
                padding: 16px;
                background: #f9fafb;
                display: flex;
                flex-direction: column;
                min-height: 0;
            }

            .message {
                margin-bottom: 12px;
                display: flex;
                flex-direction: column;
            }

            .message.employee {
                align-items: flex-start;
            }

            .message.customer,
            .message.guest {
                align-items: flex-end;
            }

            .message-bubble {
                max-width: 70%;
                padding: 10px 14px;
                border-radius: 12px;
                word-wrap: break-word;
                font-size: 13px;
                line-height: 1.5;
            }

            .message.employee .message-bubble {
                background: white;
                color: #1f2937;
                border: 1px solid #e5e7eb;
            }

            .message.customer .message-bubble,
            .message.guest .message-bubble {
                background: ${config.themeColor};
                color: white;
            }

            .message.system {
                align-items: stretch;
            }

            .message.system .message-bubble {
                max-width: 100%;
                width: 100%;
                background: #e5e7eb;
                color: #4b5563;
                text-align: center;
                border-radius: 10px;
                box-shadow: inset 0 0 0 1px rgba(0,0,0,0.04);
            }

            .message.system .message-time {
                justify-content: center;
                text-align: center;
                color: #9ca3af;
            }

            .message-time {
                font-size: 11px;
                color: #9ca3af;
                margin-top: 4px;
            }

            .typing-indicator {
                display: flex;
                gap: 4px;
                padding: 10px 14px;
                background: white;
                border-radius: 12px;
                width: fit-content;
            }

            .typing-indicator span {
                width: 8px;
                height: 8px;
                background: #9ca3af;
                border-radius: 50%;
                animation: typing 1.4s infinite;
            }

            .typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
            .typing-indicator span:nth-child(3) { animation-delay: 0.4s; }

            @keyframes typing {
                0%, 60%, 100% { transform: translateY(0); }
                30% { transform: translateY(-10px); }
            }

            .chat-input {
                display: flex;
                padding: 16px;
                background: white;
                border-top: 1px solid #e5e7eb;
                align-items: center;
                gap: 8px;
                flex-shrink: 0;
            }

            .chat-input input {
                flex: 1;
                min-width: 0;
                border: 1px solid #e5e7eb;
                border-radius: 20px;
                padding: 10px 16px;
                font-size: 13px;
                outline: none;
                background-color: white;
                color: #1f2937;
            }

            .chat-input input:focus {
                border-color: ${config.themeColor};
            }

            .chat-input button {
                background: ${config.themeColor};
                color: white;
                border: none;
                border-radius: 50%;
                width: 40px;
                height: 40px;
                flex-shrink: 0;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .chat-input button:hover {
                opacity: 0.9;
            }

            .pre-chat-form, .offline-form {
                padding: 20px;
            }

            .form-group {
                margin-bottom: 16px;
            }

            .form-group label {
                display: block;
                margin-bottom: 6px;
                font-size: 14px;
                color: #374151;
                font-weight: 500;
            }

            .form-group input, .form-group textarea {
                width: 100%;
                border: 1px solid #e5e7eb;
                border-radius: 6px;
                padding: 10px 12px;
                font-size: 14px;
                outline: none;
                font-family: inherit;
                background-color: white;
                color: #1f2937;
            }

            .form-group textarea {
                resize: vertical;
                min-height: 80px;
            }

            .form-group input:focus, .form-group textarea:focus {
                border-color: ${config.themeColor};
            }

            .btn-primary {
                width: 100%;
                background: ${config.themeColor};
                color: #ffffff !important;
                border: none;
                border-radius: 6px;
                padding: 12px 16px;
                font-size: 14px;
                font-weight: 600;
                cursor: pointer;
                text-align: center;
                line-height: 1.5;
                display: block;
            }

            .btn-primary:hover {
                opacity: 0.9;
            }

            .btn-primary:disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }

            .btn-link {
                background: none;
                border: none;
                color: ${config.themeColor};
                cursor: pointer;
                font-size: 14px;
                text-decoration: underline;
                padding: 8px 0;
            }

            .rating-container {
                padding: 20px;
                text-align: center;
                background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);
                border-top: 2px solid #e5e7eb;
                flex-shrink: 0;
                max-height: 150px;
            }

            .rating-title {
                font-size: 16px;
                font-weight: 700;
                color: #111827;
                margin-bottom: 12px;
                letter-spacing: -0.01em;
            }

            .rating-stars {
                display: flex;
                justify-content: center;
                gap: 10px;
                margin-bottom: 0;
            }

            .rating-star {
                font-size: 36px;
                cursor: pointer;
                color: #e5e7eb;
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
                transform: scale(1);
                filter: grayscale(100%);
                line-height: 1;
            }

            .rating-star:hover {
                color: #fbbf24;
                transform: scale(1.15);
                filter: grayscale(0%) drop-shadow(0 4px 8px rgba(251, 191, 36, 0.4));
            }

            .rating-star.active {
                color: #fbbf24;
                transform: scale(1.1);
                filter: grayscale(0%) drop-shadow(0 2px 6px rgba(251, 191, 36, 0.3));
            }

            .rating-thanks {
                color: #059669;
                font-weight: 600;
                font-size: 16px;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                animation: fadeIn 0.5s ease-in;
            }

            @keyframes fadeIn {
                from {
                    opacity: 0;
                    transform: translateY(-10px);
                }
                to {
                    opacity: 1;
                    transform: translateY(0);
                }
            }

            .history-link {
                padding: 12px 20px;
                background: #f3f4f6;
                border-bottom: 1px solid #e5e7eb;
                text-align: center;
            }

            @media (max-width: 640px), (max-height: 640px) {
                :host {
                    position: fixed;
                    inset: 0 !important;
                    left: 0 !important;
                    right: 0 !important;
                    top: 0 !important;
                    bottom: 0 !important;
                    width: 100vw !important;
                    height: 100vh !important;
                    margin: 0 !important;
                    padding: 0 !important;
                    z-index: 9999;
                }

                .chat-window {
                    width: 100vw !important;
                    height: 100vh !important;
                    max-height: none !important;
                    min-height: -webkit-fill-available;
                    border-radius: 0 !important;
                    box-shadow: none !important;
                }

                .chat-bubble {
                    width: 72px;
                    height: 72px;
                }
            }
        `;
    }

    /**
     * Get chat window HTML
     */
    function getChatWindowHTML() {
        const title = state.widgetConfig?.title || 'Chat with us';

        if (!state.isOnline) {
            // Offline form
            return `
                <div class="chat-header">
                    <h3>${title}</h3>
                    <button id="close-chat">&times;</button>
                </div>
                <div class="offline-banner">
                    <div style="font-weight: 600; margin-bottom: 4px;">We're currently closed</div>
                    ${state.widgetConfig?.next_opening_time ? `<div style="font-size: 13px; opacity: 0.9;">${state.widgetConfig.next_opening_time}</div>` : ''}
                </div>
                <div id="chat-content">
                    <div class="offline-form">
                        <form id="offline-form">
                            ${!config.userId ? `
                                <div class="form-group">
                                    <label for="offline-name">Name *</label>
                                    <input type="text" id="offline-name" required>
                                </div>
                                <div class="form-group">
                                    <label for="offline-email">Email *</label>
                                    <input type="email" id="offline-email" required>
                                </div>
                            ` : ''}
                            ${state.widgetConfig?.available_departments?.length > 0 ? `
                                <div class="form-group">
                                    <label for="offline-department">Department *</label>
                                    <select id="offline-department" required style="width: 100%; border: 1px solid #e5e7eb; border-radius: 6px; padding: 10px 12px; font-size: 14px; outline: none; font-family: inherit; background-color: white; color: #1f2937;">
                                        <option value="">Select a department...</option>
                                        ${state.widgetConfig.available_departments.map(dept =>
                                            `<option value="${dept.id}">${dept.name}</option>`
                                        ).join('')}
                                    </select>
                                </div>
                            ` : ''}
                            <div class="form-group">
                                <label for="offline-message">Message *</label>
                                <textarea id="offline-message" required></textarea>
                            </div>
                            <button type="submit" class="btn-primary">Send Message</button>
                        </form>
                    </div>
                </div>
            `;
        }

        // Online - regular chat
        return `
            <div class="chat-header">
                <div>
                    <h3>${title}</h3>
                    <p id="chat-status-text"></p>
                </div>
                <div class="chat-header-actions">
                    <button id="end-chat-btn" class="hidden">End Chat</button>
                    <button id="close-chat" aria-label="Hide chat">&times;</button>
                </div>
            </div>
            <div id="chat-content">
                <div class="pre-chat-form">
                    <h4 style="margin-bottom: 8px; color: #1f2937;">Start a conversation</h4>
                    <p style="margin-bottom: 16px; color: #6b7280; font-size: 14px;">
                        ${state.widgetConfig?.welcome_message || 'Hi! How can we help you today?'}
                    </p>
                    <form id="pre-chat-form">
                        <div class="form-group">
                            <label for="guest-name">Name *</label>
                            <input type="text" id="guest-name" required>
                        </div>
                        <div class="form-group">
                            <label for="guest-email">Email *</label>
                            <input type="email" id="guest-email" required>
                        </div>
                        <button type="submit" class="btn-primary">Start Chat</button>
                        <button type="button" id="view-history" class="btn-link" style="width: 100%; margin-top: 8px;">
                            View Chat History
                        </button>
                    </form>
                </div>
            </div>
        `;
    }

    /**
     * Attach event listeners
     */
    function attachEventListeners() {
        const shadow = state.elements.shadow;

        // Close button
        shadow.getElementById('close-chat').addEventListener('click', () => {
            toggleChat();
            sessionStorage.setItem('ticaga_chat_dismissed', 'true');
        });

        const endChatBtn = shadow.getElementById('end-chat-btn');
        if (endChatBtn) {
            endChatBtn.addEventListener('click', () => {
                if (state.sessionId && !state.chatEnded) {
                    endChatSession(true);
                }
            });
        }

        // Pre-chat form
        const preChatForm = shadow.getElementById('pre-chat-form');
        if (preChatForm) {
            preChatForm.addEventListener('submit', handlePreChatSubmit);
        }

        // Offline form
        const offlineForm = shadow.getElementById('offline-form');
        if (offlineForm) {
            offlineForm.addEventListener('submit', handleOfflineFormSubmit);
        }

        // View history button
        const historyBtn = shadow.getElementById('view-history');
        if (historyBtn) {
            historyBtn.addEventListener('click', () => viewChatHistory());
        }
    }

    /**
     * Toggle chat window
     */
    function toggleChat() {
        state.isOpen = !state.isOpen;
        const chatWindow = state.elements.shadow.querySelector('.chat-window');
        chatWindow.classList.toggle('hidden');

        // On mobile, enable/disable pointer-events on container based on chat state
        const minDimension = Math.min(window.innerWidth, window.innerHeight);
        const isMobile = minDimension <= 640;

        if (isMobile && state.elements.container) {
            if (state.isOpen) {
                // Chat is opening - enable pointer events and show container
                state.elements.container.style.display = 'block';
                state.elements.container.style.pointerEvents = 'auto';
                console.log('[LiveChat] Mobile chat opened - pointer events enabled');
            } else {
                // Chat is closing - disable pointer events and hide container
                state.elements.container.style.display = 'none';
                state.elements.container.style.pointerEvents = 'none';
                console.log('[LiveChat] Mobile chat closed - pointer events disabled');
            }
        }

        // Re-apply responsive layout to update positioning based on new state
        applyResponsiveLayout();
    }

    /**
     * Handle pre-chat form submission
     */
    async function handlePreChatSubmit(e) {
        e.preventDefault();

        const shadow = state.elements.shadow;
        const name = shadow.getElementById('guest-name').value;
        const email = shadow.getElementById('guest-email').value;

        try {
            const session = await startChatSession(name, email);
            state.sessionId = session.id;
            state.queuePosition = session.queue_position;
            state.sessionStartedAt = session.started_at || new Date().toISOString();
            state.chatEnded = false;
            state.messages = []; // Initialize empty messages array

            // Save session ID and guest info for reuse
            localStorage.setItem('ticaga_chat_session_id', session.id);
            localStorage.setItem('ticaga_guest_name', name);
            localStorage.setItem('ticaga_guest_email', email);

            // Fetch session with messages to get any initial messages (like welcome message)
            try {
                const sessionData = await fetch(buildApiUrl(`/session/${session.id}`), {
                    credentials: 'include',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest',
                        'X-Widget-Key': config.widgetKey
                    }
                }).then(r => r.json());

                if (sessionData.messages) {
                    state.messages = sessionData.messages;
                }
            } catch (e) {
                console.debug('Failed to fetch initial messages:', e);
            }

            // Switch to chat interface
            renderChatInterface();

            // Subscribe to chat channel
            subscribeToChat(session.id);

            // Poll for queue updates
            if (state.queuePosition) {
                startQueuePolling();
            }
        } catch (error) {
            console.error('Failed to start chat session:', error);
            alert('Failed to start chat. Please try again.');
        }
    }

    /**
     * Handle offline form submission
     */
    async function handleOfflineFormSubmit(e) {
        e.preventDefault();

        const shadow = state.elements.shadow;
        const name = shadow.getElementById('offline-name')?.value;
        const email = shadow.getElementById('offline-email')?.value;
        const message = shadow.getElementById('offline-message').value;
        const departmentId = shadow.getElementById('offline-department')?.value;

        // Build payload - include user_id if authenticated, otherwise use guest fields
        const payload = {
            widget_key: config.widgetKey,
            message: message,
        };

        if (config.userId) {
            // Authenticated user
            payload.user_id = parseInt(config.userId);
        } else {
            // Guest user
            payload.guest_name = name;
            payload.guest_email = email;
        }

        // Include department selection if available
        if (departmentId) {
            payload.department_id = parseInt(departmentId);
        }

        try {
            const response = await fetch(buildApiUrl('/offline'), {
                method: 'POST',
                credentials: 'include',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                },
                body: JSON.stringify(payload),
            });

            if (!response.ok) {
                throw new Error('Failed to submit message');
            }

            // Show success message
            const content = shadow.getElementById('chat-content');
            content.innerHTML = `
                <div style="padding: 40px 20px; text-align: center;">
                    <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" style="margin: 0 auto 16px;">
                        <circle cx="12" cy="12" r="10"></circle>
                        <path d="M9 12l2 2 4-4"></path>
                    </svg>
                    <h4 style="color: #1f2937; margin-bottom: 8px;">Message sent!</h4>
                    <p style="color: #6b7280; font-size: 14px;">We'll get back to you as soon as possible.</p>
                </div>
            `;

            setTimeout(() => {
                toggleChat();
            }, 3000);
        } catch (error) {
            console.error('Failed to submit offline message:', error);
            alert('Failed to send message. Please try again.');
        }
    }

    /**
     * Start a new chat session
     */
    async function startChatSession(name, email) {
        const response = await fetch(buildApiUrl('/start'), {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-Widget-Key': config.widgetKey
            },
            body: JSON.stringify({
                widget_key: config.widgetKey,
                guest_name: name,
                guest_email: email,
                referrer_url: document.referrer,
                current_page_url: window.location.href,
            }),
        });

        if (!response.ok) {
            throw new Error('Failed to start chat session');
        }

        return await response.json();
    }

    /**
     * Poll queue position
     */
    function startQueuePolling() {
        const pollInterval = setInterval(async () => {
            if (!state.sessionId || state.queuePosition === null) {
                clearInterval(pollInterval);
                return;
            }

            try {
                const response = await fetch(buildApiUrl(`/session/${state.sessionId}`), {
                    credentials: 'include',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest',
                        'X-Widget-Key': config.widgetKey
                    }
                });
                if (response.ok) {
                    const session = await response.json();
                    if (session.status === 'active') {
                        state.queuePosition = null;
                        updateQueueBanner();
                        clearInterval(pollInterval);
                    } else if (session.queue_position !== state.queuePosition) {
                        state.queuePosition = session.queue_position;
                        updateQueueBanner();
                    }
                }
            } catch (error) {
                console.error('Failed to poll queue:', error);
            }
        }, 5000); // Poll every 5 seconds
    }

    /**
     * Update queue position banner
     */
    function updateQueueBanner() {
        const shadow = state.elements.shadow;
        let banner = shadow.querySelector('.queue-banner');

        if (state.queuePosition) {
            if (!banner) {
                const header = shadow.querySelector('.chat-header');
                banner = document.createElement('div');
                banner.className = 'queue-banner';
                header.after(banner);
            }
            banner.innerHTML = `You're <strong>#${state.queuePosition}</strong> in the queue - an employee will be with you shortly.`;
        } else if (banner) {
            banner.remove();
        }
    }

    /**
     * Resume an existing session
     */
    async function resumeSession(sessionId) {
        try {
            const response = await fetch(buildApiUrl(`/session/${sessionId}`), {
                credentials: 'include',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                }
            });

            if (!response.ok) {
                localStorage.removeItem('ticaga_chat_session_id');
                return;
            }

            const session = await response.json();
            state.sessionStartedAt = session.started_at || null;

            if (session.status === 'ended') {
                // Show rating if not already rated
                state.sessionId = sessionId;
                state.chatEnded = true;
                state.messages = session.messages || [];
                renderChatInterface();
                localStorage.removeItem('ticaga_chat_session_id');
                showRatingPrompt();
                return;
            }

            if (session.status === 'converted') {
                localStorage.removeItem('ticaga_chat_session_id');
                return;
            }

            state.sessionId = sessionId;
            state.messages = session.messages || [];
            state.queuePosition = session.queue_position;
            state.chatEnded = false;

            renderChatInterface();
            subscribeToChat(sessionId);

            if (state.queuePosition) {
                startQueuePolling();
            }
        } catch (error) {
            console.error('Failed to resume session:', error);
            localStorage.removeItem('ticaga_chat_session_id');
        }
    }

    /**
     * Update header action visibility.
     */
    function updateEndChatButton() {
        const shadow = state.elements.shadow;
        if (!shadow) return;
        const button = shadow.getElementById('end-chat-btn');
        if (!button) return;

        if (state.sessionId && !state.chatEnded) {
            button.classList.remove('hidden');
        } else {
            button.classList.add('hidden');
        }
    }

    function updateSessionStatusText() {
        const shadow = state.elements.shadow;
        if (!shadow) return;
        const label = shadow.getElementById('chat-status-text');
        if (!label) return;

        if (state.chatEnded) {
            label.textContent = 'Chat ended';
        } else if (state.sessionId) {
            label.textContent = 'Connected to support';
        } else {
            label.textContent = '';
        }
    }

    function refreshHeaderState() {
        updateEndChatButton();
        updateSessionStatusText();
    }

    /**
     * Render chat interface
     */
    function renderChatInterface() {
        const shadow = state.elements.shadow;
        const content = shadow.getElementById('chat-content');

        // Always show messages, with or without input
        content.innerHTML = `
            <div class="chat-messages-wrapper">
                <div class="chat-messages" id="chat-messages"></div>
                <button type="button" class="new-messages-button" id="new-messages-btn">
                    New messages ↓
                </button>
            </div>
            ${!state.chatEnded ? `
                <div class="chat-input">
                    <input type="text" id="message-input" placeholder="Type a message...">
                    <button id="send-btn">
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M2 21l21-9L2 3v7l15 2-15 2v7z"/>
                        </svg>
                    </button>
                </div>
            ` : `
                <div class="chat-ended-notice" style="padding: 16px; background: #f3f4f6; border-top: 1px solid #e5e7eb; text-align: center; flex-shrink: 0;">
                    <div style="font-size: 13px; color: #6b7280; margin-bottom: 12px;">
                        This conversation has ended
                    </div>
                    <div style="display: flex; gap: 8px; justify-content: center;">
                        <button type="button" id="start-new-chat-btn" style="flex: 1; max-width: 150px; padding: 8px 16px; background: ${config.themeColor}; color: white; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: opacity 0.2s;">
                            Start New Chat
                        </button>
                        <button type="button" id="continue-chat-btn" style="flex: 1; max-width: 150px; padding: 8px 16px; background: white; color: ${config.themeColor}; border: 1px solid ${config.themeColor}; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s;">
                            Continue
                        </button>
                    </div>
                </div>
            `}
        `;

        // Update queue banner
        updateQueueBanner();

        // Update element references BEFORE rendering messages (critical!)
        const messagesEl = shadow.getElementById('chat-messages');
        const newMessagesBtn = shadow.getElementById('new-messages-btn');

        state.elements.messagesEl = messagesEl;
        state.elements.newMessagesBtn = newMessagesBtn;

        // Render existing messages
        renderMessages();

        // Attach input event listeners
        if (!state.chatEnded) {
            const messageInput = shadow.getElementById('message-input');
            messageInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') sendMessage();
            });
            messageInput.addEventListener('input', handleTyping);
            shadow.getElementById('send-btn').addEventListener('click', sendMessage);
        }

        if (messagesEl) {
            messagesEl.addEventListener('scroll', handleMessagesScroll);
        }

        if (newMessagesBtn) {
            newMessagesBtn.addEventListener('click', () => {
                scrollMessagesToBottom(true);
                resetUnread();
            });
        }

        // Attach post-chat action buttons
        if (state.chatEnded) {
            const startNewBtn = shadow.getElementById('start-new-chat-btn');
            const continueBtn = shadow.getElementById('continue-chat-btn');

            if (startNewBtn) {
                startNewBtn.addEventListener('click', startNewChat);
            }

            if (continueBtn) {
                continueBtn.addEventListener('click', continueChat);
            }
        }

        refreshHeaderState();
    }

    /**
     * Render pre-chat form (used when starting fresh chat)
     */
    function renderPreChatForm() {
        const shadow = state.elements.shadow;
        const chatWindow = shadow.querySelector('.chat-window');

        // Replace entire chat window content with fresh initial state
        chatWindow.innerHTML = getChatWindowHTML();

        // Re-attach event listeners
        attachEventListeners();
    }

    function isNearBottom(el, threshold = 40) {
        if (!el) return true;
        return el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
    }

    function scrollMessagesToBottom(smooth = true) {
        const el = state.elements.messagesEl || (state.elements.shadow && state.elements.shadow.getElementById('chat-messages'));
        if (!el) return;

        el.scrollTo({
            top: el.scrollHeight,
            behavior: smooth ? 'smooth' : 'auto',
        });
    }

    function showNewMessagesButton() {
        const btn = state.elements.newMessagesBtn;
        if (!btn) return;
        btn.style.display = 'flex';
    }

    function hideNewMessagesButton() {
        const btn = state.elements.newMessagesBtn;
        if (!btn) return;
        btn.style.display = 'none';
    }

    function updateUnreadBadge() {
        const badge = state.elements.unreadBadge;
        if (!badge) return;

        if (state.unreadCount > 0) {
            badge.textContent = state.unreadCount;
            badge.style.display = 'flex';
            state.elements.bubble && (state.elements.bubble.style.animation = 'pulse 2s infinite');
        } else {
            badge.style.display = 'none';
            state.elements.bubble && (state.elements.bubble.style.animation = '');
        }
    }

    function resetUnread() {
        state.unreadCount = 0;
        hideNewMessagesButton();
        updateUnreadBadge();
    }

    function handleMessagesScroll() {
        const el = state.elements.messagesEl;
        if (!el) return;

        if (isNearBottom(el)) {
            hideNewMessagesButton();
            resetUnread();
            // If you implement “seen” on the backend, this is where you’d call it.
        }
    }

    function renderMessages() {
        const shadow = state.elements.shadow;
        const container = state.elements.messagesEl || (shadow && shadow.getElementById('chat-messages'));
        if (!container) return;

        const wasAtBottom = isNearBottom(container);

        container.innerHTML = state.messages.map(msg => `
            <div class="message ${msg.sender_type}">
                <div class="message-bubble">${escapeHtml(msg.message)}</div>
                <div class="message-time">${formatTime(msg.created_at)}</div>
            </div>
        `).join('');

        if (state.agentTyping) {
            container.innerHTML += `
                <div class="typing-indicator">
                    <span></span><span></span><span></span>
                </div>
            `;
        }

        if (wasAtBottom && state.isOpen) {
            scrollMessagesToBottom(false);
        }
    }


    /**
     * Send message
     */
    async function sendMessage() {
        const shadow = state.elements.shadow;
        const input = shadow.getElementById('message-input');
        const message = input.value.trim();

        if (!message) return;

        try {
            const response = await fetch(buildApiUrl('/send'), {
                method: 'POST',
                credentials: 'include',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                },
                body: JSON.stringify({
                    session_id: state.sessionId,
                    message: message,
                }),
            });

            if (!response.ok) {
                throw new Error('Failed to send message');
            }

            input.value = '';
            // Stop typing indicator when message is sent
            notifyTyping(false);
        } catch (error) {
            console.error('Failed to send message:', error);
            alert('Failed to send message. Please try again.');
        }
    }

    /**
     * Customer-initiated chat ending.
     */
    async function endChatSession(sendTranscript = false) {
        if (!state.sessionId || state.chatEnded) {
            return;
        }

        try {
            const response = await fetch(buildApiUrl(`/session/${state.sessionId}/end`), {
                method: 'POST',
                credentials: 'include',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                },
                body: JSON.stringify({
                    send_transcript: sendTranscript,
                }),
            });

            let notice = 'You ended the chat.';
            if (response.ok) {
                const data = await response.json();
                if (data.transcript_sent) {
                    notice = 'You ended the chat. A transcript is on its way to your email.';
                }
            }

            state.chatEnded = true;
            state.messages.push({
                sender_type: 'system',
                message: notice,
                created_at: new Date().toISOString(),
            });
            localStorage.removeItem('ticaga_chat_session_id');
            renderChatInterface();
            showRatingPrompt();
        } catch (error) {
            console.error('Failed to end chat:', error);
        }
    }

    /**
     * Start a new chat with the same guest information
     */
    async function startNewChat() {
        // Get stored guest information
        const name = localStorage.getItem('ticaga_guest_name');
        const email = localStorage.getItem('ticaga_guest_email');

        if (!name || !email) {
            // If no stored info, reset to pre-chat form
            state.sessionId = null;
            state.chatEnded = false;
            state.messages = [];
            state.queuePosition = null;
            renderPreChatForm();
            return;
        }

        try {
            // Start a new session with stored credentials
            const session = await startChatSession(name, email);
            state.sessionId = session.id;
            state.queuePosition = session.queue_position;
            state.sessionStartedAt = session.started_at || new Date().toISOString();
            state.chatEnded = false;
            state.messages = [];

            // Save new session ID
            localStorage.setItem('ticaga_chat_session_id', session.id);

            // Fetch initial messages
            try {
                const sessionData = await fetch(buildApiUrl(`/session/${session.id}`), {
                    credentials: 'include',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest',
                        'X-Widget-Key': config.widgetKey
                    }
                }).then(r => r.json());

                if (sessionData.messages) {
                    state.messages = sessionData.messages;
                }
            } catch (e) {
                console.debug('Failed to fetch initial messages:', e);
            }

            // Switch to chat interface
            renderChatInterface();

            // Subscribe to chat channel
            if (state.echo) {
                subscribeToChat(session.id);
            }

            if (state.queuePosition !== null) {
                startQueuePolling();
            }
        } catch (error) {
            console.error('Failed to start new chat:', error);
            alert('Failed to start a new chat. Please try again.');
        }
    }

    /**
     * Continue the current ended chat session
     */
    function continueChat() {
        if (!state.sessionId) {
            return;
        }

        // Simply reopen the chat by unsetting the ended flag
        state.chatEnded = false;

        // Restore session ID in localStorage
        localStorage.setItem('ticaga_chat_session_id', state.sessionId);

        // Re-render interface with input enabled
        renderChatInterface();

        // Reconnect WebSocket if needed
        if (state.echo) {
            subscribeToChat(state.sessionId);
        }

        // Scroll to bottom to show latest messages
        setTimeout(() => {
            scrollMessagesToBottom(true);
        }, 100);
    }

    /**
     * Handle typing input event
     */
    function handleTyping() {
        // If not already marked as typing, notify server
        if (!state.guestTyping) {
            notifyTyping(true);
            state.guestTyping = true;
        }

        // Clear existing timeout
        if (state.typingTimeout) {
            clearTimeout(state.typingTimeout);
        }

        // Set timeout to stop typing indicator after 3 seconds of no input
        state.typingTimeout = setTimeout(() => {
            notifyTyping(false);
            state.guestTyping = false;
        }, 3000);
    }

    /**
     * Notify server about typing status
     */
    async function notifyTyping(isTyping) {
        if (!state.sessionId) return;

        try {
            await fetch(buildApiUrl('/typing'), {
                method: 'POST',
                credentials: 'include',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                },
                body: JSON.stringify({
                    session_id: state.sessionId,
                    is_typing: isTyping,
                }),
            });
        } catch (error) {
            // Silently fail - typing indicator is not critical
            console.debug('Failed to notify typing status:', error);
        }
    }

    /**
     * Subscribe to chat channel
     */
    function subscribeToChat(sessionId) {
        console.log('[LiveChat] Subscribing to channel:', `chat.${sessionId}`);

        // Log WebSocket connection state
        if (state.echo.connector && state.echo.connector.pusher) {
            const pusher = state.echo.connector.pusher;
            console.log('[LiveChat] Pusher state:', pusher.connection.state);

            pusher.connection.bind('state_change', (states) => {
                console.log('[LiveChat] Connection state changed:', states.previous, '->', states.current);
            });

            pusher.connection.bind('error', (err) => {
                console.error('[LiveChat] Connection error:', err);
            });
        }

        state.echo.private(`chat.${sessionId}`)
            .listen('.MessageSent', (e) => {
                console.log('[LiveChat] Message received:', e);
                handleIncomingMessage(e);
            })
            .listen('.AgentTyping', (e) => {
                state.agentTyping = e.is_typing;
                renderMessages();
            })
            .listen('.AgentJoined', (e) => {
                state.queuePosition = null;
                updateQueueBanner();
                renderMessages();
            })
            .listen('.ChatEnded', (e) => {
                // Only add message if chat wasn't already ended locally (prevents duplicate)
                if (!state.chatEnded) {
                    state.chatEnded = true;
                    state.messages.push({
                        sender_type: 'system',
                        message: 'This chat has ended. Thank you!',
                        created_at: new Date().toISOString(),
                    });
                    localStorage.removeItem('ticaga_chat_session_id');
                    renderChatInterface();

                    // Show rating prompt
                    setTimeout(() => {
                        showRatingPrompt();
                    }, 1000);
                }
            });
    }

    function handleIncomingMessage(msg) {
        const el = state.elements.messagesEl || (state.elements.shadow && state.elements.shadow.getElementById('chat-messages'));
        const wasAtBottom = isNearBottom(el);

        state.messages.push(msg);

        // If the employee sends a message and customer isn't at bottom / widget closed → unread
        if (msg.sender_type === 'agent') {
            if (!wasAtBottom || !state.isOpen) {
                state.unreadCount += 1;
                updateUnreadBadge();
                if (!state.isOpen) {
                    playIncomingSound();
                }
                if (state.isOpen && !wasAtBottom) {
                    showNewMessagesButton();
                }
            }
        }

        renderMessages();

        if (state.isOpen && wasAtBottom) {
            scrollMessagesToBottom();
        }
    }

    function playIncomingSound() {
        try {
            const audio = document.getElementById('ticaga-livechat-new-message-sound');
            if (audio) {
                audio.play().catch(() => {});
            }
        } catch (e) {
            console.debug('LiveChat sound error:', e);
        }
    }

    /**
     * Show rating prompt
     */
    function showRatingPrompt() {
        const shadow = state.elements.shadow;
        const chatWindow = shadow.querySelector('.chat-window');

        // Check if already rated
        const ratedSessions = JSON.parse(localStorage.getItem('ticaga_rated_sessions') || '[]');
        if (ratedSessions.includes(state.sessionId)) {
            return;
        }

        let ratingContainer = shadow.querySelector('.rating-container');
        if (!ratingContainer) {
            ratingContainer = document.createElement('div');
            ratingContainer.className = 'rating-container';
            ratingContainer.innerHTML = `
                <div class="rating-title">How was your experience?</div>
                <div class="rating-stars">
                    ${[1, 2, 3, 4, 5].map(i => `<span class="rating-star" data-rating="${i}">★</span>`).join('')}
                </div>
            `;
            chatWindow.appendChild(ratingContainer);

            // Attach rating click handlers
            ratingContainer.querySelectorAll('.rating-star').forEach(star => {
                star.addEventListener('click', () => submitRating(parseInt(star.dataset.rating)));
                star.addEventListener('mouseenter', () => {
                    const rating = parseInt(star.dataset.rating);
                    ratingContainer.querySelectorAll('.rating-star').forEach((s, i) => {
                        s.classList.toggle('active', i < rating);
                    });
                });
            });
            ratingContainer.addEventListener('mouseleave', () => {
                ratingContainer.querySelectorAll('.rating-star').forEach(s => s.classList.remove('active'));
            });
        }
    }

    /**
     * Submit chat rating
     */
    async function submitRating(rating) {
        try {
            const response = await fetch(buildApiUrl('/rate'), {
                method: 'POST',
                credentials: 'include',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                },
                body: JSON.stringify({
                    session_id: state.sessionId,
                    rating: rating,
                }),
            });

            if (response.ok) {
                const shadow = state.elements.shadow;
                const ratingContainer = shadow.querySelector('.rating-container');
                ratingContainer.innerHTML = `
                    <div class="rating-thanks">
                        ✓ Thank you for your feedback!
                    </div>
                `;

                // Mark as rated
                const ratedSessions = JSON.parse(localStorage.getItem('ticaga_rated_sessions') || '[]');
                ratedSessions.push(state.sessionId);
                localStorage.setItem('ticaga_rated_sessions', JSON.stringify(ratedSessions));

                setTimeout(() => {
                    localStorage.removeItem('ticaga_chat_session_id');
                }, 2000);
            }
        } catch (error) {
            console.error('Failed to submit rating:', error);
        }
    }

    /**
     * View chat history
     */
    async function viewChatHistory(email = null) {
        try {
            // Validate email parameter - reject if it's not a string
            if (email && typeof email !== 'string') {
                console.warn('[viewChatHistory] Invalid email parameter received, ignoring:', email);
                email = null;
            }

            // If no email provided, try to load from localStorage
            if (!email) {
                email = localStorage.getItem('ticaga_history_email') || localStorage.getItem('ticaga_guest_email') || null;

                // Validate localStorage value - clean up if it contains invalid data
                if (email && (typeof email !== 'string' || email.includes('[object'))) {
                    console.warn('[viewChatHistory] Invalid email in localStorage, clearing:', email);
                    localStorage.removeItem('ticaga_history_email');
                    email = null;
                }
            }

            // Build URL with widget_key (already included by buildApiUrl)
            let url = buildApiUrl('/history');

            // Add email parameter if provided
            if (email) {
                url += `&email=${encodeURIComponent(email)}`;
            }

            const response = await fetch(url, {
                credentials: 'include',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                }
            });

            if (!response.ok) {
                throw new Error('Failed to fetch chat history');
            }

            const history = await response.json();
            renderChatHistory(history, email);
        } catch (error) {
            console.error('Failed to load chat history:', error);
            alert('Failed to load chat history. Please try again.');
        }
    }

    /**
     * Render chat history view
     */
    function renderChatHistory(history, email = null) {
        const shadow = state.elements.shadow;
        const content = shadow.getElementById('chat-content');

        // Sanitize email parameter - ensure it's a string or null
        if (email && typeof email !== 'string') {
            console.warn('[History] Invalid email parameter received:', email);
            email = null;
        }

        // Email lookup form HTML (shown in both empty and populated states)
        const emailLookupForm = `
            <div style="background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin-bottom: 16px;">
                <form id="email-lookup-form" style="margin: 0;">
                    <label style="display: block; font-size: 13px; font-weight: 500; color: #374151; margin-bottom: 8px;">
                        View chat history for email address:
                    </label>
                    <div style="display: flex; gap: 8px;">
                        <input
                            type="email"
                            id="history-email"
                            placeholder="your.email@example.com"
                            value="${email || localStorage.getItem('ticaga_history_email') || localStorage.getItem('ticaga_guest_email') || ''}"
                            required
                            style="flex: 1; padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; outline: none; transition: border-color 0.2s;"
                            onfocus="this.style.borderColor='${config.themeColor}'"
                            onblur="this.style.borderColor='#d1d5db'"
                        >
                        <button type="submit" class="btn-primary" style="padding: 8px 16px; white-space: nowrap; border: none; border-radius: 6px; background: ${config.themeColor}; color: white; font-weight: 500; cursor: pointer;">
                            Search
                        </button>
                    </div>
                </form>
            </div>
        `;

        if (!history || history.length === 0) {
            content.innerHTML = `
                <div class="chat-messages" style="padding: 16px;">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
                        <h4 style="font-size: 16px; font-weight: 600; color: #1f2937; margin: 0;">Chat History</h4>
                        <button id="back-to-start" style="background: none; border: none; color: ${config.themeColor}; cursor: pointer; font-size: 14px; font-weight: 500;">
                            ← Back
                        </button>
                    </div>
                    ${emailLookupForm}
                    <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 20px;">
                        <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" style="margin-bottom: 16px;">
                            <path stroke-linecap="round" stroke-linejoin="round" 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"></path>
                        </svg>
                        <h4 style="color: #1f2937; margin-bottom: 8px; font-size: 16px; font-weight: 600;">No Chat History Found</h4>
                        <p style="color: #6b7280; font-size: 14px; text-align: center;">
                            ${email ? 'No previous chat sessions found for this email address.' : 'Enter your email address above to view your chat history.'}
                        </p>
                    </div>
                </div>
            `;

            // Attach event listeners
            shadow.getElementById('back-to-start').addEventListener('click', () => {
                const chatWindow = state.elements.shadow.querySelector('.chat-window');
                chatWindow.innerHTML = getChatWindowHTML();
                attachEventListeners();
            });

            shadow.getElementById('email-lookup-form').addEventListener('submit', async (e) => {
                e.preventDefault();
                const emailInput = shadow.getElementById('history-email');
                const email = emailInput.value.trim();
                if (email) {
                    await viewChatHistory(email);
                }
            });
            return;
        }

        // Render sessions list with improved design
        const sessionsHtml = history.map(session => {
            const statusColor = {
                'active': 'background: #dcfce7; color: #166534; border-color: #86efac;',
                'waiting': 'background: #fef3c7; color: #92400e; border-color: #fcd34d;',
                'ended': 'background: #e5e7eb; color: #1f2937; border-color: #d1d5db;',
                'converted': 'background: #dbeafe; color: #1e40af; border-color: #93c5fd;',
                'abandoned': 'background: #fee2e2; color: #991b1b; border-color: #fca5a5;'
            }[session.status] || 'background: #e5e7eb; color: #1f2937; border-color: #d1d5db;';

            const startedDate = new Date(session.started_at);
            const endedDate = session.ended_at ? new Date(session.ended_at) : null;
            const duration = endedDate ? Math.round((endedDate - startedDate) / 60000) : null;

            return `
                <div class="history-session" style="background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 14px; margin-bottom: 12px; transition: all 0.2s; cursor: pointer;" onmouseover="this.style.boxShadow='0 2px 8px rgba(0,0,0,0.08)'; this.style.borderColor='${config.themeColor}30';" onmouseout="this.style.boxShadow='none'; this.style.borderColor='#e5e7eb';">
                    <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px;">
                        <div style="flex: 1;">
                            <div style="font-weight: 600; color: #1f2937; font-size: 14px; margin-bottom: 4px;">
                                Chat #${session.id}
                            </div>
                            <div style="font-size: 12px; color: #6b7280;">
                                ${startedDate.toLocaleDateString()} at ${startedDate.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
                                ${duration ? `<span style="color: #9ca3af;"> • ${duration} min</span>` : ''}
                            </div>
                        </div>
                        <span style="padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 600; white-space: nowrap; border: 1px solid; ${statusColor}">
                            ${session.status.charAt(0).toUpperCase() + session.status.slice(1)}
                        </span>
                    </div>

                    <div style="display: flex; align-items: center; gap: 12px; font-size: 12px; color: #6b7280; margin-bottom: 10px; padding: 8px 0; border-top: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb;">
                        <span style="display: flex; align-items: center; gap: 4px;">
                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
                            </svg>
                            ${session.message_count || 0} messages
                        </span>
                        ${session.agent_name ? `
                            <span style="display: flex; align-items: center; gap: 4px;">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
                                    <circle cx="12" cy="7" r="4"></circle>
                                </svg>
                                ${escapeHtml(session.agent_name)}
                            </span>
                        ` : ''}
                        ${session.rating ? `
                            <span style="display: flex; align-items: center; gap: 4px; color: #f59e0b;">
                                ${'★'.repeat(session.rating)}${'☆'.repeat(5 - session.rating)}
                            </span>
                        ` : ''}
                    </div>

                    <div style="display: flex; gap: 8px;">
                        ${session.status === 'active' || session.status === 'waiting' ? `
                            <button class="btn-primary history-resume-btn" data-session-id="${session.id}" style="flex: 1; padding: 8px 12px; font-size: 13px; font-weight: 500; border: none; border-radius: 6px; background: ${config.themeColor}; color: white; cursor: pointer;">
                                Resume Chat
                            </button>
                        ` : `
                            <button class="btn-primary history-continue-btn" data-session-id="${session.id}" style="flex: 1; padding: 8px 12px; font-size: 13px; font-weight: 500; border: none; border-radius: 6px; background: ${config.themeColor}; color: white; cursor: pointer;">
                                Continue Conversation
                            </button>
                            <button class="btn-link history-view-btn" data-session-id="${session.id}" style="flex: 1; padding: 8px 12px; font-size: 13px; font-weight: 500; border: 1px solid ${config.themeColor}; border-radius: 6px; background: white; color: ${config.themeColor}; cursor: pointer;">
                                View Only
                            </button>
                        `}
                    </div>
                </div>
            `;
        }).join('');

        content.innerHTML = `
            <div class="chat-messages" style="padding: 16px;">
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
                    <h4 style="font-size: 16px; font-weight: 600; color: #1f2937; margin: 0;">Your Chat History</h4>
                    <button id="back-to-start" style="background: none; border: none; color: ${config.themeColor}; cursor: pointer; font-size: 14px; font-weight: 500;">
                        ← Back
                    </button>
                </div>
                ${emailLookupForm}
                <div style="max-height: calc(100vh - 250px); overflow-y: auto;">
                    ${sessionsHtml}
                </div>
            </div>
        `;

        // Attach event listeners
        shadow.getElementById('back-to-start').addEventListener('click', () => {
            const chatWindow = state.elements.shadow.querySelector('.chat-window');
            chatWindow.innerHTML = getChatWindowHTML();
            attachEventListeners();
        });

        shadow.getElementById('email-lookup-form').addEventListener('submit', async (e) => {
            e.preventDefault();
            const emailInput = shadow.getElementById('history-email');
            const email = emailInput.value.trim();
            if (email) {
                // Store email in localStorage for future history lookups
                localStorage.setItem('ticaga_history_email', email);
                await viewChatHistory(email);
            }
        });

        // Add event listeners for history session buttons
        shadow.querySelectorAll('.history-resume-btn').forEach(btn => {
            btn.addEventListener('click', async () => {
                const sessionId = btn.getAttribute('data-session-id');
                await resumeSession(sessionId);
            });
        });

        shadow.querySelectorAll('.history-continue-btn').forEach(btn => {
            btn.addEventListener('click', async () => {
                const sessionId = btn.getAttribute('data-session-id');
                await continueHistorySession(sessionId);
            });
        });

        shadow.querySelectorAll('.history-view-btn').forEach(btn => {
            btn.addEventListener('click', async () => {
                const sessionId = btn.getAttribute('data-session-id');
                await loadSessionTranscript(sessionId);
            });
        });
    }

    /**
     * Continue an ended chat session from history
     */
    async function continueHistorySession(sessionId) {
        try {
            // Load the session data
            const response = await fetch(buildApiUrl(`/session/${sessionId}`), {
                credentials: 'include',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                }
            });

            if (!response.ok) {
                throw new Error('Failed to load session');
            }

            const session = await response.json();

            // Set up state for continuing this session
            state.sessionId = sessionId;
            state.messages = session.messages || [];
            state.chatEnded = false;
            state.queuePosition = null;
            state.sessionStartedAt = session.started_at || new Date().toISOString();

            // Save session ID to localStorage
            localStorage.setItem('ticaga_chat_session_id', sessionId);

            // Render chat interface
            renderChatInterface();

            // Connect to WebSocket for real-time updates
            if (state.echo) {
                subscribeToChat(sessionId);
            }

            // Scroll to bottom
            setTimeout(() => {
                scrollMessagesToBottom(true);
            }, 100);
        } catch (error) {
            console.error('Failed to continue chat session:', error);
            alert('Failed to continue this conversation. Please try again.');
        }
    }

    /**
     * Load and display a single session transcript
     */
    async function loadSessionTranscript(sessionId) {
        try {
            const response = await fetch(buildApiUrl(`/session/${sessionId}`), {
                credentials: 'include',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-Widget-Key': config.widgetKey
                }
            });

            if (!response.ok) {
                throw new Error('Failed to load session');
            }

            const session = await response.json();
            const shadow = state.elements.shadow;
            const content = shadow.getElementById('chat-content');

            content.innerHTML = `
                <div class="chat-messages" style="padding: 16px;">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; padding-bottom: 12px; border-bottom: 1px solid #e5e7eb;">
                        <div>
                            <h4 style="font-size: 16px; font-weight: 600; color: #1f2937; margin: 0 0 4px 0;">Chat Transcript</h4>
                            <p style="font-size: 12px; color: #6b7280; margin: 0;">
                                ${new Date(session.started_at).toLocaleDateString()} at ${new Date(session.started_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
                            </p>
                        </div>
                        <button id="back-to-history" style="background: none; border: none; color: ${config.themeColor}; cursor: pointer; font-size: 14px; font-weight: 500;">
                            ← Back
                        </button>
                    </div>
                    <div id="transcript-messages" style="max-height: calc(100vh - 250px); overflow-y: auto;">
                        ${(session.messages || []).map(msg => `
                            <div class="message ${msg.sender_type}">
                                <div class="message-bubble">${escapeHtml(msg.message)}</div>
                                <div class="message-time">${formatTime(msg.created_at)}</div>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `;

            shadow.getElementById('back-to-history').addEventListener('click', viewChatHistory);
        } catch (error) {
            console.error('Failed to load session transcript:', error);
            alert('Failed to load chat transcript. Please try again.');
        }
    }

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

    function formatTime(timestamp) {
        const date = new Date(timestamp);
        return date.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', hour12: false });
    }

    /**
     * Get SVG icon based on icon name
     */
    function getIconSvg(iconName) {
        const icons = {
            'chat': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" 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"></path></svg>',
            'chat-bubble-left': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 011.037-.443 48.282 48.282 0 005.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"></path></svg>',
            'chat-bubble-left-right': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 01-.825-.242m9.345-8.334a2.126 2.126 0 00-.476-.095 48.64 48.64 0 00-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0011.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155"></path></svg>',
            'chat-bubble-left-ellipsis': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375m-13.5 3.01c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 01.778-.332 48.294 48.294 0 005.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"></path></svg>',
            'chat-bubble-oval-left': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 20.25c4.97 0 9-3.694 9-8.25s-4.03-8.25-9-8.25S3 7.444 3 12c0 2.104.859 4.023 2.273 5.48.432.447.74 1.04.586 1.641a4.483 4.483 0 01-.923 1.785A5.969 5.969 0 006 21c1.282 0 2.47-.402 3.445-1.087.81.22 1.668.337 2.555.337z"></path></svg>',
            'chat-bubble-oval-left-ellipsis': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z"></path></svg>',
            'chat-bubble-bottom-center': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"></path></svg>',
            'chat-bubble-bottom-center-text': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"></path></svg>',
            'message': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>',
            'envelope': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 19v-8.93a2 2 0 01.89-1.664l7-4.666a2 2 0 012.22 0l7 4.666A2 2 0 0121 10.07V19M3 19a2 2 0 002 2h14a2 2 0 002-2M3 19l6.75-4.5M21 19l-6.75-4.5M3 10l6.75 4.5M21 10l-6.75 4.5m0 0l-1.14.76a2 2 0 01-2.22 0l-1.14-.76"></path></svg>',
            'envelope-open': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 9v.906a2.25 2.25 0 01-1.183 1.981l-6.478 3.488M2.25 9v.906a2.25 2.25 0 001.183 1.981l6.478 3.488m8.839 2.51l-4.66-2.51m0 0l-1.023-.55a2.25 2.25 0 00-2.134 0l-1.022.55m0 0l-4.661 2.51m16.5 1.615a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V8.844a2.25 2.25 0 011.183-1.98l7.5-4.04a2.25 2.25 0 012.134 0l7.5 4.04a2.25 2.25 0 011.183 1.98V19.5z"></path></svg>',
            'support': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>',
            'lifebuoy': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M16.712 4.33a9.027 9.027 0 011.652 1.306c.51.51.944 1.064 1.306 1.652M16.712 4.33l-3.448 4.138m3.448-4.138a9.014 9.014 0 00-9.424 0M19.67 7.288l-4.138 3.448m4.138-3.448a9.014 9.014 0 010 9.424m-4.138-5.976a3.736 3.736 0 00-.88-1.388 3.737 3.737 0 00-1.388-.88m2.268 2.268a3.765 3.765 0 010 2.528m-2.268-4.796a3.765 3.765 0 00-2.528 0m4.796 4.796c-.181.506-.475.982-.88 1.388a3.736 3.736 0 01-1.388.88m2.268-2.268l4.138 3.448m0 0a9.027 9.027 0 01-1.306 1.652c-.51.51-1.064.944-1.652 1.306m0 0l-3.448-4.138m3.448 4.138a9.014 9.014 0 01-9.424 0m5.976-4.138a3.765 3.765 0 01-2.528 0m0 0a3.736 3.736 0 01-1.388-.88 3.737 3.737 0 01-.88-1.388m2.268 2.268L7.288 19.67m0 0a9.024 9.024 0 01-1.652-1.306 9.027 9.027 0 01-1.306-1.652m0 0l4.138-3.448M4.33 16.712a9.014 9.014 0 010-9.424m4.138 5.976a3.765 3.765 0 010-2.528m0 0c.181-.506.475-.982.88-1.388a3.736 3.736 0 011.388-.88m-2.268 2.268L4.33 7.288m6.406 1.18L7.288 4.33m0 0a9.024 9.024 0 00-1.652 1.306A9.025 9.025 0 004.33 7.288"></path></svg>',
            'help': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
            'information-circle': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"></path></svg>',
            'question': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
            'headset': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 3.5C9 2.67157 9.67157 2 10.5 2H13.5C14.3284 2 15 2.67157 15 3.5V4.5C17.3869 5.37764 19 7.54432 19 10V14C19 14.5523 18.5523 15 18 15H17C15.8954 15 15 14.1046 15 13V11C15 9.89543 15.8954 9 17 9H17.5C17.2239 7.20871 15.7663 5.75108 13.975 5.47501C13.4376 5.38969 13 4.93833 13 4.39494V3.5C13 3.22386 12.7761 3 12.5 3H11.5C11.2239 3 11 3.22386 11 3.5V4.39494C11 4.93833 10.5624 5.38969 10.025 5.47501C8.23367 5.75108 6.77614 7.20871 6.5 9H7C8.10457 9 9 9.89543 9 11V13C9 14.1046 8.10457 15 7 15H6C5.44772 15 5 14.5523 5 14V10C5 7.54432 6.61307 5.37764 9 4.5V3.5Z"></path><path stroke-linecap="round" stroke-linejoin="round" d="M6 15C6 17.2091 7.79086 19 10 19H11"></path></svg>',
            'phone': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"></path></svg>',
            'user': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path></svg>',
            'sparkles': '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z"></path></svg>',
        };

        return icons[iconName] || icons['chat']; // Default to 'chat' if icon not found
    }

    // Expose global API for programmatic access (needed for mobile header button)
    window.TicagaChat = {
        openChat: function() {
            if (!state.isOpen) {
                toggleChat();
            }
        },
        closeChat: function() {
            if (state.isOpen) {
                toggleChat();
            }
        },
        isOpen: function() {
            return state.isOpen;
        }
    };

    // Initialize widget on DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})(); 