
class NotificationManager {
    constructor() {
        this.unreadCount = 0;
        this.updateInterval = 30000;
        this.init();
    }

    init() {
        this.requestNotificationPermission();
        this.startPolling();
        this.setupBadgeUpdater();
    }

    requestNotificationPermission() {
        if ('Notification' in window && Notification.permission === 'default') {
            Notification.requestPermission();
        }
    }

    startPolling() {
        this.updateUnreadCount();
        setInterval(() => this.updateUnreadCount(), this.updateInterval);
    }

    updateUnreadCount() {
        fetch('/api/notifications/unread')
            .then(r => r.json())
            .then(data => {
                this.unreadCount = data.count;
                this.updateBadge();
                this.updateNotificationBell();
            })
            .catch(err => console.log('Notification fetch failed:', err));
    }

    updateBadge() {
        if ('setAppBadge' in navigator) {
            if (this.unreadCount > 0) {
                navigator.setAppBadge(this.unreadCount);
            } else {
                navigator.clearAppBadge();
            }
        }
    }

    updateNotificationBell() {
        const bellElement = document.getElementById('notification-bell');
        if (bellElement) {
            if (this.unreadCount > 0) {
                bellElement.classList.add('has-unread');
                bellElement.setAttribute('data-count', this.unreadCount);
            } else {
                bellElement.classList.remove('has-unread');
            }
        }
    }

    setupDropdown() {
        const bell = document.getElementById('notification-bell');
        const dropdown = document.getElementById('notification-dropdown');
        if (!bell || !dropdown) return;

        bell.addEventListener('click', (e) => {
            e.preventDefault();
            if (dropdown.classList.contains('visible')) {
                dropdown.classList.remove('visible');
                return;
            }
            this.loadDropdown();
        });

        document.addEventListener('click', (e) => {
            if (!dropdown.contains(e.target) && e.target !== bell) {
                dropdown.classList.remove('visible');
            }
        });
    }

    loadDropdown() {
        const dropdown = document.getElementById('notification-dropdown');
        if (!dropdown) return;
        fetch('/api/notifications/unread')
            .then(r => r.json())
            .then(data => {
                const items = data.notifications.map(n => {
                    const content = JSON.parse(n.data).content || n.type;
                    return `<div class="item ${n.is_read ? '' : 'unread'}" data-id="${n.id}">
                        <i class="fas fa-bell"></i>
                        <span>${content}</span>
                    </div>`;
                });
                dropdown.innerHTML = items.join('') || '<div class="item">Немає нових</div>';
                dropdown.classList.add('visible');
                // attach click handlers to mark read
                dropdown.querySelectorAll('.item').forEach(el => {
                    el.addEventListener('click', () => {
                        const id = el.getAttribute('data-id');
                        this.markAsRead(id).then(() => {
                            el.classList.remove('unread');
                            this.unreadCount = Math.max(0, this.unreadCount - 1);
                            this.updateBadge();
                            this.updateNotificationBell();
                        });
                    });
                });
            });
    }

    setupBadgeUpdater() {
        document.addEventListener('visibilitychange', () => {
            if (!document.hidden) {
                this.updateUnreadCount();
            }
        });
    }

    showNotification(title, options = {}) {
        const defaultOptions = {
            icon: '/assets/img/icon.png',
            badge: '/assets/img/badge.png',
            tag: 'notification',
            requireInteraction: false
        };

        const opts = { ...defaultOptions, ...options };

        if ('Notification' in window && Notification.permission === 'granted') {
            const notif = new Notification(title, opts);
            if (options.onclick) {
                notif.onclick = options.onclick;
            }
        }
    }

    markAsRead(notificationId) {
        return fetch(`/api/notifications/${notificationId}/read`, { method: 'POST' })
            .then(r => r.json())
            .then(() => {
                this.unreadCount = Math.max(0, this.unreadCount - 1);
                this.updateBadge();
                this.updateNotificationBell();
            });
    }

    // convenience helper for clearing all notifications
    clearAll() {
        return fetch('/api/notifications/mark-all-read', { method: 'POST' })
            .then(r => r.json())
            .then(() => {
                this.unreadCount = 0;
                this.updateBadge();
                this.updateNotificationBell();
            });
    }
}

class RealtimeUpdater {
    constructor() {
        this.updateInterval = 45000;
        this.init();
    }

    init() {
        this.startUpdating();
        this.setupVisibilityListener();
    }

    startUpdating() {
        this.updateStats();
        setInterval(() => this.updateStats(), this.updateInterval);
    }

    updateStats() {
        fetch('/api/quick-stats')
            .then(r => r.json())
            .then(data => {
                this.updateDOM(data);
            })
            .catch(err => console.log('Stats update failed:', err));
    }

    updateDOM(data) {
        this.updateElement('notif-count', data.unread_notifications);
        this.updateElement('streak-days', data.level || 0);
    }

    updateElement(id, value) {
        const element = document.getElementById(id);
        if (element && element.textContent !== String(value)) {
            element.textContent = value;
            this.animateUpdate(element);
        }
    }

    animateUpdate(element) {
        element.style.animation = 'none';
        setTimeout(() => {
            element.style.animation = 'pulse 0.5s ease-in-out';
        }, 10);
    }

    setupVisibilityListener() {
        document.addEventListener('visibilitychange', () => {
            if (!document.hidden) {
                this.updateStats();
            }
        });
    }
}

class OfflineDetector {
    constructor() {
        this.init();
    }

    init() {
        window.addEventListener('offline', () => this.handleOffline());
        window.addEventListener('online', () => this.handleOnline());
    }

    handleOffline() {
        const indicator = document.getElementById('offline-indicator');
        if (indicator) {
            indicator.style.display = 'flex';
        }
        this.showToast('Вы отключены от интернета', 'warning');
    }

    handleOnline() {
        const indicator = document.getElementById('offline-indicator');
        if (indicator) {
            indicator.style.display = 'none';
        }
        this.showToast('Соединение восстановлено', 'success');
    }

    showToast(message, type = 'info') {
        const toast = document.createElement('div');
        toast.className = `toast toast-${type}`;
        toast.innerHTML = `
            <i class="fas fa-${type === 'success' ? 'check-circle' : 'exclamation-circle'}"></i>
            ${message}
        `;
        document.body.appendChild(toast);
        setTimeout(() => toast.remove(), 3000);
    }
}

class UniversalSearch {
    constructor(inputSelector = '#search-input') {
        this.input = document.querySelector(inputSelector);
        this.resultsContainer = null;
        this.debounceTimer = null;
        if (this.input) {
            this.init();
        }
    }

    init() {
        this.input.addEventListener('input', (e) => this.handleInput(e));
        this.input.addEventListener('focus', () => this.showResults());
        this.createResultsContainer();
    }

    handleInput(e) {
        clearTimeout(this.debounceTimer);
        const query = e.target.value.trim();

        if (query.length < 2) {
            this.hideResults();
            return;
        }

        this.debounceTimer = setTimeout(() => {
            this.search(query);
        }, 300);
    }

    search(query) {
        fetch(`/search?q=${encodeURIComponent(query)}`)
            .then(r => r.text())
            .then(html => {
                this.displayResults(html, query);
            })
            .catch(() => this.showError());
    }

    displayResults(html, query) {
        if (this.resultsContainer) {
            this.resultsContainer.innerHTML = html;
            this.showResults();
        }
    }

    createResultsContainer() {
        this.resultsContainer = document.createElement('div');
        this.resultsContainer.className = 'search-results';
        this.input.parentElement.appendChild(this.resultsContainer);
    }

    showResults() {
        if (this.resultsContainer) {
            this.resultsContainer.style.display = 'block';
        }
    }

    hideResults() {
        if (this.resultsContainer) {
            this.resultsContainer.style.display = 'none';
        }
    }

    showError() {
        if (this.resultsContainer) {
            this.resultsContainer.innerHTML = '<div class="search-error">Помилка при пошуку</div>';
            this.showResults();
        }
    }
}

class ToastNotification {
    static show(message, type = 'info', duration = 3000) {
        const toast = document.createElement('div');
        toast.className = `toast toast-${type}`;
        toast.innerHTML = `
            <div class="toast-content">
                <i class="fas fa-${this.getIcon(type)}"></i>
                <span>${message}</span>
            </div>
        `;

        const container = document.getElementById('toast-container') || (() => {
            const div = document.createElement('div');
            div.id = 'toast-container';
            document.body.appendChild(div);
            return div;
        })();

        container.appendChild(toast);

        setTimeout(() => {
            toast.classList.add('remove');
            setTimeout(() => toast.remove(), 300);
        }, duration);
    }

    static getIcon(type) {
        const icons = {
            success: 'check-circle',
            error: 'times-circle',
            warning: 'exclamation-circle',
            info: 'info-circle'
        };
        return icons[type] || icons.info;
    }
}

document.addEventListener('DOMContentLoaded', function() {
    window.notificationManager = new NotificationManager();
    window.realtimeUpdater = new RealtimeUpdater();
    window.offlineDetector = new OfflineDetector();
    window.universalSearch = new UniversalSearch();
});
