import { BunnyService } from './bunny'; interface VideoSyncCache { videos: any[]; lastUpdate: number; isUpdating: boolean; } class VideoSyncService { private cache: VideoSyncCache = { videos: [], lastUpdate: 0, isUpdating: false }; private bunnyService: BunnyService; private syncInterval: NodeJS.Timeout | null = null; constructor() { this.bunnyService = new BunnyService(); } async initialize() { console.log('🔄 Initializing video sync service...'); try { await this.syncVideos(); this.startPeriodicSync(); console.log('✅ Video sync service initialized successfully'); } catch (error) { console.error('❌ Failed to initialize video sync service:', error); // Continue without crashing the server } } private async syncVideos() { if (this.cache.isUpdating) { console.log('⏳ Video sync already in progress, skipping...'); return; } this.cache.isUpdating = true; const startTime = Date.now(); try { console.log('🔍 Fetching latest videos from Bunny.net...'); const result = await this.bunnyService.getVideos(1, 100); this.cache.videos = result.videos; this.cache.lastUpdate = Date.now(); const duration = Date.now() - startTime; console.log(`✅ Video sync completed: ${result.videos.length} videos cached in ${duration}ms`); } catch (error) { console.error('❌ Video sync failed:', error); } finally { this.cache.isUpdating = false; } } private startPeriodicSync() { // Sync every 60 seconds this.syncInterval = setInterval(() => { console.log('⏰ Starting scheduled video sync...'); this.syncVideos(); }, 60 * 1000); console.log('📅 Scheduled video sync every 60 seconds'); } getVideos(limit: number = 20, offset: number = 0, search?: string) { let filteredVideos = this.cache.videos; // Fast client-side search if (search && search.length >= 2) { const searchLower = search.toLowerCase(); filteredVideos = this.cache.videos.filter(video => video.title.toLowerCase().includes(searchLower) || video.description?.toLowerCase().includes(searchLower) ); } const paginatedVideos = filteredVideos.slice(offset, offset + limit); return { videos: paginatedVideos, total: filteredVideos.length, hasMore: offset + limit < filteredVideos.length, cacheAge: Date.now() - this.cache.lastUpdate }; } async getVideo(id: string) { // First try cache const cachedVideo = this.cache.videos.find(v => v.id === id); if (cachedVideo) { return cachedVideo; } // Fallback to direct API call return await this.bunnyService.getVideo(id); } getCacheStats() { return { videosCount: this.cache.videos.length, lastUpdate: this.cache.lastUpdate, isUpdating: this.cache.isUpdating, cacheAge: Date.now() - this.cache.lastUpdate }; } stop() { if (this.syncInterval) { clearInterval(this.syncInterval); this.syncInterval = null; console.log('🛑 Video sync service stopped'); } } } export const videoSyncService = new VideoSyncService();