/**
 * MYP Platform Core Utilities - Optimized Version
 * Consolidates common functionality from multiple files
 * Reduces redundancy and improves performance
 */

(function(window) {
    'use strict';

    // Single instance pattern for core utilities
    const MYPCore = {
        // Version for cache busting
        version: '1.0.0',
        
        // CSRF Token Management (replaces 22+ different implementations)
        csrf: {
            _token: null,
            
            getToken() {
                if (!this._token) {
                    // Try multiple sources in order of preference
                    this._token = 
                        document.querySelector('meta[name="csrf-token"]')?.content ||
                        document.querySelector('input[name="csrf_token"]')?.value ||
                        this._getFromCookie('csrf_token') ||
                        '';
                }
                return this._token;
            },
            
            _getFromCookie(name) {
                const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
                return match ? match[2] : null;
            },
            
            clearCache() {
                this._token = null;
            }
        },

        // DOM Utilities with caching
        dom: {
            _cache: new Map(),
            
            // Cached querySelector
            get(selector, parent = document) {
                const key = `${parent === document ? 'doc' : 'el'}_${selector}`;
                if (!this._cache.has(key)) {
                    this._cache.set(key, parent.querySelector(selector));
                }
                return this._cache.get(key);
            },
            
            // Cached querySelectorAll
            getAll(selector, parent = document) {
                return parent.querySelectorAll(selector);
            },
            
            // Efficient HTML escaping
            escapeHtml(text) {
                const div = this._escapeDiv || (this._escapeDiv = document.createElement('div'));
                div.textContent = text;
                return div.innerHTML;
            },
            
            // Clear cache when DOM changes
            clearCache() {
                this._cache.clear();
            },
            
            // Efficient element creation
            create(tag, attrs = {}, children = []) {
                const el = document.createElement(tag);
                Object.entries(attrs).forEach(([key, value]) => {
                    if (key === 'class') {
                        el.className = value;
                    } else if (key === 'style' && typeof value === 'object') {
                        Object.assign(el.style, value);
                    } else if (key.startsWith('data-')) {
                        el.dataset[key.slice(5)] = value;
                    } else {
                        el.setAttribute(key, value);
                    }
                });
                children.forEach(child => {
                    if (typeof child === 'string') {
                        el.appendChild(document.createTextNode(child));
                    } else {
                        el.appendChild(child);
                    }
                });
                return el;
            }
        },

        // Unified Notification System (replaces 3 separate systems)
        notify: {
            _container: null,
            _queue: [],
            _activeToasts: new Map(),
            _toastId: 0,
            
            show(message, type = 'info', duration = 5000, options = {}) {
                // Check for DND mode
                if (window.dndManager?.isEnabled && !options.force) {
                    console.log(`[DND] Suppressed ${type} notification:`, message);
                    return null;
                }
                
                const id = `toast-${++this._toastId}`;
                const toast = this._createToast(id, message, type, duration, options);
                
                this._ensureContainer();
                this._container.appendChild(toast);
                
                // Animate in
                requestAnimationFrame(() => {
                    toast.classList.add('show');
                });
                
                // Auto remove
                if (duration > 0 && !options.persistent) {
                    const timeout = setTimeout(() => this.close(id), duration);
                    this._activeToasts.set(id, { element: toast, timeout });
                }
                
                return id;
            },
            
            _createToast(id, message, type, duration, options) {
                const toast = MYPCore.dom.create('div', {
                    id,
                    class: `myp-toast myp-toast-${type}`,
                    role: 'alert',
                    'aria-live': 'polite'
                });
                
                const icon = this._getIcon(type);
                const content = MYPCore.dom.create('div', { class: 'toast-content' }, [
                    MYPCore.dom.create('span', { class: 'toast-icon' }, [icon]),
                    MYPCore.dom.create('span', { class: 'toast-message' }, [message])
                ]);
                
                const closeBtn = MYPCore.dom.create('button', {
                    class: 'toast-close',
                    'aria-label': 'Close notification',
                    onclick: () => this.close(id)
                }, ['×']);
                
                toast.appendChild(content);
                toast.appendChild(closeBtn);
                
                if (duration > 0 && !options.persistent) {
                    const progress = MYPCore.dom.create('div', { class: 'toast-progress' });
                    const bar = MYPCore.dom.create('div', { 
                        class: 'toast-progress-bar',
                        style: { animationDuration: `${duration}ms` }
                    });
                    progress.appendChild(bar);
                    toast.appendChild(progress);
                }
                
                return toast;
            },
            
            _getIcon(type) {
                const icons = {
                    success: '✓',
                    error: '✗',
                    warning: '⚠',
                    info: 'ℹ'
                };
                return icons[type] || icons.info;
            },
            
            _ensureContainer() {
                if (!this._container) {
                    this._container = MYPCore.dom.get('#myp-toast-container') ||
                        MYPCore.dom.create('div', { id: 'myp-toast-container', class: 'myp-toast-container' });
                    
                    if (!this._container.parentNode) {
                        document.body.appendChild(this._container);
                    }
                }
            },
            
            close(id) {
                const toast = this._activeToasts.get(id);
                if (toast) {
                    clearTimeout(toast.timeout);
                    toast.element.classList.remove('show');
                    setTimeout(() => {
                        toast.element.remove();
                        this._activeToasts.delete(id);
                    }, 300);
                }
            },
            
            closeAll() {
                this._activeToasts.forEach((_, id) => this.close(id));
            }
        },

        // API Request Utilities
        api: {
            _cache: new Map(),
            _pendingRequests: new Map(),
            
            async request(url, options = {}) {
                const config = {
                    ...options,
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': MYPCore.csrf.getToken(),
                        ...options.headers
                    }
                };
                
                // Check cache for GET requests
                if (options.method === 'GET' || !options.method) {
                    const cacheKey = this._getCacheKey(url, options);
                    const cached = this._cache.get(cacheKey);
                    
                    if (cached && !options.noCache) {
                        const age = Date.now() - cached.timestamp;
                        const maxAge = options.cacheTime || 300000; // 5 minutes default
                        
                        if (age < maxAge) {
                            return cached.data;
                        }
                    }
                    
                    // Prevent duplicate requests
                    if (this._pendingRequests.has(cacheKey)) {
                        return this._pendingRequests.get(cacheKey);
                    }
                }
                
                // Make request
                const requestPromise = fetch(url, config)
                    .then(async response => {
                        if (!response.ok) {
                            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                        }
                        
                        const data = await response.json();
                        
                        // Cache successful GET requests
                        if (config.method === 'GET' || !config.method) {
                            const cacheKey = this._getCacheKey(url, options);
                            this._cache.set(cacheKey, {
                                data,
                                timestamp: Date.now()
                            });
                            this._pendingRequests.delete(cacheKey);
                        }
                        
                        return data;
                    })
                    .catch(error => {
                        if (config.method === 'GET' || !config.method) {
                            this._pendingRequests.delete(this._getCacheKey(url, options));
                        }
                        throw error;
                    });
                
                if (config.method === 'GET' || !config.method) {
                    this._pendingRequests.set(this._getCacheKey(url, options), requestPromise);
                }
                
                return requestPromise;
            },
            
            _getCacheKey(url, options) {
                return `${url}_${JSON.stringify(options.params || {})}`;
            },
            
            clearCache(pattern) {
                if (pattern) {
                    for (const [key] of this._cache) {
                        if (key.includes(pattern)) {
                            this._cache.delete(key);
                        }
                    }
                } else {
                    this._cache.clear();
                }
            }
        },

        // Time/Date Utilities
        time: {
            formatAgo(timestamp) {
                const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
                const now = new Date();
                const seconds = Math.floor((now - date) / 1000);
                
                const intervals = [
                    { label: 'Jahr', seconds: 31536000, plural: 'Jahre' },
                    { label: 'Monat', seconds: 2592000, plural: 'Monate' },
                    { label: 'Woche', seconds: 604800, plural: 'Wochen' },
                    { label: 'Tag', seconds: 86400, plural: 'Tage' },
                    { label: 'Stunde', seconds: 3600, plural: 'Stunden' },
                    { label: 'Minute', seconds: 60, plural: 'Minuten' }
                ];
                
                for (const interval of intervals) {
                    const count = Math.floor(seconds / interval.seconds);
                    if (count >= 1) {
                        const label = count === 1 ? interval.label : interval.plural;
                        return `vor ${count} ${label}`;
                    }
                }
                
                return 'Gerade eben';
            },
            
            formatDuration(seconds) {
                const hours = Math.floor(seconds / 3600);
                const minutes = Math.floor((seconds % 3600) / 60);
                const secs = seconds % 60;
                
                const parts = [];
                if (hours > 0) parts.push(`${hours}h`);
                if (minutes > 0) parts.push(`${minutes}m`);
                if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);
                
                return parts.join(' ');
            }
        },

        // Performance Utilities
        perf: {
            debounce(func, wait) {
                let timeout;
                return function debounced(...args) {
                    const context = this;
                    clearTimeout(timeout);
                    timeout = setTimeout(() => func.apply(context, args), wait);
                };
            },
            
            throttle(func, limit) {
                let inThrottle;
                return function throttled(...args) {
                    const context = this;
                    if (!inThrottle) {
                        func.apply(context, args);
                        inThrottle = true;
                        setTimeout(() => inThrottle = false, limit);
                    }
                };
            },
            
            memoize(func, resolver) {
                const cache = new Map();
                return function memoized(...args) {
                    const key = resolver ? resolver(...args) : args[0];
                    if (cache.has(key)) {
                        return cache.get(key);
                    }
                    const result = func.apply(this, args);
                    cache.set(key, result);
                    return result;
                };
            }
        },

        // Event Management
        events: {
            _listeners: new Map(),
            
            on(element, event, handler, options = {}) {
                const key = `${element}_${event}`;
                if (!this._listeners.has(key)) {
                    this._listeners.set(key, new Set());
                }
                
                this._listeners.get(key).add(handler);
                element.addEventListener(event, handler, options);
                
                // Return cleanup function
                return () => this.off(element, event, handler);
            },
            
            off(element, event, handler) {
                const key = `${element}_${event}`;
                const handlers = this._listeners.get(key);
                
                if (handlers) {
                    handlers.delete(handler);
                    if (handlers.size === 0) {
                        this._listeners.delete(key);
                    }
                }
                
                element.removeEventListener(event, handler);
            },
            
            once(element, event, handler, options = {}) {
                const wrappedHandler = (e) => {
                    handler(e);
                    this.off(element, event, wrappedHandler);
                };
                
                return this.on(element, event, wrappedHandler, options);
            }
        },

        // Storage Utilities
        storage: {
            get(key, defaultValue = null) {
                try {
                    const item = localStorage.getItem(`myp_${key}`);
                    return item ? JSON.parse(item) : defaultValue;
                } catch (e) {
                    console.error('Storage get error:', e);
                    return defaultValue;
                }
            },
            
            set(key, value) {
                try {
                    localStorage.setItem(`myp_${key}`, JSON.stringify(value));
                    return true;
                } catch (e) {
                    console.error('Storage set error:', e);
                    return false;
                }
            },
            
            remove(key) {
                localStorage.removeItem(`myp_${key}`);
            },
            
            clear(prefix = 'myp_') {
                const keys = Object.keys(localStorage);
                keys.forEach(key => {
                    if (key.startsWith(prefix)) {
                        localStorage.removeItem(key);
                    }
                });
            }
        }
    };

    // Global shortcuts for backwards compatibility
    window.MYPCore = MYPCore;
    
    // Legacy function mappings
    window.showToast = (msg, type, duration) => MYPCore.notify.show(msg, type, duration);
    window.showNotification = window.showToast;
    window.showFlashMessage = window.showToast;
    window.showSuccessMessage = (msg) => MYPCore.notify.show(msg, 'success');
    window.showErrorMessage = (msg) => MYPCore.notify.show(msg, 'error');
    window.showWarningMessage = (msg) => MYPCore.notify.show(msg, 'warning');
    window.showInfoMessage = (msg) => MYPCore.notify.show(msg, 'info');
    
    // Auto-initialize on DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            console.log('✅ MYP Core Utilities initialized');
        });
    } else {
        console.log('✅ MYP Core Utilities initialized');
    }

})(window);