HEX
Server: LiteSpeed
System: Linux s3.sitechai.com 4.18.0-553.51.1.lve.1.el8.x86_64 #1 SMP Wed May 14 14:34:57 UTC 2025 x86_64
User: workzeni (2217)
PHP: 8.1.32
Disabled: mail, show_source, system, shell_exec, passthru, exec, eval, shell
Upload Files
File: /home/workzeni/stream-flix.workzenix.com/public/admin/js/script.js
/*
 * StreamFlix Admin Panel - Professional OTT Platform Dashboard
 * Modern JavaScript with ES6+ Features
 * 
 * Features:
 * - Sidebar Navigation & Responsive Layout
 * - Theme Toggle (Dark/Light Mode)
 * - Modal Management
 * - Form Validation & Submission
 * - Data Tables with Search, Sort, Pagination
 * - Chart.js Integration for Analytics
 * - Real-time Notifications
 * - Local Storage for Settings
 */

// Global Admin Panel Class
class StreamFlixAdmin {
    constructor() {
        this.sidebar = null;
        this.theme = localStorage.getItem('admin-theme') || 'light';
        this.sidebarCollapsed = localStorage.getItem('sidebar-collapsed') === 'true';
        this.currentPage = window.location.pathname.split('/').pop() || 'dashboard.html';
        
        this.init();
    }

    // Initialize the admin panel
    init() {
        this.initTheme();
        this.initSidebar();
        this.initDropdowns();
        this.initModals();
        this.initForms();
        this.initTables();
        this.initCharts();
        this.initNotifications();
        this.initTooltips();
        this.initAnimations();
        
        // Set active navigation
        this.setActiveNavigation();
        
        console.log('StreamFlix Admin Panel Initialized');
    }

    // Theme Management
    initTheme() {
        // Set initial theme using data-theme attribute
        document.documentElement.setAttribute('data-theme', this.theme);
        
        const themeToggle = document.querySelector('.theme-toggle');
        if (themeToggle) {
            // Update toggle button text and icon
            this.updateThemeToggleUI();
            
            // Add click event listener
            themeToggle.addEventListener('click', () => this.toggleTheme());
        }
    }

    toggleTheme() {
        // Switch between light and dark themes
        this.theme = this.theme === 'light' ? 'dark' : 'light';
        
        // Update document attribute for CSS theme switching
        document.documentElement.setAttribute('data-theme', this.theme);
        
        // Save to localStorage
        localStorage.setItem('admin-theme', this.theme);
        
        // Update UI
        this.updateThemeToggleUI();
        
        // Show notification
        this.showNotification(`Switched to ${this.theme} theme`, 'success');
    }

    updateThemeToggleUI() {
        const themeToggle = document.querySelector('.theme-toggle');
        const themeIcon = themeToggle?.querySelector('.theme-icon');
        const themeText = themeToggle?.querySelector('.theme-text');
        
        if (themeIcon && themeText) {
            if (this.theme === 'light') {
                themeIcon.className = 'theme-icon fas fa-sun';
                themeText.textContent = 'Light';
            } else {
                themeIcon.className = 'theme-icon fas fa-moon';
                themeText.textContent = 'Dark';
            }
        }
    }

    // Dropdown Management
    initDropdowns() {
        // Create backdrop element
        this.createDropdownBackdrop();
        
        // Initialize notification dropdown
        this.initNotificationDropdown();
        
        // Initialize profile dropdown
        this.initProfileDropdown();
        
        // Global click handler to close dropdowns
        document.addEventListener('click', (e) => {
            if (!e.target.closest('.dropdown')) {
                this.closeAllDropdowns();
            }
        });
        
        // ESC key to close dropdowns
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                this.closeAllDropdowns();
            }
        });
    }

    createDropdownBackdrop() {
        if (!document.querySelector('.dropdown-backdrop')) {
            const backdrop = document.createElement('div');
            backdrop.className = 'dropdown-backdrop';
            backdrop.addEventListener('click', () => this.closeAllDropdowns());
            document.body.appendChild(backdrop);
        }
    }

    initNotificationDropdown() {
        const notificationBtn = document.querySelector('.notification-dropdown-trigger');
        if (notificationBtn) {
            notificationBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                this.toggleDropdown('notification-dropdown');
            });
        }
    }

    initProfileDropdown() {
        const profileTrigger = document.querySelector('.profile-trigger');
        if (profileTrigger) {
            profileTrigger.addEventListener('click', (e) => {
                e.stopPropagation();
                this.toggleDropdown('profile-dropdown');
            });
        }
    }

    toggleDropdown(dropdownId) {
        const dropdown = document.querySelector(`.${dropdownId}`);
        const backdrop = document.querySelector('.dropdown-backdrop');
        
        if (!dropdown) return;
        
        // Close other dropdowns first
        this.closeAllDropdowns(dropdownId);
        
        // Toggle current dropdown
        const isOpen = dropdown.classList.contains('open');
        
        if (isOpen) {
            dropdown.classList.remove('open');
            backdrop.classList.remove('show');
        } else {
            dropdown.classList.add('open');
            backdrop.classList.add('show');
        }
    }

    closeAllDropdowns(except = null) {
        const dropdowns = document.querySelectorAll('.dropdown');
        const backdrop = document.querySelector('.dropdown-backdrop');
        
        dropdowns.forEach(dropdown => {
            if (!except || !dropdown.classList.contains(except)) {
                dropdown.classList.remove('open');
            }
        });
        
        if (backdrop) {
            backdrop.classList.remove('show');
        }
    }

    // Notification Management
    markNotificationAsRead(notificationId) {
        const notification = document.querySelector(`[data-notification-id="${notificationId}"]`);
        if (notification) {
            notification.classList.remove('unread');
            this.updateNotificationBadge();
        }
    }

    markAllNotificationsAsRead() {
        const notifications = document.querySelectorAll('.notification-item.unread');
        notifications.forEach(notification => {
            notification.classList.remove('unread');
        });
        this.updateNotificationBadge();
        this.showNotification('All notifications marked as read', 'success');
    }

    updateNotificationBadge() {
        const badge = document.querySelector('.notification-badge');
        const unreadCount = document.querySelectorAll('.notification-item.unread').length;
        
        if (badge) {
            if (unreadCount > 0) {
                badge.textContent = unreadCount > 99 ? '99+' : unreadCount;
                badge.style.display = 'block';
            } else {
                badge.style.display = 'none';
            }
        }
    }

    // Profile Actions
    handleProfileAction(action) {
        switch (action) {
            case 'profile':
                this.showNotification('Opening profile settings...', 'info');
                // Redirect to profile page or open modal
                break;
            case 'settings':
                this.showNotification('Opening account settings...', 'info');
                // Redirect to settings page
                break;
            case 'help':
                this.showNotification('Opening help center...', 'info');
                // Open help modal or redirect
                break;
            case 'logout':
                this.handleLogout();
                break;
            default:
                console.log('Unknown profile action:', action);
        }
        
        this.closeAllDropdowns();
    }

    handleLogout() {
        if (confirm('Are you sure you want to logout?')) {
            this.showNotification('Logging out...', 'info');
            // Simulate logout delay
            setTimeout(() => {
                // Clear localStorage
                localStorage.removeItem('admin-theme');
                localStorage.removeItem('sidebar-collapsed');
                // Redirect to login page
                window.location.href = 'login.html';
            }, 1000);
        }
    }

    // Sidebar Management
    initSidebar() {
        this.sidebar = document.querySelector('.sidebar');
        const toggleBtn = document.querySelector('.sidebar-toggle');
        const overlay = document.querySelector('.sidebar-overlay');
        
        if (this.sidebar) {
            // Apply saved state
            if (this.sidebarCollapsed) {
                this.sidebar.classList.add('collapsed');
            }
            
            // Toggle button
            if (toggleBtn) {
                toggleBtn.addEventListener('click', () => this.toggleSidebar());
            }
            
            // Overlay for mobile
            if (overlay) {
                overlay.addEventListener('click', () => this.closeSidebar());
            }
            
            // Handle window resize
            window.addEventListener('resize', () => this.handleResize());
        }
    }

    toggleSidebar() {
        if (this.sidebar) {
            this.sidebarCollapsed = !this.sidebarCollapsed;
            this.sidebar.classList.toggle('collapsed', this.sidebarCollapsed);
            localStorage.setItem('sidebar-collapsed', this.sidebarCollapsed);
        }
    }

    openSidebar() {
        if (this.sidebar) {
            this.sidebar.classList.add('open');
        }
    }

    closeSidebar() {
        if (this.sidebar) {
            this.sidebar.classList.remove('open');
        }
    }

    handleResize() {
        const isMobile = window.innerWidth <= 1024;
        if (isMobile) {
            this.sidebar?.classList.remove('collapsed');
        } else {
            this.sidebar?.classList.remove('open');
        }
    }

    // Set active navigation based on current page
    setActiveNavigation() {
        const navLinks = document.querySelectorAll('.nav-link');
        navLinks.forEach(link => {
            const href = link.getAttribute('href');
            if (href === this.currentPage || 
                (this.currentPage === '' && href === 'dashboard.html')) {
                link.classList.add('active');
            } else {
                link.classList.remove('active');
            }
        });
    }

    // Modal Management
    // initModals() {
    //     // Modal triggers
    //     document.addEventListener('click', (e) => {
    //         if (e.target.matches('[data-modal]')) {
    //             e.preventDefault();
    //             const modalId = e.target.dataset.modal;
    //             this.openModal(modalId);
    //         }
            
    //         if (e.target.matches('.modal-close') || e.target.matches('.modal-overlay')) {
    //             this.closeModal();
    //         }
    //     });

    //     // ESC key to close modal
    //     document.addEventListener('keydown', (e) => {
    //         if (e.key === 'Escape') {
    //             this.closeModal();
    //         }
    //     });
    // }

    openModal(modalId) {
        const modal = document.getElementById(modalId);
        if (modal) {
            modal.classList.add('show');
            document.body.style.overflow = 'hidden';
            
            // Focus first input
            const firstInput = modal.querySelector('input, select, textarea');
            if (firstInput) {
                setTimeout(() => firstInput.focus(), 100);
            }
        }
    }

    // closeModal() {
    //     const activeModal = document.querySelector('.modal-overlay.show');
    //     if (activeModal) {
    //         activeModal.classList.remove('show');
    //         document.body.style.overflow = '';
    //     }
    // }

    // Form Management
    initForms() {
        const forms = document.querySelectorAll('form[data-form]');
        forms.forEach(form => {
            form.addEventListener('submit', (e) => this.handleFormSubmit(e));
            
            // Real-time validation
            const inputs = form.querySelectorAll('input, select, textarea');
            inputs.forEach(input => {
                input.addEventListener('blur', () => this.validateField(input));
                input.addEventListener('input', () => this.clearFieldError(input));
            });
        });
    }

    handleFormSubmit(e) {
        e.preventDefault();
        const form = e.target;
        const formType = form.dataset.form;
        
        if (this.validateForm(form)) {
            this.submitForm(form, formType);
        }
    }

    validateForm(form) {
        let isValid = true;
        const inputs = form.querySelectorAll('input[required], select[required], textarea[required]');
        
        inputs.forEach(input => {
            if (!this.validateField(input)) {
                isValid = false;
            }
        });
        
        return isValid;
    }

    validateField(field) {
        const value = field.value.trim();
        const type = field.type;
        let isValid = true;
        let errorMessage = '';
        
        // Required validation
        if (field.hasAttribute('required') && !value) {
            isValid = false;
            errorMessage = 'This field is required';
        }
        
        // Email validation
        else if (type === 'email' && value) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(value)) {
                isValid = false;
                errorMessage = 'Please enter a valid email address';
            }
        }
        
        // Password validation
        else if (type === 'password' && value) {
            if (value.length < 6) {
                isValid = false;
                errorMessage = 'Password must be at least 6 characters';
            }
        }
        
        // Number validation
        else if (type === 'number' && value) {
            if (isNaN(value) || value < 0) {
                isValid = false;
                errorMessage = 'Please enter a valid number';
            }
        }
        
        // URL validation
        else if (type === 'url' && value) {
            try {
                new URL(value);
            } catch {
                isValid = false;
                errorMessage = 'Please enter a valid URL';
            }
        }
        
        this.showFieldError(field, isValid ? '' : errorMessage);
        return isValid;
    }

    showFieldError(field, message) {
        this.clearFieldError(field);
        
        if (message) {
            field.classList.add('error');
            const errorDiv = document.createElement('div');
            errorDiv.className = 'field-error';
            errorDiv.textContent = message;
            field.parentNode.appendChild(errorDiv);
        }
    }

    clearFieldError(field) {
        field.classList.remove('error');
        const existingError = field.parentNode.querySelector('.field-error');
        if (existingError) {
            existingError.remove();
        }
    }

    async submitForm(form, formType) {
        const submitBtn = form.querySelector('button[type="submit"]');
        const originalText = submitBtn.textContent;
        
        // Show loading state
        submitBtn.disabled = true;
        submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Saving...';
        
        try {
            const formData = new FormData(form);
            const data = Object.fromEntries(formData.entries());
            
            // Simulate API call
            await this.simulateApiCall(formType, data);
            
            // Success
            this.showNotification(`${formType} saved successfully!`, 'success');
            this.closeModal();
            form.reset();
            
            // Refresh data if needed
            if (formType.includes('add') || formType.includes('edit')) {
                this.refreshTableData();
            }
            
        } catch (error) {
            this.showNotification(`Error saving ${formType}: ${error.message}`, 'error');
        } finally {
            // Reset button
            submitBtn.disabled = false;
            submitBtn.textContent = originalText;
        }
    }

    // Simulate API calls for demo
    async simulateApiCall(type, data) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                // Simulate random success/failure for demo
                if (Math.random() > 0.1) {
                    // Store in localStorage for demo
                    this.saveToLocalStorage(type, data);
                    resolve(data);
                } else {
                    reject(new Error('Network error'));
                }
            }, 1000 + Math.random() * 1000);
        });
    }

    saveToLocalStorage(type, data) {
        const key = type.replace('add-', '').replace('edit-', '') + 's';
        let items = JSON.parse(localStorage.getItem(key) || '[]');
        
        if (type.includes('add')) {
            data.id = Date.now();
            data.createdAt = new Date().toISOString();
            items.push(data);
        } else if (type.includes('edit')) {
            const index = items.findIndex(item => item.id == data.id);
            if (index !== -1) {
                items[index] = { ...items[index], ...data, updatedAt: new Date().toISOString() };
            }
        }
        
        localStorage.setItem(key, JSON.stringify(items));
    }

    // Table Management
    initTables() {
        const tables = document.querySelectorAll('[data-table]');
        tables.forEach(table => {
            this.initTableFeatures(table);
        });
    }

    initTableFeatures(table) {
        const tableContainer = table.closest('.table-container');
        if (!tableContainer) return;
        
        // Search functionality
        const searchInput = tableContainer.querySelector('.table-search');
        if (searchInput) {
            searchInput.addEventListener('input', (e) => {
                this.filterTable(table, e.target.value);
            });
        }
        
        // Sort functionality
        const sortableHeaders = table.querySelectorAll('th[data-sort]');
        sortableHeaders.forEach(header => {
            header.style.cursor = 'pointer';
            header.addEventListener('click', () => {
                this.sortTable(table, header.dataset.sort);
            });
        });
        
        // Pagination
        this.initPagination(table);
    }

    filterTable(table, searchTerm) {
        const rows = table.querySelectorAll('tbody tr');
        const term = searchTerm.toLowerCase();
        
        rows.forEach(row => {
            const text = row.textContent.toLowerCase();
            row.style.display = text.includes(term) ? '' : 'none';
        });
    }

    sortTable(table, column) {
        const tbody = table.querySelector('tbody');
        const rows = Array.from(tbody.querySelectorAll('tr'));
        const columnIndex = Array.from(table.querySelectorAll('th')).findIndex(th => th.dataset.sort === column);
        
        if (columnIndex === -1) return;
        
        const isAscending = table.dataset.sortDirection !== 'asc';
        table.dataset.sortDirection = isAscending ? 'asc' : 'desc';
        
        rows.sort((a, b) => {
            const aVal = a.cells[columnIndex].textContent.trim();
            const bVal = b.cells[columnIndex].textContent.trim();
            
            // Try to parse as numbers
            const aNum = parseFloat(aVal);
            const bNum = parseFloat(bVal);
            
            if (!isNaN(aNum) && !isNaN(bNum)) {
                return isAscending ? aNum - bNum : bNum - aNum;
            }
            
            // String comparison
            return isAscending ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
        });
        
        // Re-append sorted rows
        rows.forEach(row => tbody.appendChild(row));
        
        // Update sort indicators
        table.querySelectorAll('th').forEach(th => th.classList.remove('sort-asc', 'sort-desc'));
        const sortedHeader = table.querySelector(`th[data-sort="${column}"]`);
        if (sortedHeader) {
            sortedHeader.classList.add(isAscending ? 'sort-asc' : 'sort-desc');
        }
    }

    initPagination(table) {
        const paginationContainer = table.closest('.table-container').querySelector('.pagination-container');
        if (!paginationContainer) return;
        
        const rowsPerPage = parseInt(table.dataset.perPage) || 10;
        const rows = table.querySelectorAll('tbody tr');
        const totalPages = Math.ceil(rows.length / rowsPerPage);
        
        if (totalPages <= 1) return;
        
        let currentPage = 1;
        
        const showPage = (page) => {
            const start = (page - 1) * rowsPerPage;
            const end = start + rowsPerPage;
            
            rows.forEach((row, index) => {
                row.style.display = (index >= start && index < end) ? '' : 'none';
            });
            
            currentPage = page;
            this.updatePaginationUI(paginationContainer, currentPage, totalPages);
        };
        
        // Create pagination UI
        this.createPaginationUI(paginationContainer, totalPages, showPage);
        showPage(1);
    }

    createPaginationUI(container, totalPages, showPageCallback) {
        container.innerHTML = `
            <div class="pagination">
                <button class="btn btn-sm btn-outline" data-page="prev">
                    <i class="fas fa-chevron-left"></i>
                </button>
                <div class="page-numbers"></div>
                <button class="btn btn-sm btn-outline" data-page="next">
                    <i class="fas fa-chevron-right"></i>
                </button>
            </div>
        `;
        
        container.addEventListener('click', (e) => {
            const btn = e.target.closest('[data-page]');
            if (!btn) return;
            
            const action = btn.dataset.page;
            const currentPage = parseInt(container.dataset.currentPage) || 1;
            
            if (action === 'prev' && currentPage > 1) {
                showPageCallback(currentPage - 1);
            } else if (action === 'next' && currentPage < totalPages) {
                showPageCallback(currentPage + 1);
            } else if (!isNaN(action)) {
                showPageCallback(parseInt(action));
            }
        });
    }

    updatePaginationUI(container, currentPage, totalPages) {
        container.dataset.currentPage = currentPage;
        
        const pageNumbers = container.querySelector('.page-numbers');
        const prevBtn = container.querySelector('[data-page="prev"]');
        const nextBtn = container.querySelector('[data-page="next"]');
        
        // Update buttons state
        prevBtn.disabled = currentPage === 1;
        nextBtn.disabled = currentPage === totalPages;
        
        // Generate page numbers
        let pages = [];
        const maxVisible = 5;
        
        if (totalPages <= maxVisible) {
            pages = Array.from({ length: totalPages }, (_, i) => i + 1);
        } else {
            const start = Math.max(1, currentPage - 2);
            const end = Math.min(totalPages, start + maxVisible - 1);
            pages = Array.from({ length: end - start + 1 }, (_, i) => start + i);
        }
        
        pageNumbers.innerHTML = pages.map(page => `
            <button class="btn btn-sm ${page === currentPage ? 'btn-primary' : 'btn-outline'}" 
                    data-page="${page}">${page}</button>
        `).join('');
    }

    refreshTableData() {
        // Refresh table data after CRUD operations
        const tables = document.querySelectorAll('[data-table]');
        tables.forEach(table => {
            const tableType = table.dataset.table;
            this.loadTableData(table, tableType);
        });
    }

    loadTableData(table, type) {
        const data = JSON.parse(localStorage.getItem(type + 's') || '[]');
        const tbody = table.querySelector('tbody');
        
        if (!tbody || !data.length) return;
        
        // Generate table rows based on type
        tbody.innerHTML = this.generateTableRows(data, type);
    }

    generateTableRows(data, type) {
        switch (type) {
            case 'movie':
                return data.map(item => `
                    <tr>
                        <td><img src="${item.poster || '/placeholder.jpg'}" alt="${item.title}" style="width: 50px; height: 75px; object-fit: cover; border-radius: 4px;"></td>
                        <td>${item.title}</td>
                        <td>${item.genre}</td>
                        <td>${item.year}</td>
                        <td><span class="badge badge-${item.status === 'active' ? 'success' : 'warning'}">${item.status}</span></td>
                        <td>
                            <button class="btn btn-sm btn-outline" data-modal="editMovieModal" onclick="editMovie(${item.id})">
                                <i class="fas fa-edit"></i>
                            </button>
                            <button class="btn btn-sm btn-outline" onclick="deleteMovie(${item.id})">
                                <i class="fas fa-trash"></i>
                            </button>
                        </td>
                    </tr>
                `).join('');
                
            case 'user':
                return data.map(item => `
                    <tr>
                        <td>${item.name}</td>
                        <td>${item.email}</td>
                        <td><span class="badge badge-${item.role === 'admin' ? 'primary' : item.role === 'editor' ? 'info' : 'success'}">${item.role}</span></td>
                        <td>${new Date(item.createdAt).toLocaleDateString()}</td>
                        <td><span class="badge badge-${item.status === 'active' ? 'success' : 'warning'}">${item.status}</span></td>
                        <td>
                            <button class="btn btn-sm btn-outline" data-modal="editUserModal" onclick="editUser(${item.id})">
                                <i class="fas fa-edit"></i>
                            </button>
                            <button class="btn btn-sm btn-outline" onclick="deleteUser(${item.id})">
                                <i class="fas fa-trash"></i>
                            </button>
                        </td>
                    </tr>
                `).join('');
                
            default:
                return '';
        }
    }

    // Chart Management
    initCharts() {
        // Initialize Chart.js charts if the library is loaded
        if (typeof Chart !== 'undefined') {
            this.initDashboardCharts();
        }
    }

    initDashboardCharts() {
        // Views Chart
        const viewsChart = document.getElementById('viewsChart');
        if (viewsChart) {
            new Chart(viewsChart, {
                type: 'line',
                data: {
                    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
                    datasets: [{
                        label: 'Views',
                        data: [12000, 19000, 15000, 25000, 22000, 30000],
                        borderColor: '#667eea',
                        backgroundColor: 'rgba(102, 126, 234, 0.1)',
                        tension: 0.4
                    }]
                },
                options: {
                    responsive: true,
                    plugins: {
                        legend: {
                            display: false
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            grid: {
                                color: 'rgba(255, 255, 255, 0.1)'
                            },
                            ticks: {
                                color: '#8892b0'
                            }
                        },
                        x: {
                            grid: {
                                color: 'rgba(255, 255, 255, 0.1)'
                            },
                            ticks: {
                                color: '#8892b0'
                            }
                        }
                    }
                }
            });
        }
        
        // Revenue Chart
        const revenueChart = document.getElementById('revenueChart');
        if (revenueChart) {
            new Chart(revenueChart, {
                type: 'doughnut',
                data: {
                    labels: ['Subscriptions', 'Ads', 'Premium'],
                    datasets: [{
                        data: [60, 25, 15],
                        backgroundColor: ['#667eea', '#e94560', '#0f3460'],
                        borderWidth: 0
                    }]
                },
                options: {
                    responsive: true,
                    plugins: {
                        legend: {
                            position: 'bottom',
                            labels: {
                                color: '#8892b0',
                                padding: 20
                            }
                        }
                    }
                }
            });
        }
    }

    // Notification System
    initNotifications() {
        // Create notification container if it doesn't exist
        if (!document.querySelector('.notification-container')) {
            const container = document.createElement('div');
            container.className = 'notification-container';
            container.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                z-index: 9999;
                pointer-events: none;
            `;
            document.body.appendChild(container);
        }
    }

    showNotification(message, type = 'info', duration = 5000) {
        const container = document.querySelector('.notification-container');
        const notification = document.createElement('div');
        
        const icons = {
            success: 'fas fa-check-circle',
            error: 'fas fa-exclamation-circle',
            warning: 'fas fa-exclamation-triangle',
            info: 'fas fa-info-circle'
        };
        
        notification.className = `notification notification-${type} slide-in-right`;
        notification.style.cssText = `
            background: var(--surface-bg);
            border: 1px solid var(--glass-border);
            border-left: 4px solid var(--accent-${type === 'error' ? 'primary' : type === 'success' ? 'success' : 'secondary'});
            border-radius: var(--border-radius-md);
            padding: var(--spacing-md) var(--spacing-lg);
            margin-bottom: var(--spacing-md);
            box-shadow: var(--shadow-lg);
            backdrop-filter: blur(20px);
            pointer-events: auto;
            min-width: 300px;
            max-width: 400px;
        `;
        
        notification.innerHTML = `
            <div class="d-flex align-items-center gap-md">
                <i class="${icons[type]}" style="color: var(--accent-${type === 'error' ? 'primary' : type === 'success' ? 'success' : 'secondary'}); font-size: 1.2rem;"></i>
                <div class="flex-1">
                    <div style="color: var(--text-primary); font-weight: 500;">${message}</div>
                </div>
                <button class="notification-close" style="background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px;">
                    <i class="fas fa-times"></i>
                </button>
            </div>
        `;
        
        // Close button functionality
        notification.querySelector('.notification-close').addEventListener('click', () => {
            this.removeNotification(notification);
        });
        
        container.appendChild(notification);
        
        // Auto remove after duration
        if (duration > 0) {
            setTimeout(() => {
                this.removeNotification(notification);
            }, duration);
        }
    }

    removeNotification(notification) {
        notification.style.transform = 'translateX(100%)';
        notification.style.opacity = '0';
        setTimeout(() => {
            if (notification.parentNode) {
                notification.parentNode.removeChild(notification);
            }
        }, 300);
    }

    // Tooltip Management
    initTooltips() {
        const tooltipElements = document.querySelectorAll('[data-tooltip]');
        tooltipElements.forEach(element => {
            element.classList.add('tooltip');
        });
    }

    // Animation Management
    initAnimations() {
        // Intersection Observer for scroll animations
        const observerOptions = {
            threshold: 0.1,
            rootMargin: '0px 0px -50px 0px'
        };
        
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.classList.add('fade-in');
                    observer.unobserve(entry.target);
                }
            });
        }, observerOptions);
        
        // Observe elements with animation classes
        document.querySelectorAll('.animate-on-scroll').forEach(el => {
            observer.observe(el);
        });
    }

    // Utility Methods
    formatNumber(num) {
        if (num >= 1000000) {
            return (num / 1000000).toFixed(1) + 'M';
        } else if (num >= 1000) {
            return (num / 1000).toFixed(1) + 'K';
        }
        return num.toString();
    }

    formatCurrency(amount) {
        return new Intl.NumberFormat('en-US', {
            style: 'currency',
            currency: 'USD'
        }).format(amount);
    }

    formatDate(date) {
        return new Intl.DateTimeFormat('en-US', {
            year: 'numeric',
            month: 'short',
            day: 'numeric'
        }).format(new Date(date));
    }

    debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }
}

// Initialize admin panel when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    window.adminPanel = new StreamFlixAdmin();
});

// Global utility functions for inline event handlers
function editMovie(id) {
    const movies = JSON.parse(localStorage.getItem('movies') || '[]');
    const movie = movies.find(m => m.id == id);
    if (movie) {
        // Populate edit form
        Object.keys(movie).forEach(key => {
            const input = document.querySelector(`#editMovieModal [name="${key}"]`);
            if (input) input.value = movie[key];
        });
        window.adminPanel.openModal('editMovieModal');
    }
}

function deleteMovie(id) {
    if (confirm('Are you sure you want to delete this movie?')) {
        let movies = JSON.parse(localStorage.getItem('movies') || '[]');
        movies = movies.filter(m => m.id != id);
        localStorage.setItem('movies', JSON.stringify(movies));
        window.adminPanel.refreshTableData();
        window.adminPanel.showNotification('Movie deleted successfully', 'success');
    }
}

function editUser(id) {
    const users = JSON.parse(localStorage.getItem('users') || '[]');
    const user = users.find(u => u.id == id);
    if (user) {
        // Populate edit form
        Object.keys(user).forEach(key => {
            const input = document.querySelector(`#editUserModal [name="${key}"]`);
            if (input) input.value = user[key];
        });
        window.adminPanel.openModal('editUserModal');
    }
}

function deleteUser(id) {
    if (confirm('Are you sure you want to delete this user?')) {
        let users = JSON.parse(localStorage.getItem('users') || '[]');
        users = users.filter(u => u.id != id);
        localStorage.setItem('users', JSON.stringify(users));
        window.adminPanel.refreshTableData();
        window.adminPanel.showNotification('User deleted successfully', 'success');
    }
}

function toggleStatus(type, id) {
    const items = JSON.parse(localStorage.getItem(type + 's') || '[]');
    const item = items.find(i => i.id == id);
    if (item) {
        item.status = item.status === 'active' ? 'inactive' : 'active';
        localStorage.setItem(type + 's', JSON.stringify(items));
        window.adminPanel.refreshTableData();
        window.adminPanel.showNotification(`${type} status updated`, 'success');
    }
}

// Dropdown utility functions
function markNotificationAsRead(notificationId) {
    window.adminPanel.markNotificationAsRead(notificationId);
}

function markAllNotificationsAsRead() {
    window.adminPanel.markAllNotificationsAsRead();
}

function handleProfileAction(action) {
    window.adminPanel.handleProfileAction(action);
}

// Export for module usage
if (typeof module !== 'undefined' && module.exports) {
    module.exports = StreamFlixAdmin;
}