// Advanced performance utilities for optimization and user experience enhancement

/**
 * Preload critical resources for improved perceived performance
 */
export const preloadManager = {
    // Track preloaded resources to avoid duplicates
    preloadedResources: new Set<string>(),

    /**
     * Preload a route component for instant navigation
     */
    preloadRoute(routeName: string) {
        if (this.preloadedResources.has(routeName)) return

        // Dynamic import based on route name
        const routeMap: Record<string, () => Promise<any>> = {
            'lists': () => import('@/pages/ListsPage.vue'),
            'list-detail': () => import('@/pages/ListDetailPage.vue'),
            'expenses': () => import('@/pages/ExpensesPage.vue'),
            'chores': () => import('@/pages/ChoresPage.vue'),
            'groups': () => import('@/pages/GroupsPage.vue'),
            'account': () => import('@/pages/AccountPage.vue'),
        }

        const preloader = routeMap[routeName]
        if (preloader) {
            preloader().then(() => {
                this.preloadedResources.add(routeName)
                console.log(`[Performance] Preloaded route: ${routeName}`)
            }).catch(error => {
                console.warn(`[Performance] Failed to preload route ${routeName}:`, error)
            })
        }
    },

    /**
     * Preload the most likely next routes based on current page
     */
    preloadLikelyRoutes(currentRoute: string) {
        const routePredictions: Record<string, string[]> = {
            'dashboard': ['lists', 'expenses', 'chores'],
            'lists': ['list-detail', 'expenses'],
            'list-detail': ['expenses'],
            'expenses': ['lists'],
            'chores': ['lists'],
            'groups': ['account'],
        }

        const routes = routePredictions[currentRoute] || []
        routes.forEach(route => this.preloadRoute(route))
    },

    /**
     * Preload images that are likely to be shown soon
     */
    preloadImages(imageUrls: string[]) {
        imageUrls.forEach(url => {
            if (this.preloadedResources.has(url)) return

            const link = document.createElement('link')
            link.rel = 'preload'
            link.as = 'image'
            link.href = url
            document.head.appendChild(link)

            this.preloadedResources.add(url)
        })
    }
}

/**
 * Lazy loading utilities with intersection observer
 */
export const lazyLoader = {
    observer: null as IntersectionObserver | null,

    /**
     * Initialize intersection observer for lazy loading
     */
    init() {
        if (this.observer || typeof window === 'undefined') return

        this.observer = new IntersectionObserver(
            (entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const element = entry.target as HTMLElement
                        const callback = element.dataset.lazyCallback

                        if (callback && (window as any)[callback]) {
                            (window as any)[callback](element)
                            this.observer?.unobserve(element)
                        }
                    }
                })
            },
            {
                rootMargin: '50px 0px', // Start loading 50px before element comes into view
                threshold: 0.1
            }
        )
    },

    /**
     * Observe an element for lazy loading
     */
    observe(element: HTMLElement, callback: (el: HTMLElement) => void) {
        if (!this.observer) this.init()

        // Store callback globally (simple approach)
        const callbackName = `lazyCallback_${Date.now()}_${Math.random().toString(36).substring(2)}`
            ; (window as any)[callbackName] = callback
        element.dataset.lazyCallback = callbackName

        this.observer?.observe(element)
    },

    /**
     * Lazy load images with fade-in effect
     */
    lazyLoadImage(img: HTMLImageElement, src: string) {
        this.observe(img, (element) => {
            const imgEl = element as HTMLImageElement
            imgEl.style.opacity = '0'
            imgEl.style.transition = 'opacity 0.3s ease-in-out'

            imgEl.onload = () => {
                imgEl.style.opacity = '1'
            }

            imgEl.src = src
        })
    }
}

/**
 * Cache management for API responses and assets
 */
export const cacheManager = {
    // In-memory cache for API responses
    apiCache: new Map<string, { data: any; timestamp: number; ttl: number }>(),

    /**
     * Cache an API response with TTL
     */
    cacheApiResponse(key: string, data: any, ttlMs: number = 5 * 60 * 1000) {
        this.apiCache.set(key, {
            data,
            timestamp: Date.now(),
            ttl: ttlMs
        })
    },

    /**
     * Get cached API response if still valid
     */
    getCachedApiResponse(key: string): any | null {
        const cached = this.apiCache.get(key)
        if (!cached) return null

        const isExpired = Date.now() - cached.timestamp > cached.ttl
        if (isExpired) {
            this.apiCache.delete(key)
            return null
        }

        return cached.data
    },

    /**
     * Clear expired cache entries
     */
    clearExpiredCache() {
        const now = Date.now()
        for (const [key, cached] of this.apiCache.entries()) {
            if (now - cached.timestamp > cached.ttl) {
                this.apiCache.delete(key)
            }
        }
    },

    /**
     * Get cache statistics
     */
    getCacheStats() {
        return {
            size: this.apiCache.size,
            memoryUsage: JSON.stringify([...this.apiCache.entries()]).length
        }
    }
}

/**
 * Bundle size optimization utilities
 */
export const bundleOptimizer = {
    /**
     * Track which features are actually used
     */
    featureUsage: new Map<string, number>(),

    /**
     * Mark a feature as used
     */
    markFeatureUsed(featureName: string) {
        const count = this.featureUsage.get(featureName) || 0
        this.featureUsage.set(featureName, count + 1)
    },

    /**
     * Get usage statistics for bundle optimization
     */
    getUsageStats() {
        return Object.fromEntries(this.featureUsage.entries())
    },

    /**
     * Dynamic import with error handling and fallback
     */
    async dynamicImport<T>(importFn: () => Promise<T>, fallback?: T): Promise<T> {
        try {
            const startTime = performance.now()
            const module = await importFn()
            const duration = performance.now() - startTime

            console.log(`[Bundle] Dynamic import completed in ${duration.toFixed(2)}ms`)
            return module
        } catch (error) {
            console.error('[Bundle] Dynamic import failed:', error)
            if (fallback !== undefined) {
                return fallback
            }
            throw error
        }
    }
}

/**
 * Initialize performance optimizations
 */
export function initAdvancedPerformanceOptimizations() {
    // Initialize lazy loader
    lazyLoader.init()

    // Clear expired cache every 10 minutes
    setInterval(() => {
        cacheManager.clearExpiredCache()
    }, 10 * 60 * 1000)

    // Preload likely routes after initial page load
    setTimeout(() => {
        const currentPath = window.location.pathname
        const routeName = currentPath.split('/')[1] || 'dashboard'
        preloadManager.preloadLikelyRoutes(routeName)
    }, 1000)

    console.log('[Performance] Advanced performance optimizations initialized')
}

// Export all utilities as default
export default {
    preloadManager,
    lazyLoader,
    cacheManager,
    bundleOptimizer,
    initAdvancedPerformanceOptimizations
} 