/**
 * ChatGPT Assistent Modul
 * Verwaltet die Interaktion mit der OpenAI API und die Benutzeroberfläche des Assistenten
 */

class ChatGPTAssistant {
    constructor() {
        this.messages = [];
        this.isOpen = false;
        this.isLoading = false;
        this.container = null;
        this.chatHistory = null;
        this.inputField = null;
        this.suggestionArea = null;
        this.maxRetries = 2;
        this.retryCount = 0;
        this.markdownParser = null;
        this.initializeMarkdownParser();
    }

    /**
     * Initialisiert den Markdown-Parser
     */
    async initializeMarkdownParser() {
        // Dynamisch marked.js laden, wenn noch nicht vorhanden
        if (!window.marked) {
            try {
                // Prüfen, ob marked.js bereits im Dokument geladen ist
                if (!document.querySelector('script[src*="marked"]')) {
                    // Falls nicht, Script-Tag erstellen und einfügen
                    const script = document.createElement('script');
                    script.src = 'https://cdn.jsdelivr.net/npm/marked/marked.min.js';
                    script.async = true;
                    
                    // Promise erstellen, das resolved wird, wenn das Script geladen wurde
                    await new Promise((resolve, reject) => {
                        script.onload = resolve;
                        script.onerror = reject;
                        document.head.appendChild(script);
                    });
                    
                    console.log('Marked.js erfolgreich geladen');
                }
                
                // Marked konfigurieren
                this.markdownParser = window.marked;
                this.markdownParser.setOptions({
                    gfm: true,
                    breaks: true,
                    sanitize: true,
                    smartLists: true,
                    smartypants: true
                });
            } catch (error) {
                console.error('Fehler beim Laden von marked.js:', error);
                // Fallback-Parser, der nur einfache Absätze erkennt
                this.markdownParser = {
                    parse: (text) => {
                        return text.split('\n').map(line => {
                            if (line.trim() === '') return '<br>';
                            return `<p>${line}</p>`;
                        }).join('');
                    }
                };
            }
        } else {
            // Marked ist bereits geladen
            this.markdownParser = window.marked;
        }
    }

    /**
     * Initialisiert den Assistenten und fügt die UI zum DOM hinzu
     */
    init() {
        // Assistent-Container erstellen
        this.createAssistantUI();
        
        // Event-Listener hinzufügen
        this.setupEventListeners();
        
        // Ersten Willkommensnachricht anzeigen
        this.addMessage("assistant", "Hallo! Ich bin dein KI-Assistent (4o-mini) und habe Zugriff auf die Wissensdatenbank. Wie kann ich dir helfen?\n\nDu kannst mir Fragen über:\n- **Gedanken** in der Datenbank\n- **Kategorien** und Wissenschaftsbereiche\n- **Mindmaps** und Wissensverknüpfungen\n\nstellen.");
        
        // Vorschläge anzeigen
        this.showSuggestions([
            "Zeige mir Gedanken zur künstlichen Intelligenz",
            "Welche Kategorien gibt es in der Datenbank?",
            "Suche nach Mindmaps zum Thema Informatik"
        ]);
        
        console.log('KI-Assistent initialisiert!');
    }

    /**
     * Erstellt die UI-Elemente für den Assistenten
     */
    createAssistantUI() {
        // Hauptcontainer erstellen
        this.container = document.createElement('div');
        this.container.id = 'chatgpt-assistant';
        this.container.className = 'fixed bottom-4 right-4 z-50 flex flex-col';
        
        // Button zum Öffnen/Schließen des Assistenten
        const toggleButton = document.createElement('button');
        toggleButton.id = 'assistant-toggle';
        toggleButton.className = 'ml-auto bg-primary-600 hover:bg-primary-700 text-white rounded-full p-3 shadow-lg transition-all duration-300 mb-2';
        toggleButton.innerHTML = '<i class="fas fa-robot text-xl"></i>';
        
        // Chat-Container
        const chatContainer = document.createElement('div');
        chatContainer.id = 'assistant-chat';
        chatContainer.className = 'bg-white dark:bg-dark-800 rounded-lg shadow-xl overflow-hidden transition-all duration-300 w-80 md:w-96 max-h-0 opacity-0';
        
        // Chat-Header
        const header = document.createElement('div');
        header.className = 'bg-primary-600 text-white p-3 flex items-center justify-between';
        header.innerHTML = `
            <div class="flex items-center">
                <i class="fas fa-robot mr-2"></i>
                <span>KI-Assistent (4o-mini)</span>
            </div>
            <button id="assistant-close" class="text-white hover:text-gray-200">
                <i class="fas fa-times"></i>
            </button>
        `;
        
        // Chat-Verlauf
        this.chatHistory = document.createElement('div');
        this.chatHistory.id = 'assistant-history';
        this.chatHistory.className = 'p-3 overflow-y-auto max-h-96 space-y-3';
        
        // Vorschlagsbereich
        this.suggestionArea = document.createElement('div');
        this.suggestionArea.id = 'assistant-suggestions';
        this.suggestionArea.className = 'px-3 pb-2 flex flex-wrap gap-2 overflow-x-auto hidden';
        
        // Chat-Eingabe
        const inputContainer = document.createElement('div');
        inputContainer.className = 'border-t border-gray-200 dark:border-dark-600 p-3 flex items-center';
        
        this.inputField = document.createElement('input');
        this.inputField.type = 'text';
        this.inputField.placeholder = 'Stelle eine Frage zur Wissensdatenbank...';
        this.inputField.className = 'flex-1 border border-gray-300 dark:border-dark-600 dark:bg-dark-700 dark:text-white rounded-l-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary-500';
        
        const sendButton = document.createElement('button');
        sendButton.id = 'assistant-send';
        sendButton.className = 'bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded-r-lg';
        sendButton.innerHTML = '<i class="fas fa-paper-plane"></i>';
        
        // Elemente zusammenfügen
        inputContainer.appendChild(this.inputField);
        inputContainer.appendChild(sendButton);
        
        chatContainer.appendChild(header);
        chatContainer.appendChild(this.chatHistory);
        chatContainer.appendChild(this.suggestionArea);
        chatContainer.appendChild(inputContainer);
        
        this.container.appendChild(toggleButton);
        this.container.appendChild(chatContainer);
        
        // Zum DOM hinzufügen
        document.body.appendChild(this.container);
    }

    /**
     * Richtet Event-Listener für die Benutzeroberfläche ein
     */
    setupEventListeners() {
        // Toggle-Button
        const toggleButton = document.getElementById('assistant-toggle');
        if (toggleButton) {
            toggleButton.addEventListener('click', () => this.toggleAssistant());
        }
        
        // Schließen-Button
        const closeButton = document.getElementById('assistant-close');
        if (closeButton) {
            closeButton.addEventListener('click', () => this.toggleAssistant(false));
        }
        
        // Senden-Button
        const sendButton = document.getElementById('assistant-send');
        if (sendButton) {
            sendButton.addEventListener('click', () => this.sendMessage());
        }
        
        // Enter-Taste im Eingabefeld
        if (this.inputField) {
            this.inputField.addEventListener('keyup', (e) => {
                if (e.key === 'Enter') {
                    this.sendMessage();
                }
            });
        }
        
        // Vorschläge klickbar machen
        if (this.suggestionArea) {
            this.suggestionArea.addEventListener('click', (e) => {
                if (e.target.classList.contains('suggestion-pill')) {
                    this.inputField.value = e.target.textContent;
                    this.sendMessage();
                }
            });
        }
    }

    /**
     * Öffnet oder schließt den Assistenten
     * @param {boolean} state - Optional: erzwingt einen bestimmten Zustand
     */
    toggleAssistant(state = null) {
        const chatContainer = document.getElementById('assistant-chat');
        if (!chatContainer) return;
        
        this.isOpen = state !== null ? state : !this.isOpen;
        
        if (this.isOpen) {
            chatContainer.classList.remove('max-h-0', 'opacity-0');
            chatContainer.classList.add('max-h-[32rem]', 'opacity-100');
            if (this.inputField) this.inputField.focus();
            
            // Zeige Vorschläge wenn verfügbar
            if (this.suggestionArea && this.suggestionArea.children.length > 0) {
                this.suggestionArea.classList.remove('hidden');
            }
        } else {
            chatContainer.classList.remove('max-h-[32rem]', 'opacity-100');
            chatContainer.classList.add('max-h-0', 'opacity-0');
        }
    }

    /**
     * Fügt eine Nachricht zum Chat-Verlauf hinzu
     * @param {string} sender - 'user' oder 'assistant'
     * @param {string} text - Nachrichtentext
     */
    addMessage(sender, text) {
        // Nachricht zum Verlauf hinzufügen
        this.messages.push({ role: sender, content: text });
        
        // DOM-Element erstellen
        const messageEl = document.createElement('div');
        messageEl.className = `flex ${sender === 'user' ? 'justify-end' : 'justify-start'}`;
        
        const bubble = document.createElement('div');
        bubble.className = sender === 'user' 
            ? 'bg-primary-100 dark:bg-primary-900 text-gray-800 dark:text-white rounded-lg py-2 px-3 max-w-[85%]'
            : 'bg-gray-100 dark:bg-dark-700 text-gray-800 dark:text-white rounded-lg py-2 px-3 max-w-[85%]';
        
        // Formatierung des Texts (mit Markdown für Assistent-Nachrichten)
        let formattedText = '';
        
        if (sender === 'assistant' && this.markdownParser) {
            // Für Assistentnachrichten Markdown verwenden
            try {
                formattedText = this.markdownParser.parse(text);
                
                // CSS für Markdown-Formatierung hinzufügen
                const markdownStyles = `
                    .markdown-bubble h1, .markdown-bubble h2, .markdown-bubble h3, 
                    .markdown-bubble h4, .markdown-bubble h5, .markdown-bubble h6 {
                        font-weight: bold;
                        margin-top: 0.5rem;
                        margin-bottom: 0.5rem;
                    }
                    .markdown-bubble h1 { font-size: 1.4rem; }
                    .markdown-bubble h2 { font-size: 1.3rem; }
                    .markdown-bubble h3 { font-size: 1.2rem; }
                    .markdown-bubble h4 { font-size: 1.1rem; }
                    .markdown-bubble ul, .markdown-bubble ol {
                        padding-left: 1.5rem;
                        margin: 0.5rem 0;
                    }
                    .markdown-bubble ul { list-style-type: disc; }
                    .markdown-bubble ol { list-style-type: decimal; }
                    .markdown-bubble p { margin: 0.5rem 0; }
                    .markdown-bubble code {
                        font-family: monospace;
                        background-color: rgba(0, 0, 0, 0.1);
                        padding: 1px 4px;
                        border-radius: 3px;
                    }
                    .markdown-bubble pre {
                        background-color: rgba(0, 0, 0, 0.1);
                        padding: 0.5rem;
                        border-radius: 4px;
                        overflow-x: auto;
                        margin: 0.5rem 0;
                    }
                    .markdown-bubble pre code {
                        background-color: transparent;
                        padding: 0;
                    }
                    .markdown-bubble blockquote {
                        border-left: 3px solid rgba(0, 0, 0, 0.2);
                        padding-left: 0.8rem;
                        margin: 0.5rem 0;
                        font-style: italic;
                    }
                    .dark .markdown-bubble code {
                        background-color: rgba(255, 255, 255, 0.1);
                    }
                    .dark .markdown-bubble pre {
                        background-color: rgba(255, 255, 255, 0.1);
                    }
                    .dark .markdown-bubble blockquote {
                        border-left-color: rgba(255, 255, 255, 0.2);
                    }
                `;
                
                // Füge die Styles hinzu, wenn sie noch nicht vorhanden sind
                if (!document.querySelector('#markdown-chat-styles')) {
                    const style = document.createElement('style');
                    style.id = 'markdown-chat-styles';
                    style.textContent = markdownStyles;
                    document.head.appendChild(style);
                }
                
                // Klasse für Markdown-Formatierung hinzufügen
                bubble.classList.add('markdown-bubble');
            } catch (error) {
                console.error('Fehler bei der Markdown-Formatierung:', error);
                // Fallback zur einfachen Formatierung
                formattedText = text.split('\n').map(line => {
                    if (line.trim() === '') return '<br>';
                    return `<p>${line}</p>`;
                }).join('');
            }
        } else {
            // Für Benutzernachrichten einfache Formatierung
            formattedText = text.split('\n').map(line => {
                if (line.trim() === '') return '<br>';
                return `<p>${line}</p>`;
            }).join('');
        }
        
        bubble.innerHTML = formattedText;
        
        messageEl.appendChild(bubble);
        
        if (this.chatHistory) {
            this.chatHistory.appendChild(messageEl);
            
            // Scroll zum Ende des Verlaufs
            this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
        }
    }

    /**
     * Zeigt Vorschläge als klickbare Pills an
     * @param {string[]} suggestions - Liste von Vorschlägen
     */
    showSuggestions(suggestions) {
        if (!this.suggestionArea) return;
        
        // Vorherige Vorschläge entfernen
        this.suggestionArea.innerHTML = '';
        
        if (suggestions && suggestions.length > 0) {
            suggestions.forEach(suggestion => {
                const pill = document.createElement('button');
                pill.className = 'suggestion-pill text-sm bg-gray-200 dark:bg-dark-600 hover:bg-gray-300 dark:hover:bg-dark-500 text-gray-800 dark:text-gray-200 rounded-full px-3 py-1 mb-2 transition-colors';
                pill.textContent = suggestion;
                this.suggestionArea.appendChild(pill);
            });
            
            this.suggestionArea.classList.remove('hidden');
        } else {
            this.suggestionArea.classList.add('hidden');
        }
    }

    /**
     * Sendet die Benutzernachricht an den Server und zeigt die Antwort an
     */
    async sendMessage() {
        if (!this.inputField) return;
        
        const userInput = this.inputField.value.trim();
        if (!userInput || this.isLoading) return;
        
        // Vorschläge ausblenden
        if (this.suggestionArea) {
            this.suggestionArea.classList.add('hidden');
        }
        
        // Benutzernachricht anzeigen
        this.addMessage('user', userInput);
        
        // Eingabefeld zurücksetzen
        this.inputField.value = '';
        
        // Ladeindikator anzeigen
        this.isLoading = true;
        this.showLoadingIndicator();
        
        try {
            console.log('Sende Anfrage an KI-Assistent API...');
            // Anfrage an den Server senden
            const response = await fetch('/api/assistant', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    messages: this.messages
                }),
                cache: 'no-cache', // Kein Cache verwenden
                credentials: 'same-origin' // Cookies senden
            });
            
            // Ladeindikator entfernen
            this.removeLoadingIndicator();
            
            if (!response.ok) {
                throw new Error(`Serverfehler: ${response.status} ${response.statusText}`);
            }
            
            const data = await response.json();
            console.log('Antwort erhalten:', data);
            
            // Antwort anzeigen
            if (data.response) {
                this.addMessage('assistant', data.response);
                
                // Neue Vorschläge basierend auf dem aktuellen Kontext anzeigen
                this.generateContextualSuggestions();
                
                // Erfolgreiche Anfrage zurücksetzen
                this.retryCount = 0;
            } else if (data.error) {
                this.addMessage('assistant', `Fehler: ${data.error}`);
            } else {
                throw new Error('Unerwartetes Antwortformat vom Server');
            }
        } catch (error) {
            console.error('Fehler bei der Kommunikation mit dem Assistenten:', error);
            
            // Ladeindikator entfernen, falls noch vorhanden
            this.removeLoadingIndicator();
            
            // Fehlermeldung anzeigen oder Wiederholungsversuch starten
            if (this.retryCount < this.maxRetries) {
                this.retryCount++;
                this.addMessage('assistant', 'Es gab ein Problem mit der Anfrage. Ich versuche es erneut...');
                
                // Kurze Verzögerung vor dem erneuten Versuch
                setTimeout(() => {
                    // Letzte Benutzernachricht aus dem Messages-Array entfernen
                    const lastUserMessage = this.messages[this.messages.length - 2].content;
                    this.messages = this.messages.slice(0, -2); // Entferne Benutzernachricht und Fehlermeldung
                    
                    // Erneuter Versand mit gleicher Nachricht
                    this.inputField.value = lastUserMessage;
                    this.sendMessage();
                }, 1500);
            } else {
                // Maximale Anzahl an Wiederholungsversuchen erreicht
                this.addMessage('assistant', 'Es tut mir leid, aber es gab ein Problem bei der Verarbeitung deiner Anfrage. Bitte versuche es später noch einmal.');
                this.retryCount = 0; // Zurücksetzen für die nächste Anfrage
            }
        } finally {
            this.isLoading = false;
        }
    }

    /**
     * Generiert kontextbasierte Vorschläge basierend auf dem aktuellen Chat-Verlauf
     */
    generateContextualSuggestions() {
        // Basierend auf letzter Antwort des Assistenten, verschiedene Vorschläge generieren
        const lastAssistantMessage = this.messages.findLast(msg => msg.role === 'assistant')?.content || '';
        
        let suggestions = [];
        
        // Intelligente Vorschläge basierend auf Kontext
        if (lastAssistantMessage.includes('Künstliche Intelligenz') || 
            lastAssistantMessage.includes('KI ') || 
            lastAssistantMessage.includes('AI ')) {
            suggestions = [
                "Wie wird KI in der Wissenschaft eingesetzt?",
                "Zeige mir Gedanken zum maschinellen Lernen",
                "Was ist der Unterschied zwischen KI und ML?"
            ];
        } else if (lastAssistantMessage.includes('Kategorie') || 
                  lastAssistantMessage.includes('Kategorien')) {
            suggestions = [
                "Zeige mir die Unterkategorien",
                "Welche Gedanken gehören zu dieser Kategorie?",
                "Liste alle Wissenschaftskategorien auf"
            ];
        } else if (lastAssistantMessage.includes('Mindmap') || 
                  lastAssistantMessage.includes('Visualisierung')) {
            suggestions = [
                "Wie kann ich eine eigene Mindmap erstellen?",
                "Zeige mir Beispiele für Mindmaps",
                "Wie funktionieren die Verbindungen in Mindmaps?"
            ];
        } else {
            // Standardvorschläge
            suggestions = [
                "Erzähle mir mehr dazu",
                "Gibt es Beispiele dafür?",
                "Wie kann ich diese Information nutzen?"
            ];
        }
        
        this.showSuggestions(suggestions);
    }

    /**
     * Zeigt einen Ladeindikator im Chat an
     */
    showLoadingIndicator() {
        if (!this.chatHistory) return;
        
        // Entferne vorhandenen Ladeindikator (falls vorhanden)
        this.removeLoadingIndicator();
        
        const loadingEl = document.createElement('div');
        loadingEl.id = 'assistant-loading';
        loadingEl.className = 'flex justify-start';
        
        const bubble = document.createElement('div');
        bubble.className = 'bg-gray-100 dark:bg-dark-700 text-gray-800 dark:text-white rounded-lg py-2 px-3';
        bubble.innerHTML = '<div class="typing-indicator"><span></span><span></span><span></span></div>';
        
        loadingEl.appendChild(bubble);
        this.chatHistory.appendChild(loadingEl);
        
        // Scroll zum Ende des Verlaufs
        this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
    }

    /**
     * Entfernt den Ladeindikator aus dem Chat
     */
    removeLoadingIndicator() {
        const loadingIndicator = document.getElementById('assistant-loading');
        if (loadingIndicator) {
            loadingIndicator.remove();
        }
    }

    /**
     * Öffnet den Assistenten und sendet eine vorgegebene Frage
     * @param {string} question - Die zu stellende Frage
     */
    async sendQuestion(question) {
        if (!question || this.isLoading) return;
        
        // Assistenten öffnen
        this.toggleAssistant(true);
        
        // Kurze Verzögerung, um sicherzustellen, dass der UI vollständig geöffnet ist
        await new Promise(resolve => setTimeout(resolve, 300));
        
        // Frage in Eingabefeld setzen
        if (this.inputField) {
            this.inputField.value = question;
            
            // Sende die Frage
            this.sendMessage();
        }
    }
}

// Mache die Klasse global verfügbar
window.ChatGPTAssistant = ChatGPTAssistant; 