/**
 * Mindmap.js - Modul für die Mindmap-Visualisierung mit Cytoscape.js
 * Version: 1.0.0
 * Datum: 01.05.2025
 */

// Stellen Sie sicher, dass das globale MindMap-Objekt existiert
if (!window.MindMap) {
    window.MindMap = {};
}

/**
 * Mindmap-Visualisierungsklasse
 */
class MindmapVisualization {
    /**
     * Konstruktor für die Mindmap-Visualisierung
     * @param {string} containerId - ID des Container-Elements
     * @param {Object} options - Konfigurationsoptionen
     */
    constructor(containerId, options = {}) {
        this.containerId = containerId;
        this.container = document.getElementById(containerId);
        this.cy = null;
        this.data = null;
        this.options = Object.assign({
            defaultLayout: 'cose',
            darkMode: document.documentElement.classList.contains('dark'),
            apiEndpoint: '/api/mindmap',
            onNodeClick: null
        }, options);
        
        // Event-Listener für Dark Mode-Änderungen
        document.addEventListener('darkModeToggled', (event) => {
            this.options.darkMode = event.detail.isDark;
            if (this.cy) {
                this.updateStyles();
            }
        });
    }
    
    /**
     * Initialisiert die Mindmap
     */
    async initialize() {
        console.log("Initialisiere Mindmap...");
        
        try {
            // Versuche, Daten vom Server zu laden
            this.data = await this.loadDataFromServer();
            console.log("Daten vom Server geladen:", this.data);
        } catch (error) {
            console.warn("Fehler beim Laden der Daten vom Server:", error);
            console.log("Verwende Standarddaten als Fallback");
            this.data = this.getDefaultData();
        }
        
        // Cytoscape initialisieren
        this.initializeCytoscape();
        
        return this;
    }
    
    /**
     * Lädt Daten vom Server
     * @returns {Promise} - Promise mit den geladenen Daten
     */
    async loadDataFromServer() {
        try {
            // Zuerst versuchen wir, Daten von /api/mindmap zu laden
            const response = await fetch(this.options.apiEndpoint);
            if (!response.ok) {
                throw new Error(`HTTP Fehler: ${response.status}`);
            }
            
            const data = await response.json();
            
            // Wenn keine Daten vorhanden sind, versuche /api/refresh-mindmap
            if (!data.nodes || data.nodes.length === 0) {
                console.log("Keine Daten gefunden, versuche /api/refresh-mindmap");
                const refreshResponse = await fetch('/api/refresh-mindmap');
                if (!refreshResponse.ok) {
                    throw new Error(`HTTP Fehler beim Refresh: ${refreshResponse.status}`);
                }
                return await refreshResponse.json();
            }
            
            return data;
        } catch (error) {
            console.error("Fehler beim Laden der Daten:", error);
            throw error;
        }
    }
    
    /**
     * Liefert Standarddaten als Fallback
     * @returns {Object} - Standarddaten für die Mindmap
     */
    getDefaultData() {
        return {
            nodes: [
                { id: "root", name: "Wissen", description: "Zentrale Wissensbasis", color_code: "#4299E1" },
                { id: "philosophy", name: "Philosophie", description: "Philosophisches Denken", color_code: "#9F7AEA" },
                { id: "science", name: "Wissenschaft", description: "Wissenschaftliche Erkenntnisse", color_code: "#48BB78" },
                { id: "technology", name: "Technologie", description: "Technologische Entwicklungen", color_code: "#ED8936" },
                { id: "arts", name: "Künste", description: "Künstlerische Ausdrucksformen", color_code: "#ED64A6" }
            ],
            edges: [
                { source: "root", target: "philosophy" },
                { source: "root", target: "science" },
                { source: "root", target: "technology" },
                { source: "root", target: "arts" }
            ]
        };
    }
    
    /**
     * Initialisiert Cytoscape.js
     */
    initializeCytoscape() {
        if (!this.container) {
            console.error(`Container mit ID '${this.containerId}' nicht gefunden.`);
            return;
        }
        
        // Konvertiert die API-Daten ins Cytoscape-Format
        const elements = this.convertToCytoscapeFormat(this.data);
        
        // Erstellt die Cytoscape-Instanz
        this.cy = cytoscape({
            container: this.container,
            elements: elements,
            style: this.getStyles(),
            layout: {
                name: this.options.defaultLayout,
                animate: true,
                animationDuration: 800,
                nodeDimensionsIncludeLabels: true,
                padding: 30,
                spacingFactor: 1.2,
                randomize: true,
                componentSpacing: 100,
                nodeRepulsion: 8000,
                edgeElasticity: 100,
                nestingFactor: 1.2,
                gravity: 80
            }
        });
        
        // Event-Listener für Knotenklicks
        this.cy.on('tap', 'node', (event) => {
            const node = event.target;
            this.handleNodeClick(node);
        });
        
        console.log("Cytoscape initialisiert");
    }
    
    /**
     * Konvertiert API-Daten ins Cytoscape-Format
     * @param {Object} data - Daten von der API
     * @returns {Array} - Elemente im Cytoscape-Format
     */
    convertToCytoscapeFormat(data) {
        const elements = [];
        
        // Überprüfen, ob wir Daten aus der API haben
        if (data.nodes && Array.isArray(data.nodes)) {
            // Füge zuerst einen Root-Knoten "Wissen" hinzu, falls er nicht existiert
            let rootExists = data.nodes.some(node => node.name === "Wissen");
            
            if (!rootExists) {
                elements.push({
                    data: {
                        id: "root",
                        name: "Wissen",
                        description: "Zentrale Wissensbasis",
                        color: "#4299E1",
                        isRoot: true
                    }
                });
            }
            
            // Knoten hinzufügen
            data.nodes.forEach(node => {
                // Prüfen, ob es sich um einen Knoten-Objekt oder einen Baum handelt
                const nodeId = node.id || `node-${elements.length}`;
                const nodeName = node.name;
                const nodeDesc = node.description || "";
                const nodeColor = node.color_code || '#8B5CF6';
                
                elements.push({
                    data: {
                        id: nodeId,
                        name: nodeName,
                        description: nodeDesc,
                        color: nodeColor,
                        category: node.category_id,
                        isRoot: node.name === "Wissen"
                    }
                });
                
                // Falls es ein hierarchischer Baum ist mit Kindern
                if (node.children && Array.isArray(node.children)) {
                    this.processChildNodes(node, elements, nodeId);
                }
            });
            
            // Kanten hinzufügen - bei hierarchischen Daten
            if (!data.edges || !Array.isArray(data.edges)) {
                // Wenn keine Kanten definiert sind, verknüpfe alle Root-Knoten mit dem "Wissen" Knoten
                const rootId = elements.find(el => el.data.isRoot)?.data.id || "root";
                
                elements.forEach(element => {
                    if (element.data.id !== rootId && !element.data.hasParent) {
                        elements.push({
                            data: {
                                id: `${rootId}-${element.data.id}`,
                                source: rootId,
                                target: element.data.id
                            }
                        });
                    }
                });
            } else {
                // Wenn Kanten definiert sind, diese direkt verwenden
                data.edges.forEach(edge => {
                    elements.push({
                        data: {
                            id: `${edge.source}-${edge.target}`,
                            source: edge.source,
                            target: edge.target
                        }
                    });
                });
            }
        }
        
        return elements;
    }
    
    /**
     * Verarbeitet Kindknoten rekursiv für hierarchische Daten
     * @param {Object} node - Der aktuelle Knoten
     * @param {Array} elements - Das Element-Array
     * @param {string} parentId - Die ID des Elternknotens
     */
    processChildNodes(node, elements, parentId) {
        if (node.children && Array.isArray(node.children)) {
            node.children.forEach(child => {
                const childId = child.id || `node-${elements.length}`;
                const childName = child.name;
                const childDesc = child.description || "";
                const childColor = child.color_code || '#8B5CF6';
                
                elements.push({
                    data: {
                        id: childId,
                        name: childName,
                        description: childDesc,
                        color: childColor,
                        category: child.category_id,
                        hasParent: true
                    }
                });
                
                // Kante zum Elternknoten
                elements.push({
                    data: {
                        id: `${parentId}-${childId}`,
                        source: parentId,
                        target: childId
                    }
                });
                
                // Rekursiv Kinder verarbeiten
                this.processChildNodes(child, elements, childId);
            });
        }
    }
    
    /**
     * Liefert die Styles für Cytoscape
     * @returns {Array} - Cytoscape-Stylesheets
     */
    getStyles() {
        const darkMode = this.options.darkMode;
        
        return [
            {
                selector: 'node',
                style: {
                    'background-color': 'data(color)',
                    'label': 'data(name)',
                    'width': 40,
                    'height': 40,
                    'font-size': 12,
                    'text-valign': 'bottom',
                    'text-halign': 'center',
                    'text-margin-y': 8,
                    'color': darkMode ? '#f1f5f9' : '#334155',
                    'text-background-color': darkMode ? 'rgba(30, 41, 59, 0.8)' : 'rgba(241, 245, 249, 0.8)',
                    'text-background-opacity': 0.8,
                    'text-background-padding': '2px',
                    'text-background-shape': 'roundrectangle',
                    'text-wrap': 'ellipsis',
                    'text-max-width': '100px'
                }
            },
            {
                selector: 'node[?isRoot]',
                style: {
                    'width': 60,
                    'height': 60,
                    'font-size': 14,
                    'font-weight': 'bold',
                    'text-background-opacity': 0.9,
                    'text-background-color': '#4299E1'
                }
            },
            {
                selector: 'edge',
                style: {
                    'width': 2,
                    'line-color': darkMode ? 'rgba(255, 255, 255, 0.15)' : 'rgba(30, 41, 59, 0.15)',
                    'target-arrow-color': darkMode ? 'rgba(255, 255, 255, 0.15)' : 'rgba(30, 41, 59, 0.15)',
                    'curve-style': 'bezier',
                    'target-arrow-shape': 'triangle'
                }
            },
            {
                selector: 'node:selected',
                style: {
                    'background-color': 'data(color)',
                    'border-width': 3,
                    'border-color': '#8b5cf6',
                    'width': 50,
                    'height': 50,
                    'font-size': 14,
                    'font-weight': 'bold',
                    'text-background-color': '#8b5cf6',
                    'text-background-opacity': 0.9
                }
            }
        ];
    }
    
    /**
     * Aktualisiert die Styles basierend auf dem Dark Mode
     */
    updateStyles() {
        this.cy.style(this.getStyles());
    }
    
    /**
     * Behandelt den Klick auf einen Knoten
     * @param {Object} node - Cytoscape-Knoten
     */
    handleNodeClick(node) {
        console.log("Knoten angeklickt:", node.id(), node.data());
        
        // Callback aufrufen, falls definiert
        if (typeof this.options.onNodeClick === 'function') {
            this.options.onNodeClick(node.data());
        }
    }
    
    /**
     * Passt die Ansicht an alle Elemente an
     */
    fitToElements() {
        if (this.cy) {
            this.cy.fit();
            this.cy.center();
        }
    }
    
    /**
     * Setzt das Layout zurück
     * @param {string} layoutName - Name des Layouts (optional)
     */
    resetLayout(layoutName) {
        if (this.cy) {
            this.cy.layout({
                name: layoutName || this.options.defaultLayout,
                animate: true,
                randomize: true,
                fit: true
            }).run();
        }
    }
}

// Globale Export
window.MindMap.Visualization = MindmapVisualization;

// Automatische Initialisierung, wenn das DOM geladen ist
document.addEventListener('DOMContentLoaded', function() {
    const cyContainer = document.getElementById('cy');
    if (cyContainer) {
        console.log("Mindmap-Container gefunden, initialisiere...");
        const mindmap = new MindmapVisualization('cy', {
            onNodeClick: function(nodeData) {
                console.log("Knoten ausgewählt:", nodeData);
                // Hier könnte man weitere Aktionen durchführen
            }
        });
        
        mindmap.initialize().then(() => {
            console.log("Mindmap erfolgreich initialisiert");
            
            // Speichere die Instanz global für den Zugriff von außen
            window.mindmap = mindmap;
        }).catch(error => {
            console.error("Fehler bei der Initialisierung der Mindmap:", error);
        });
    }
});
