/**
 * Advanced Messenger Application
 * Real-time messaging with modern UI/UX
 */
class MessengerApp {
    constructor(config) {
        this.config = {
            apiBase: config.apiBase || '/api/v1/messenger',
            currentUserId: config.currentUserId,
            currentUser: config.currentUser,
            longPollTimeout: 25000,
            reconnectDelay: 3000,
            typingTimeout: 3000,
            messageLimit: 50,
            ...config
        };

        // State management
        this.state = {
            conversations: new Map(),
            messages: new Map(),
            currentConversation: null,
            isTyping: new Set(),
            typingTimeout: null,
            longPollController: null,
            lastEventId: 0,
            isConnected: false,
            isLoading: false,
            searchQuery: '',
            unreadCounts: new Map()
        };

        // UI elements
        this.elements = {
            conversationList: document.getElementById('conversation-list'),
            messagesContainer: document.getElementById('messages-container'),
            messageInput: document.getElementById('message-input'),
            sendBtn: document.getElementById('send-btn'),
            chatHeader: document.getElementById('chat-header'),
            messageComposer: document.getElementById('message-composer'),
            emptyState: document.getElementById('empty-state'),
            emojiPicker: document.getElementById('emoji-picker'),
            emojiGrid: document.getElementById('emoji-grid')
        };

        // Initialize
        this.init();
    }

    async init() {
        console.log('🚀 Initializing Advanced Messenger...');
        
        try {
            this.setupEventListeners();
            this.initializeEmojis();
            await this.loadConversations();
            this.startLongPolling();
            
            // Show success message
            this.showNotification('Messenger connected successfully!', 'success');
            this.state.isConnected = true;
            
            console.log('✅ Messenger initialized successfully');
        } catch (error) {
            console.error('❌ Failed to initialize messenger:', error);
            this.showNotification('Failed to connect to messenger', 'error');
        }
    }

    setupEventListeners() {
        // Search conversations
        document.getElementById('conversation-search').addEventListener('input', (e) => {
            this.searchConversations(e.target.value);
        });

        // Message input auto-expand
        this.elements.messageInput.addEventListener('input', () => {
            this.handleTyping();
            this.autoResizeInput();
        });

        // Keyboard shortcuts
        document.addEventListener('keydown', (e) => {
            this.handleKeyboardShortcuts(e);
        });

        // Visibility change (tab focus)
        document.addEventListener('visibilitychange', () => {
            if (!document.hidden && this.state.currentConversation) {
                this.markMessagesAsRead(this.state.currentConversation);
            }
        });

        // Online/offline detection
        window.addEventListener('online', () => {
            this.showNotification('Connection restored', 'success');
            this.startLongPolling();
        });

        window.addEventListener('offline', () => {
            this.showNotification('Connection lost', 'warning');
            this.stopLongPolling();
        });
    }

    async apiCall(endpoint, options = {}) {
        const url = this.config.apiBase + endpoint;
        const config = {
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'),
                'X-Requested-With': 'XMLHttpRequest',
                ...options.headers
            },
            credentials: 'same-origin',
            ...options
        };

        if (config.body && !(config.body instanceof FormData)) {
            config.body = JSON.stringify(config.body);
        }

        console.log('API Call:', {
            url: url,
            method: config.method || 'GET',
            headers: config.headers,
            body: config.body
        });

        try {
            const response = await fetch(url, config);
            console.log('API Response:', {
                status: response.status,
                statusText: response.statusText,
                headers: Object.fromEntries(response.headers.entries()),
                ok: response.ok
            });
            
            if (response.status === 419) {
                // CSRF token mismatch
                console.error('CSRF token mismatch, reloading page');
                location.reload();
                return;
            }

            const data = await response.json();
            console.log('API Response Data:', data);
            
            if (!response.ok && response.status !== 204) {
                throw new Error(data.message || `HTTP ${response.status}`);
            }
            
            return data;
        } catch (error) {
            console.error('API Error:', error);
            console.error('Error details:', {
                message: error.message,
                stack: error.stack,
                name: error.name
            });
            
            if (error.name === 'TypeError' && error.message.includes('fetch')) {
                this.showNotification('Network error - check your connection', 'error');
            } else {
                this.showNotification(error.message, 'error');
            }
            
            throw error;
        }
    }

    async loadConversations() {
        this.setLoading(true);
        
        try {
            const response = await this.apiCall('/conversations');
            const conversations = response.data || [];
            
            this.state.conversations.clear();
            conversations.forEach(conv => {
                this.state.conversations.set(conv.id, conv);
                this.state.unreadCounts.set(conv.id, conv.unread_count || 0);
            });
            
            this.renderConversations();
            
            if (conversations.length === 0) {
                this.showEmptyConversations();
            }
            
        } catch (error) {
            console.error('Failed to load conversations:', error);
            this.showNotification('Failed to load conversations', 'error');
        } finally {
            this.setLoading(false);
        }
    }

    renderConversations() {
        const conversations = Array.from(this.state.conversations.values());
        
        // Filter by search query
        const filteredConversations = conversations.filter(conv => {
            if (!this.state.searchQuery) return true;
            const query = this.state.searchQuery.toLowerCase();
            return conv.title?.toLowerCase().includes(query) ||
                   conv.last_message?.content?.toLowerCase().includes(query);
        });

        // Sort by last activity
        filteredConversations.sort((a, b) => 
            new Date(b.last_activity_at) - new Date(a.last_activity_at)
        );

        this.elements.conversationList.innerHTML = filteredConversations.map(conv => 
            this.renderConversationItem(conv)
        ).join('');
    }

    renderConversationItem(conversation) {
        const unreadCount = this.state.unreadCounts.get(conversation.id) || 0;
        const isActive = this.state.currentConversation === conversation.id;
        const lastMessage = conversation.last_message;
        const timeAgo = this.formatTimeAgo(conversation.last_activity_at);
        
        const initials = this.getInitials(conversation.title || 'Unknown');
        const onlineStatus = Math.random() > 0.5; // Mock online status
        
        return `
            <div class="conversation-item ${isActive ? 'active' : ''}" 
                 onclick="messenger.selectConversation(${conversation.id})"
                 data-conversation-id="${conversation.id}">
                <div class="conversation-avatar">
                    ${conversation.avatar ? 
                        `<img src="${conversation.avatar}" alt="${conversation.title}" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;">` :
                        initials
                    }
                    ${onlineStatus && conversation.type === 'dm' ? '<div class="online-indicator"></div>' : ''}
                </div>
                <div class="conversation-info">
                    <h4 class="conversation-title">
                        ${conversation.title || 'Unknown Chat'}
                        ${conversation.is_group ? '<i class="fas fa-users" style="font-size: 12px; margin-left: 5px; opacity: 0.7;"></i>' : ''}
                    </h4>
                    <p class="conversation-preview">
                        ${lastMessage?.content || 'No messages yet'}
                    </p>
                </div>
                <div class="conversation-meta">
                    <div class="conversation-time">${timeAgo}</div>
                    ${unreadCount > 0 ? `<div class="unread-badge">${unreadCount > 99 ? '99+' : unreadCount}</div>` : ''}
                </div>
            </div>
        `;
    }

    async selectConversation(conversationId) {
        if (this.state.currentConversation === conversationId) return;
        
        // Update UI state
        this.state.currentConversation = conversationId;
        this.updateConversationSelection();
        
        // Load messages
        await this.loadMessages(conversationId);
        
        // Mark as read
        this.markMessagesAsRead(conversationId);
        
        // Show chat interface
        this.showChatInterface();
        
        // Update header
        const conversation = this.state.conversations.get(conversationId);
        this.updateChatHeader(conversation);
    }

    updateConversationSelection() {
        // Update active state in sidebar
        this.elements.conversationList.querySelectorAll('.conversation-item').forEach(item => {
            const convId = parseInt(item.dataset.conversationId);
            item.classList.toggle('active', convId === this.state.currentConversation);
        });
    }

    async loadMessages(conversationId) {
        this.setLoading(true);
        
        try {
            const response = await this.apiCall(`/conversations/${conversationId}/messages`);
            const messages = response.data || [];
            
            this.state.messages.set(conversationId, messages);
            this.renderMessages(messages);
            this.scrollToBottom();
            
        } catch (error) {
            console.error('Failed to load messages:', error);
            this.showNotification('Failed to load messages', 'error');
        } finally {
            this.setLoading(false);
        }
    }

    renderMessages(messages) {
        if (!messages || messages.length === 0) {
            this.elements.messagesContainer.innerHTML = `
                <div class="empty-state">
                    <div class="empty-icon"><i class="fas fa-comment-alt"></i></div>
                    <h4>No messages yet</h4>
                    <p>Start the conversation by sending a message!</p>
                </div>
            `;
            return;
        }

        // Group messages by user and time
        const groupedMessages = this.groupMessages(messages);
        
        this.elements.messagesContainer.innerHTML = groupedMessages.map(group => 
            this.renderMessageGroup(group)
        ).join('');

        // Add typing indicators
        this.renderTypingIndicators();
    }

    groupMessages(messages) {
        const groups = [];
        let currentGroup = null;
        
        messages.forEach(message => {
            const shouldStartNewGroup = !currentGroup || 
                currentGroup.userId !== message.user.id ||
                (new Date(message.created_at) - new Date(currentGroup.lastTime)) > 300000; // 5 minutes
            
            if (shouldStartNewGroup) {
                currentGroup = {
                    userId: message.user.id,
                    user: message.user,
                    messages: [],
                    lastTime: message.created_at
                };
                groups.push(currentGroup);
            }
            
            currentGroup.messages.push(message);
            currentGroup.lastTime = message.created_at;
        });
        
        return groups;
    }

    renderMessageGroup(group) {
        const isOwn = group.userId === this.config.currentUserId;
        const initials = this.getInitials(group.user.full_name || group.user.username);
        
        return `
            <div class="message-group">
                ${group.messages.map(message => `
                    <div class="message ${isOwn ? 'own' : ''}" data-message-id="${message.id}">
                        ${!isOwn ? `
                            <div class="message-avatar">
                                ${group.user.avatar ? 
                                    `<img src="${group.user.avatar}" alt="${group.user.full_name}" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;">` :
                                    initials
                                }
                            </div>
                        ` : ''}
                        <div class="message-content">
                            ${this.renderMessageContent(message)}
                            <div class="message-time">${this.formatMessageTime(message.created_at)}</div>
                        </div>
                        ${isOwn ? `
                            <div class="message-avatar">
                                ${this.config.currentUser.avatar ? 
                                    `<img src="${this.config.currentUser.avatar}" alt="${this.config.currentUser.full_name}" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;">` :
                                    this.getInitials(this.config.currentUser.full_name || this.config.currentUser.username)
                                }
                            </div>
                        ` : ''}
                    </div>
                `).join('')}
            </div>
        `;
    }

    renderMessageContent(message) {
        let content = `<p class="message-text">${this.escapeHtml(message.content)}</p>`;
        
        // Add reply indicator
        if (message.reply_to) {
            content = `
                <div class="message-reply" style="border-left: 3px solid #667eea; padding-left: 10px; margin-bottom: 8px; opacity: 0.8;">
                    <small>Replying to: ${this.escapeHtml(message.reply_to.content.substring(0, 50))}...</small>
                </div>
                ${content}
            `;
        }
        
        // Add attachments
        if (message.attachments && message.attachments.length > 0) {
            content += this.renderAttachments(message.attachments);
        }
        
        // Add edit indicator
        if (message.is_edited) {
            content += '<small style="opacity: 0.6; font-style: italic;">(edited)</small>';
        }
        
        return content;
    }

    renderAttachments(attachments) {
        return attachments.map(attachment => {
            if (attachment.type === 'image') {
                return `
                    <div class="message-attachment">
                        <img src="${attachment.url}" alt="${attachment.name}" 
                             style="max-width: 200px; border-radius: 8px; margin-top: 8px; cursor: pointer;"
                             onclick="messenger.openImageModal('${attachment.url}')">
                    </div>
                `;
            } else {
                return `
                    <div class="message-attachment" style="margin-top: 8px;">
                        <a href="${attachment.url}" target="_blank" 
                           style="display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; background: rgba(255,255,255,0.2); padding: 8px; border-radius: 6px;">
                            <i class="fas fa-file"></i>
                            <span>${attachment.name}</span>
                            <small>(${this.formatFileSize(attachment.size)})</small>
                        </a>
                    </div>
                `;
            }
        }).join('');
    }

    renderTypingIndicators() {
        if (this.state.isTyping.size === 0) return;
        
        const typingUsers = Array.from(this.state.isTyping);
        const typingHtml = `
            <div class="typing-indicator">
                <div class="message-avatar">👤</div>
                <div>
                    <small>${typingUsers.join(', ')} ${typingUsers.length > 1 ? 'are' : 'is'} typing...</small>
                    <div class="typing-dots">
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                    </div>
                </div>
            </div>
        `;
        
        this.elements.messagesContainer.insertAdjacentHTML('beforeend', typingHtml);
        this.scrollToBottom();
    }

    async sendMessage() {
        const content = this.elements.messageInput.value.trim();
        if (!content || !this.state.currentConversation) return;
        
        const clientGeneratedId = `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        
        // Clear input and stop typing
        this.elements.messageInput.value = '';
        this.autoResizeInput();
        this.stopTyping();
        
        // Add optimistic message
        const optimisticMessage = {
            id: clientGeneratedId,
            conversation_id: this.state.currentConversation,
            user: this.config.currentUser,
            type: 'text',
            content: content,
            attachments: [],
            reply_to: null,
            is_edited: false,
            is_deleted: false,
            is_system: false,
            is_own: true,
            client_generated_id: clientGeneratedId,
            created_at: new Date().toISOString(),
            edited_at: null,
            pending: true
        };
        
        this.addOptimisticMessage(optimisticMessage);
        
        try {
            const response = await this.apiCall(`/conversations/${this.state.currentConversation}/messages`, {
                method: 'POST',
                body: { content, client_generated_id: clientGeneratedId }
            });
            
            // Replace optimistic message with real one
            this.replaceOptimisticMessage(clientGeneratedId, response.data);
            
        } catch (error) {
            console.error('Failed to send message:', error);
            this.markMessageAsFailed(clientGeneratedId);
            this.showNotification('Failed to send message', 'error');
        }
    }

    addOptimisticMessage(message) {
        const conversationMessages = this.state.messages.get(this.state.currentConversation) || [];
        conversationMessages.push(message);
        this.state.messages.set(this.state.currentConversation, conversationMessages);
        
        this.renderMessages(conversationMessages);
        this.scrollToBottom();
    }

    replaceOptimisticMessage(clientId, realMessage) {
        const conversationMessages = this.state.messages.get(this.state.currentConversation) || [];
        const index = conversationMessages.findIndex(msg => msg.client_generated_id === clientId);
        
        if (index !== -1) {
            conversationMessages[index] = realMessage;
            this.state.messages.set(this.state.currentConversation, conversationMessages);
            this.renderMessages(conversationMessages);
        }
    }

    markMessageAsFailed(clientId) {
        const messageElement = document.querySelector(`[data-message-id="${clientId}"]`);
        if (messageElement) {
            messageElement.classList.add('failed');
            messageElement.title = 'Failed to send - click to retry';
            messageElement.style.opacity = '0.5';
        }
    }

    handleTyping() {
        if (!this.state.currentConversation) return;
        
        // Clear existing timeout
        if (this.state.typingTimeout) {
            clearTimeout(this.state.typingTimeout);
        }
        
        // Send typing indicator (throttled)
        this.sendTypingIndicator(true);
        
        // Stop typing after timeout
        this.state.typingTimeout = setTimeout(() => {
            this.stopTyping();
        }, this.config.typingTimeout);
    }

    stopTyping() {
        if (this.state.typingTimeout) {
            clearTimeout(this.state.typingTimeout);
            this.state.typingTimeout = null;
        }
        
        this.sendTypingIndicator(false);
    }

    async sendTypingIndicator(isTyping) {
        if (!this.state.currentConversation) return;
        
        try {
            await this.apiCall('/typing', {
                method: 'POST',
                body: {
                    conversation_id: this.state.currentConversation,
                    is_typing: isTyping
                }
            });
        } catch (error) {
            // Typing indicators are not critical, fail silently
            console.debug('Typing indicator failed:', error);
        }
    }

    // Long polling for real-time updates
    async startLongPolling() {
        return;
        if (this.state.longPollController) {
            this.state.longPollController.abort();
        }
        
        this.state.longPollController = new AbortController();
        let consecutiveErrors = 0;
        const maxErrors = 5;
        
        while (this.state.longPollController && !this.state.longPollController.signal.aborted) {
            try {
                const response = await fetch(`${this.config.apiBase}/updates?since=${this.state.lastEventId}&timeout=25`, {
                    signal: this.state.longPollController.signal,
                    credentials: 'same-origin',
                    headers: {
                        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'),
                        'X-Requested-With': 'XMLHttpRequest'
                    }
                });
                
                // Debug logging
                console.log('Long polling response:', {
                    status: response.status,
                    statusText: response.statusText,
                    ok: response.ok,
                    headers: Object.fromEntries(response.headers.entries())
                });
                
                if (response.ok) {
                    consecutiveErrors = 0; // Reset error count on success
                    
                    try {
                        const data = await response.json();
                        if (data.data && data.data.events && data.data.events.length > 0) {
                            this.handleRealTimeEvents(data.data.events);
                            this.state.lastEventId = data.data.next_since;
                        }
                    } catch (jsonError) {
                        console.warn('Failed to parse JSON response:', jsonError);
                        // Continue with long polling even if JSON parsing fails
                    }
                } else if (response.status === 204) {
                    // No content - this is fine for long polling
                    consecutiveErrors = 0;
                } else if (response.status === 401) {
                    // Authentication error - stop long polling
                    console.warn('Authentication lost - stopping long polling');
                    this.showNotification('Authentication expired. Please refresh the page.', 'warning');
                    break;
                } else {
                    throw new Error(`HTTP ${response.status}`);
                }
                
            } catch (error) {
                if (error.name === 'AbortError') {
                    break; // Intentional abort
                }
                
                consecutiveErrors++;
                console.error(`Long polling error (${consecutiveErrors}/${maxErrors}):`, error);
                
                if (consecutiveErrors >= maxErrors) {
                    console.error('Too many consecutive errors - stopping long polling');
                    this.showNotification('Connection issues detected. Long polling stopped.', 'error');
                    break;
                }
                
                // Exponential backoff with jitter
                const delay = Math.min(this.config.reconnectDelay * Math.pow(2, consecutiveErrors - 1), 30000);
                const jitter = Math.random() * 1000;
                await new Promise(resolve => setTimeout(resolve, delay + jitter));
            }
        }
    }

    stopLongPolling() {
        if (this.state.longPollController) {
            this.state.longPollController.abort();
            this.state.longPollController = null;
        }
    }

    // Advanced UI features
    autoResizeInput() {
        const input = this.elements.messageInput;
        input.style.height = 'auto';
        input.style.height = Math.min(input.scrollHeight, 120) + 'px';
    }

    initializeEmojis() {
        const emojis = [
            '😀', '😃', '😄', '😁', '😅', '😂', '🤣', '😊',
            '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘',
            '😗', '😙', '😚', '😋', '😛', '😝', '😜', '🤪',
            '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏', '😒',
            '😞', '😔', '😟', '😕', '🙁', '☹️', '😣', '😖',
            '😫', '😩', '🥺', '😢', '😭', '😤', '😠', '😡',
            '👍', '👎', '👌', '✊', '✌️', '🤞', '🤟', '🤘',
            '❤️', '💕', '💖', '💗', '💙', '💚', '💛', '🧡',
            '💜', '🖤', '🤍', '🤎', '💔', '❣️', '💟', '💘'
        ];

        this.elements.emojiGrid.innerHTML = emojis.map(emoji => 
            `<button class="emoji-item" onclick="messenger.insertEmoji('${emoji}')">${emoji}</button>`
        ).join('');
    }

    insertEmoji(emoji) {
        const input = this.elements.messageInput;
        const start = input.selectionStart;
        const end = input.selectionEnd;
        const text = input.value;
        
        input.value = text.substring(0, start) + emoji + text.substring(end);
        input.selectionStart = input.selectionEnd = start + emoji.length;
        input.focus();
        
        this.toggleEmoji();
        this.autoResizeInput();
    }

    toggleEmoji() {
        this.elements.emojiPicker.classList.toggle('show');
    }

    // File handling
    attachFile() {
        document.getElementById('file-input').click();
    }

    attachPhoto() {
        document.getElementById('photo-input').click();
    }

    handleFileUpload(files) {
        Array.from(files).forEach(file => {
            this.uploadFile(file);
        });
    }

    handlePhotoUpload(files) {
        Array.from(files).forEach(file => {
            this.uploadFile(file, true);
        });
    }

    async uploadFile(file, isPhoto = false) {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('type', isPhoto ? 'image' : 'file');

        try {
            const response = await fetch(`${this.config.apiBase}/attachments`, {
                method: 'POST',
                body: formData,
                credentials: 'same-origin',
                headers: {
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'),
                    'X-Requested-With': 'XMLHttpRequest'
                }
            });

            if (response.ok) {
                const data = await response.json();
                this.showNotification(`${file.name} uploaded successfully`, 'success');
            } else {
                throw new Error('Upload failed');
            }
        } catch (error) {
            console.error('File upload failed:', error);
            this.showNotification(`Failed to upload ${file.name}`, 'error');
        }
    }

    // Utility methods
    getInitials(name) {
        if (!name || typeof name !== 'string') {
            return '??';
        }
        
        const words = name.trim().split(' ').filter(word => word.length > 0);
        if (words.length === 0) {
            return '??';
        }
        
        return words.map(word => word[0]).join('').toUpperCase().substring(0, 2);
    }

    formatTimeAgo(timestamp) {
        const now = new Date();
        const date = new Date(timestamp);
        const diff = now - date;
        
        const minutes = Math.floor(diff / 60000);
        const hours = Math.floor(diff / 3600000);
        const days = Math.floor(diff / 86400000);
        
        if (minutes < 1) return 'now';
        if (minutes < 60) return `${minutes}m`;
        if (hours < 24) return `${hours}h`;
        if (days < 7) return `${days}d`;
        
        return date.toLocaleDateString();
    }

    formatMessageTime(timestamp) {
        const date = new Date(timestamp);
        return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }

    formatFileSize(bytes) {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

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

    // UI state management
    showChatInterface() {
        this.elements.emptyState.style.display = 'none';
        this.elements.chatHeader.style.display = 'flex';
        this.elements.messageComposer.style.display = 'block';
    }

    updateChatHeader(conversation) {
        if (!conversation) return;
        
        document.getElementById('chat-user-name').textContent = conversation.title || 'Unknown';
        document.getElementById('chat-user-status').textContent = 
            conversation.type === 'group' ? 
            `${conversation.participants_count || 0} members` : 
            'Online';
        
        const avatar = document.getElementById('chat-avatar');
        avatar.textContent = this.getInitials(conversation.title || 'Unknown');
    }

    showEmptyConversations() {
        this.elements.conversationList.innerHTML = `
            <div style="padding: 40px 20px; text-align: center; color: rgba(255,255,255,0.7);">
                <i class="fas fa-comments" style="font-size: 3rem; margin-bottom: 15px; opacity: 0.5;"></i>
                <h4>No conversations yet</h4>
                <p>Start a new conversation to begin messaging!</p>
                <button class="btn btn-light btn-sm" onclick="messenger.newConversation()" style="margin-top: 15px;">
                    <i class="fas fa-plus"></i> New Chat
                </button>
            </div>
        `;
    }

    setLoading(isLoading) {
        this.state.isLoading = isLoading;
        document.body.classList.toggle('loading', isLoading);
    }

    scrollToBottom() {
        setTimeout(() => {
            this.elements.messagesContainer.scrollTop = this.elements.messagesContainer.scrollHeight;
        }, 100);
    }

    searchConversations(query) {
        this.state.searchQuery = query;
        this.renderConversations();
    }

    // Notifications
    showNotification(message, type = 'info') {
        const toast = document.createElement('div');
        toast.className = `alert alert-${type === 'error' ? 'danger' : type} position-fixed`;
        toast.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
        toast.innerHTML = `
            <button type="button" class="btn-close" onclick="this.parentElement.remove()"></button>
            ${message}
        `;
        
        document.body.appendChild(toast);
        
        setTimeout(() => {
            if (toast.parentElement) {
                toast.remove();
            }
        }, 5000);
    }

    showDesktopNotification(message) {
        if ('Notification' in window && Notification.permission === 'granted') {
            const conversation = this.state.conversations.get(message.conversation_id);
            new Notification(`${message.user.full_name} in ${conversation?.title || 'Chat'}`, {
                body: message.content,
                icon: message.user.avatar || '/favicon.ico'
            });
        }
    }

    // Advanced features (stubs)
    startVoiceCall() {
        this.showNotification('Voice calling feature coming soon!', 'info');
    }

    startVideoCall() {
        this.showNotification('Video calling feature coming soon!', 'info');
    }

    showOptions() {
        this.showNotification('Chat options coming soon!', 'info');
    }

    async newConversation() {
        // Create a simple modal for user selection
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed; top: 0; left: 0; width: 100%; height: 100%; 
            background: rgba(0,0,0,0.7); z-index: 10000; display: flex; 
            align-items: center; justify-content: center;
        `;
        
        modal.innerHTML = `
            <div style="background: white; padding: 30px; border-radius: 12px; max-width: 500px; width: 90%;">
                <h3 style="margin: 0 0 20px 0;">Start New Conversation</h3>
                
                <div style="margin-bottom: 20px;">
                    <label style="display: block; margin-bottom: 8px; font-weight: 600;">Search Users:</label>
                    <input type="text" id="user-search" placeholder="Type to search users..." 
                           style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px;">
                </div>
                
                <div id="user-results" style="max-height: 200px; overflow-y: auto; margin-bottom: 20px; border: 1px solid #eee; border-radius: 6px;">
                    <div style="padding: 20px; text-align: center; color: #666;">
                        Start typing to search for users...
                    </div>
                </div>
                
                <div style="margin-bottom: 20px;">
                    <label style="display: block; margin-bottom: 8px; font-weight: 600;">Conversation Type:</label>
                    <select id="conv-type" style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px;">
                        <option value="dm">Direct Message</option>
                        <option value="group">Group Chat</option>
                    </select>
                </div>
                
                <div id="group-title-field" style="margin-bottom: 20px; display: none;">
                    <label style="display: block; margin-bottom: 8px; font-weight: 600;">Group Name:</label>
                    <input type="text" id="group-title" placeholder="Enter group name..." 
                           style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px;">
                </div>
                
                <div style="display: flex; gap: 15px; justify-content: flex-end;">
                    <button id="cancel-conv" style="padding: 12px 24px; border: 1px solid #ddd; background: white; border-radius: 6px; cursor: pointer; font-size: 16px;">
                        Cancel
                    </button>
                    <button id="create-conv" style="padding: 12px 24px; border: none; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 6px; cursor: pointer; font-size: 16px;" disabled>
                        Create Conversation
                    </button>
                </div>
            </div>
        `;
        
        document.body.appendChild(modal);
        
        let selectedUsers = [];
        
        // Handle user search
        const searchInput = document.getElementById('user-search');
        const userResults = document.getElementById('user-results');
        const createBtn = document.getElementById('create-conv');
        const convType = document.getElementById('conv-type');
        const groupTitleField = document.getElementById('group-title-field');
        
        // Show/hide group title field
        convType.addEventListener('change', function() {
            groupTitleField.style.display = this.value === 'group' ? 'block' : 'none';
        });
        
        let searchTimeout;
        searchInput.addEventListener('input', function() {
            clearTimeout(searchTimeout);
            searchTimeout = setTimeout(async () => {
                if (this.value.length < 2) {
                    userResults.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">Type at least 2 characters to search...</div>';
                    return;
                }
                
                try {
                    console.log('Searching for users with query:', this.value);
                    const response = await messenger.apiCall(`/users/search?query=${encodeURIComponent(this.value)}`);
                    console.log('Search response:', response);
                    
                    const users = response.data || [];
                    console.log('Users found:', users);
                    
                    if (users.length === 0) {
                        userResults.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">No users found</div>';
                        return;
                    }
                    
                    userResults.innerHTML = users.map(user => {
                        const displayName = user.full_name || `${user.first_name || ''} ${user.last_name || ''}`.trim() || user.username;
                        const initials = messenger.getInitials(displayName);
                        
                        return `
                            <div class="user-item" data-user-id="${user.id}" style="padding: 12px; border-bottom: 1px solid #eee; cursor: pointer; display: flex; align-items: center; gap: 12px; transition: background 0.2s;">
                                <div style="width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
                                    ${initials}
                                </div>
                                <div>
                                    <div style="font-weight: 600;">${displayName}</div>
                                    <div style="font-size: 14px; color: #666;">@${user.username}</div>
                                </div>
                                <div style="margin-left: auto;">
                                    <input type="checkbox" class="user-checkbox" value="${user.id}">
                                </div>
                            </div>
                        `;
                    }).join('');
                    
                    // Handle user selection
                    userResults.querySelectorAll('.user-checkbox').forEach(checkbox => {
                        checkbox.addEventListener('change', function() {
                            const userId = parseInt(this.value);
                            if (this.checked) {
                                selectedUsers.push(userId);
                            } else {
                                selectedUsers = selectedUsers.filter(id => id !== userId);
                            }
                            createBtn.disabled = selectedUsers.length === 0;
                        });
                    });
                    
                    // Handle row clicks
                    userResults.querySelectorAll('.user-item').forEach(item => {
                        item.addEventListener('mouseenter', () => item.style.background = '#f8f9fa');
                        item.addEventListener('mouseleave', () => item.style.background = 'white');
                        item.addEventListener('click', (e) => {
                            if (e.target.type !== 'checkbox') {
                                const checkbox = item.querySelector('.user-checkbox');
                                checkbox.checked = !checkbox.checked;
                                checkbox.dispatchEvent(new Event('change'));
                            }
                        });
                    });
                    
                } catch (error) {
                    console.error('Error searching users:', error);
                    console.error('Error details:', {
                        message: error.message,
                        stack: error.stack,
                        name: error.name
                    });
                    userResults.innerHTML = `<div style="padding: 20px; text-align: center; color: #f56565;">Error searching users: ${error.message}</div>`;
                }
            }, 300);
        });
        
        // Handle create conversation
        createBtn.addEventListener('click', async function() {
            if (selectedUsers.length === 0) return;
            
            this.disabled = true;
            this.textContent = 'Creating...';
            
            try {
                const type = convType.value;
                const title = type === 'group' ? document.getElementById('group-title').value : null;
                
                const response = await messenger.apiCall('/conversations', {
                    method: 'POST',
                    body: {
                        type: type,
                        participant_ids: selectedUsers,
                        title: title
                    }
                });
                
                // Add to conversations list
                messenger.state.conversations.set(response.data.id, response.data);
                messenger.renderConversations();
                
                // Select the new conversation
                await messenger.selectConversation(response.data.id);
                
                messenger.showNotification('Conversation created successfully!', 'success');
                modal.remove();
                
            } catch (error) {
                messenger.showNotification('Failed to create conversation', 'error');
                this.disabled = false;
                this.textContent = 'Create Conversation';
            }
        });
        
        // Handle cancel
        document.getElementById('cancel-conv').addEventListener('click', () => modal.remove());
        modal.addEventListener('click', (e) => {
            if (e.target === modal) modal.remove();
        });
        
        // Focus search input
        searchInput.focus();
    }

    openImageModal(imageUrl) {
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed; top: 0; left: 0; width: 100%; height: 100%; 
            background: rgba(0,0,0,0.9); z-index: 10000; display: flex; 
            align-items: center; justify-content: center; cursor: zoom-out;
        `;
        modal.innerHTML = `<img src="${imageUrl}" style="max-width: 90%; max-height: 90%; border-radius: 8px;">`;
        modal.onclick = () => modal.remove();
        document.body.appendChild(modal);
    }

    handleKeyboardShortcuts(e) {
        if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
            this.sendMessage();
        }
        
        if (e.key === 'Escape') {
            this.elements.emojiPicker.classList.remove('show');
        }
    }

    // Event handlers
    handleRealTimeEvents(events) {
        events.forEach(event => {
            switch (event.type) {
                case 'message.created':
                    this.handleNewMessage(event.data);
                    break;
                case 'typing.start':
                    this.state.isTyping.add(event.data.user_name);
                    this.renderTypingIndicators();
                    break;
                case 'typing.stop':
                    this.state.isTyping.delete(event.data.user_name);
                    this.renderTypingIndicators();
                    break;
            }
        });
    }

    handleNewMessage(message) {
        const conversationMessages = this.state.messages.get(message.conversation_id) || [];
        conversationMessages.push(message);
        this.state.messages.set(message.conversation_id, conversationMessages);
        
        if (this.state.currentConversation === message.conversation_id) {
            this.renderMessages(conversationMessages);
            this.scrollToBottom();
            
            if (!document.hidden) {
                this.markMessagesAsRead(message.conversation_id);
            }
        } else {
            const current = this.state.unreadCounts.get(message.conversation_id) || 0;
            this.state.unreadCounts.set(message.conversation_id, current + 1);
            this.renderConversations();
        }
        
        if (this.state.currentConversation !== message.conversation_id || document.hidden) {
            this.showDesktopNotification(message);
        }
    }

    markMessagesAsRead(conversationId) {
        this.state.unreadCounts.set(conversationId, 0);
        this.renderConversations();
    }
}

// Request notification permission on load
if ('Notification' in window && Notification.permission === 'default') {
    Notification.requestPermission();
}

// Export for global use
window.MessengerApp = MessengerApp;
