// chat-ui.js - UI адаптер для ванильного JavaScript
class ChatUIAdapter {
    constructor(chatCore, elements) {
        this.chatCore = chatCore;
        this.elements = elements;
        this.isRecording = false;
        this.recognition = null;
        
        this.setupCallbacks();
        this.setupEventListeners();
        this.initVoiceRecognition();
    }
    
    setupCallbacks() {
        this.chatCore.setCallbacks({
            onMessage: (role, content, files) => this.renderMessage(role, content, files),
            onStatusChange: (waiting) => this.updateWaitingState(waiting),
            onConversationListUpdate: (conversations) => this.renderConversationList(conversations),
            onConversationChange: (id, messages) => this.loadConversationMessages(messages),
            onFileListUpdate: (files) => this.updateFileList(files),
            onUploadProgress: (percent) => this.updateProgress(percent),
            onError: (error) => this.showError(error)
        });
    }
    
    setupEventListeners() {
        // Отправка сообщения
        if (this.elements.sendButton) {
            this.elements.sendButton.addEventListener('click', () => this.handleSend());
        }
        
        if (this.elements.messageInput) {
            this.elements.messageInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    this.handleSend();
                }
            });
            
            // Автоматическое изменение высоты textarea
            this.elements.messageInput.addEventListener('input', (e) => {
                e.target.style.height = 'auto';
                e.target.style.height = Math.min(e.target.scrollHeight, 120) + 'px';
            });
        }
        
        // Новая задача/чат
        if (this.elements.newChatButton) {
            this.elements.newChatButton.addEventListener('click', async () => {
                const newId = this.chatCore.createNewConversation();
                await this.chatCore.createTask();
                this.showTemporaryMessage('Новый чат создан', 'info');
            });
        }
        
        // Файлы
        if (this.elements.fileInput) {
            this.elements.fileInput.addEventListener('change', (e) => {
                this.handleFileSelect(Array.from(e.target.files));
            });
        }
        
        if (this.elements.fileButton) {
            this.elements.fileButton.addEventListener('click', () => {
                if (this.elements.fileInput) {
                    this.elements.fileInput.click();
                }
            });
        }
        
        // Голос
        if (this.elements.voiceButton) {
            this.elements.voiceButton.addEventListener('click', () => this.toggleVoiceRecording());
        }
        
        // Toggle sidebar (для мобильной версии)
        if (this.elements.toggleSidebar) {
            this.elements.toggleSidebar.addEventListener('click', () => {
                const sidebar = document.querySelector('.sidebar');
                if (sidebar) {
                    sidebar.classList.toggle('open');
                }
            });
        }
        
        // Drag & drop
        if (this.elements.dropZone) {
            this.setupDragAndDrop();
        }
        
        // Закрытие ошибки по клику
        if (this.elements.errorDisplay) {
            this.elements.errorDisplay.addEventListener('click', () => {
                this.elements.errorDisplay.style.display = 'none';
            });
        }
    }
    
    handleSend() {
        const text = this.elements.messageInput ? this.elements.messageInput.value.trim() : '';
        const files = this.chatCore.selectedFiles || [];
        
        if (text || files.length > 0) {
            this.chatCore.sendMessage(text, files);
            if (this.elements.messageInput) {
                this.elements.messageInput.value = '';
                this.elements.messageInput.style.height = 'auto';
            }
            this.chatCore.selectedFiles = [];
            this.updateFileList([]);
        }
    }
    
    handleFileSelect(files) {
        // Валидация файлов
        const validation = this.chatCore.validateFiles(files);
        if (!validation.valid) {
            this.showError(validation.errors.join('\n'));
            if (this.elements.fileInput) {
                this.elements.fileInput.value = '';
            }
            return;
        }
        
        // Сохраняем выбранные файлы
        this.chatCore.selectedFiles = files;
        this.updateFileList(files);
    }
    
    renderMessage(role, content, files) {
        if (!this.elements.chatContainer) return;
        
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${role}`;
        
        // Создаем контент сообщения
        const contentDiv = document.createElement('div');
        contentDiv.className = 'message-content';
        
        // Обработка markdown-like форматирования
        let formattedContent = this.formatMessageContent(content);
        contentDiv.innerHTML = formattedContent;
        
        messageDiv.appendChild(contentDiv);
        
        // Добавляем файлы если есть
        if (files && files.length > 0) {
            const filesDiv = document.createElement('div');
            filesDiv.className = 'message-files';
            
            files.forEach(file => {
                const fileElement = document.createElement('div');
                fileElement.className = 'file-attachment';
                
                if (file.type && file.type.startsWith('image/')) {
                    const img = document.createElement('img');
                    img.src = file.objectUrl;
                    img.alt = file.name;
                    img.className = 'file-preview';
                    fileElement.appendChild(img);
                    
                    // Добавляем название файла
                    const caption = document.createElement('div');
                    caption.className = 'file-caption';
                    caption.textContent = file.name;
                    fileElement.appendChild(caption);
                } else {
                    fileElement.innerHTML = `
                        <span class="file-icon">📄</span>
                        <span class="file-name">${this.escapeHtml(file.name)}</span>
                        <span class="file-size">(${this.formatFileSize(file.size)})</span>
                    `;
                }
                
                filesDiv.appendChild(fileElement);
            });
            
            messageDiv.appendChild(filesDiv);
        }
        
        this.elements.chatContainer.appendChild(messageDiv);
        this.scrollToBottom();
    }
    
    formatMessageContent(content) {
        if (!content) return '';
        
        // Экранируем HTML
        let formatted = this.escapeHtml(content);
        
        // Преобразуем **жирный** текст
        formatted = formatted.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
        
        // Преобразуем *курсив*
        formatted = formatted.replace(/\*(.+?)\*/g, '<em>$1</em>');
        
        // Преобразуем `код`
        formatted = formatted.replace(/`(.+?)`/g, '<code>$1</code>');
        
        // Преобразуем [ссылки](url)
        formatted = formatted.replace(/\[(.+?)\]\((https?:\/\/.+?)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');
        
        // Преобразуем переносы строк
        formatted = formatted.replace(/\n/g, '<br>');
        
        return formatted;
    }
    
    renderConversationList(conversations) {
        if (!this.elements.conversationList) return;
        
        this.elements.conversationList.innerHTML = '';
        
        if (conversations.length === 0) {
            const emptyDiv = document.createElement('div');
            emptyDiv.className = 'empty-conversations';
            emptyDiv.textContent = 'Нет диалогов';
            this.elements.conversationList.appendChild(emptyDiv);
            return;
        }
        
        conversations.forEach(conv => {
            const item = document.createElement('div');
            item.className = 'conversation-item';
            if (conv.id === this.chatCore.currentConversationId) {
                item.classList.add('active');
            }
            
            item.innerHTML = `
                <div class="conversation-title">${this.escapeHtml(conv.title || 'Новый чат')}</div>
                <div class="conversation-time">${this.formatDate(conv.updatedAt)}</div>
            `;
            
            item.addEventListener('click', () => {
                this.chatCore.switchToConversation(conv.id);
                // На мобильных устройствах закрываем сайдбар после выбора
                if (window.innerWidth <= 768) {
                    const sidebar = document.querySelector('.sidebar');
                    if (sidebar) {
                        sidebar.classList.remove('open');
                    }
                }
            });
            
            this.elements.conversationList.appendChild(item);
        });
    }
    
    loadConversationMessages(messages) {
        if (!this.elements.chatContainer) return;
        
        this.elements.chatContainer.innerHTML = '';
        
        if (!messages || messages.length === 0) {
            const welcomeDiv = document.createElement('div');
            welcomeDiv.className = 'welcome-message';
            welcomeDiv.innerHTML = `
                <div class="welcome-icon">👋</div>
                <div class="welcome-text">Привет! Я Кэби, ваш AI-ассистент.<br>Задайте мне вопрос или начните новый диалог.</div>
            `;
            this.elements.chatContainer.appendChild(welcomeDiv);
        } else {
            messages.forEach(msg => {
                this.renderMessage(msg.role, msg.content, msg.files);
            });
        }
        
        this.scrollToBottom();
    }
    
    updateFileList(files) {
        if (!this.elements.fileList) return;
        
        if (!files || files.length === 0) {
            this.elements.fileList.innerHTML = '';
            this.elements.fileList.style.display = 'none';
        } else {
            this.elements.fileList.style.display = 'block';
            this.elements.fileList.innerHTML = '';
            
            files.forEach((file, index) => {
                const fileTag = document.createElement('div');
                fileTag.className = 'file-tag';
                fileTag.innerHTML = `
                    <span class="file-tag-name">📎 ${this.escapeHtml(file.name)} (${this.formatFileSize(file.size)})</span>
                    <button class="file-tag-remove" data-index="${index}">×</button>
                `;
                
                const removeBtn = fileTag.querySelector('.file-tag-remove');
                removeBtn.addEventListener('click', () => {
                    files.splice(index, 1);
                    this.updateFileList(files);
                    this.chatCore.selectedFiles = files;
                });
                
                this.elements.fileList.appendChild(fileTag);
            });
        }
    }
    
    updateProgress(percent) {
        if (!this.elements.progressBar) return;
        
        if (percent > 0 && percent < 100) {
            this.elements.progressBar.style.display = 'block';
            const progressFill = this.elements.progressBar.querySelector('.progress-fill') || 
                                (() => {
                                    const fill = document.createElement('div');
                                    fill.className = 'progress-fill';
                                    this.elements.progressBar.appendChild(fill);
                                    return fill;
                                })();
            progressFill.style.width = percent + '%';
        } else {
            this.elements.progressBar.style.display = 'none';
        }
    }
    
    updateWaitingState(waiting) {
        if (this.elements.messageInput) {
            this.elements.messageInput.disabled = waiting;
        }
        if (this.elements.sendButton) {
            this.elements.sendButton.disabled = waiting;
        }
        if (this.elements.fileButton) {
            this.elements.fileButton.disabled = waiting;
        }
        if (this.elements.voiceButton) {
            this.elements.voiceButton.disabled = waiting;
        }
        if (this.elements.statusIndicator) {
            if (waiting) {
                this.elements.statusIndicator.textContent = '⏳ печатает...';
                this.elements.statusIndicator.className = 'status typing';
            } else {
                this.elements.statusIndicator.textContent = '● онлайн';
                this.elements.statusIndicator.className = 'status online';
            }
        }
    }
    
    showError(error) {
        console.error('Error:', error);
        if (this.elements.errorDisplay) {
            this.elements.errorDisplay.textContent = error;
            this.elements.errorDisplay.style.display = 'block';
            setTimeout(() => {
                if (this.elements.errorDisplay) {
                    this.elements.errorDisplay.style.display = 'none';
                }
            }, 5000);
        }
    }
    
    showTemporaryMessage(message, type = 'info') {
        const toast = document.createElement('div');
        toast.className = `toast-message ${type}`;
        toast.textContent = message;
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.classList.add('show');
        }, 10);
        
        setTimeout(() => {
            toast.classList.remove('show');
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    }
    
    initVoiceRecognition() {
        if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
            if (this.elements.voiceButton) {
                this.elements.voiceButton.style.display = 'none';
            }
            return;
        }
        
        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
        this.recognition = new SpeechRecognition();
        this.recognition.lang = 'ru-RU';
        this.recognition.continuous = false;
        this.recognition.interimResults = false;
        this.recognition.maxAlternatives = 1;
        
        this.recognition.onresult = (event) => {
            const text = event.results[0][0].transcript;
            if (this.elements.messageInput) {
                this.elements.messageInput.value = text;
                // Триггерим событие input для изменения высоты
                const inputEvent = new Event('input', { bubbles: true });
                this.elements.messageInput.dispatchEvent(inputEvent);
            }
            this.stopVoiceRecording();
            this.showTemporaryMessage('✅ Распознано: ' + text, 'success');
        };
        
        this.recognition.onerror = (event) => {
            console.error('Recognition error:', event.error);
            this.stopVoiceRecording();
            this.showError('Ошибка распознавания: ' + event.error);
        };
        
        this.recognition.onend = () => {
            this.stopVoiceRecording();
        };
    }
    
    toggleVoiceRecording() {
        if (this.isRecording) {
            this.stopVoiceRecording();
        } else {
            this.startVoiceRecording();
        }
    }
    
    startVoiceRecording() {
        if (this.recognition) {
            try {
                this.recognition.start();
                this.isRecording = true;
                if (this.elements.voiceButton) {
                    this.elements.voiceButton.classList.add('recording');
                    this.elements.voiceButton.title = 'Остановить запись';
                }
                this.showTemporaryMessage('🎤 Говорите...', 'info');
            } catch (e) {
                console.error('Voice recognition error:', e);
                this.showError('Не удалось запустить распознавание');
            }
        }
    }
    
    stopVoiceRecording() {
        if (this.recognition && this.isRecording) {
            this.recognition.stop();
            this.isRecording = false;
            if (this.elements.voiceButton) {
                this.elements.voiceButton.classList.remove('recording');
                this.elements.voiceButton.title = 'Голосовой ввод';
            }
        }
    }
    
    setupDragAndDrop() {
        const dropZone = this.elements.dropZone;
        
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropZone.addEventListener(eventName, (e) => {
                e.preventDefault();
                e.stopPropagation();
            });
        });
        
        ['dragenter', 'dragover'].forEach(eventName => {
            dropZone.addEventListener(eventName, () => {
                dropZone.classList.add('drag-over');
            });
        });
        
        ['dragleave', 'drop'].forEach(eventName => {
            dropZone.addEventListener(eventName, () => {
                dropZone.classList.remove('drag-over');
            });
        });
        
        dropZone.addEventListener('drop', (e) => {
            const files = Array.from(e.dataTransfer.files);
            if (files.length > 0 && this.chatCore.config.ALLOW_FILES) {
                this.handleFileSelect(files);
            }
        });
    }
    
    scrollToBottom() {
        if (this.elements.chatContainer) {
            setTimeout(() => {
                this.elements.chatContainer.scrollTop = this.elements.chatContainer.scrollHeight;
            }, 100);
        }
    }
    
    escapeHtml(text) {
        if (!text) return '';
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Б';
        const k = 1024;
        const sizes = ['Б', 'КБ', 'МБ', 'ГБ'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
    }
    
    formatDate(date) {
        if (!date) return '';
        
        const dateObj = typeof date === 'string' ? new Date(date) : date;
        const now = new Date();
        const diff = now - dateObj;
        const days = Math.floor(diff / (1000 * 60 * 60 * 24));
        
        if (days === 0) {
            const hours = dateObj.getHours().toString().padStart(2, '0');
            const minutes = dateObj.getMinutes().toString().padStart(2, '0');
            return `Сегодня в ${hours}:${minutes}`;
        }
        if (days === 1) return 'Вчера';
        if (days < 7) return `${days} дн. назад`;
        
        return dateObj.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' });
    }
}