'use client' import { useState, useEffect } from 'react' // import { useTranslations } from 'next-intl' import { Box, Card, CardContent, Typography, Button, LinearProgress, List, ListItem, ListItemText, ListItemSecondaryAction, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Chip, Alert, Tooltip, CircularProgress } from '@mui/material' import { Download, Delete, CloudDownload, Storage, Wifi, WifiOff, CheckCircle, Error, Info, Refresh } from '@mui/icons-material' import { bibleDownloadManager, type BibleVersion, type DownloadProgress } from '@/lib/offline-storage' interface OfflineDownloadManagerProps { availableVersions: BibleVersion[] onVersionDownloaded?: (versionId: string) => void } export function OfflineDownloadManager({ availableVersions, onVersionDownloaded }: OfflineDownloadManagerProps) { // const t = useTranslations('bible') const [downloadedVersions, setDownloadedVersions] = useState([]) const [downloads, setDownloads] = useState>({}) const [storageInfo, setStorageInfo] = useState({ used: 0, quota: 0, percentage: 0 }) const [isOnline, setIsOnline] = useState(true) const [confirmDelete, setConfirmDelete] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { loadDownloadedVersions() loadStorageInfo() checkOnlineStatus() // Listen for online/offline events const handleOnline = () => setIsOnline(true) const handleOffline = () => setIsOnline(false) window.addEventListener('online', handleOnline) window.addEventListener('offline', handleOffline) return () => { window.removeEventListener('online', handleOnline) window.removeEventListener('offline', handleOffline) } }, []) const loadDownloadedVersions = async () => { try { console.log('[OfflineDownloadManager] Loading downloaded versions...') const versions = await bibleDownloadManager.getDownloadedVersions() console.log('[OfflineDownloadManager] Downloaded versions:', versions) console.log('[OfflineDownloadManager] Number of versions:', versions.length) setDownloadedVersions(versions) } catch (error: unknown) { console.error('Failed to load downloaded versions:', error) } finally { setLoading(false) } } const loadStorageInfo = async () => { try { const info = await bibleDownloadManager.getStorageInfo() setStorageInfo(info) } catch (error: unknown) { console.error('Failed to load storage info:', error) } } const checkOnlineStatus = () => { setIsOnline(navigator.onLine) } const handleDownload = async (version: BibleVersion) => { if (!isOnline) { alert('You need an internet connection to download Bible versions') return } console.log(`Starting download for version: ${version.name} (${version.id})`) try { // Initialize download progress immediately setDownloads(prev => ({ ...prev, [version.id]: { versionId: version.id, status: 'pending', progress: 0, totalBooks: 0, downloadedBooks: 0, totalChapters: 0, downloadedChapters: 0, startedAt: new Date().toISOString() } })) await bibleDownloadManager.downloadVersion( version.id, (progress: DownloadProgress) => { console.log(`Download progress for ${version.name}:`, progress) setDownloads(prev => ({ ...prev, [version.id]: progress })) if (progress.status === 'completed') { console.log(`Download completed for ${version.name}`) loadDownloadedVersions() loadStorageInfo() onVersionDownloaded?.(version.id) // Remove from downloads state after completion setTimeout(() => { setDownloads(prev => { const { [version.id]: _, ...rest } = prev return rest }) }, 3000) } else if (progress.status === 'failed') { console.error(`Download failed for ${version.name}:`, progress.error) alert(`Download failed: ${progress.error || 'Unknown error'}`) } } ) } catch (error: unknown) { console.error('Download failed:', error) const errorMessage = (error as Error)?.message || 'Download failed' // Update downloads state to show failure setDownloads(prev => ({ ...prev, [version.id]: { versionId: version.id, status: 'failed' as const, progress: 0, totalBooks: 0, downloadedBooks: 0, totalChapters: 0, downloadedChapters: 0, startedAt: new Date().toISOString(), error: errorMessage } })) alert(`Download failed: ${errorMessage}`) } } const handleDelete = async (versionId: string) => { try { await bibleDownloadManager.deleteVersion(versionId) setDownloadedVersions(prev => prev.filter(v => v.id !== versionId)) loadStorageInfo() setConfirmDelete(null) } catch (error: unknown) { console.error('Delete failed:', error) alert('Failed to delete version') } } const formatBytes = (bytes: number): string => { if (bytes === 0) return '0 Bytes' const k = 1024 const sizes = ['Bytes', 'KB', 'MB', 'GB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] } const getStatusIcon = (status: string) => { switch (status) { case 'completed': return case 'failed': return case 'downloading': return default: return } } const isVersionDownloaded = (versionId: string) => { return downloadedVersions.some(v => v.id === versionId) } const isVersionDownloading = (versionId: string) => { const status = downloads[versionId]?.status return status === 'downloading' || status === 'pending' } if (loading) { return ( Loading offline storage... ) } return ( {/* Header */} Offline Bible Storage : } label={isOnline ? 'Online' : 'Offline'} color={isOnline ? 'success' : 'error'} size="small" /> {/* Downloaded Versions - Moved to top */} Downloaded Versions ({downloadedVersions.length}) {downloadedVersions.length === 0 ? ( No Bible versions downloaded yet. Download versions below to read offline. ) : ( {downloadedVersions.map((version) => ( {version.abbreviation} - {version.language} {version.downloadedAt && ( Downloaded: {new Date(version.downloadedAt).toLocaleDateString()} )} } /> setConfirmDelete(version.id)} color="error" size="small" > ))} )} {/* Storage Info */} Storage Usage {storageInfo.percentage.toFixed(1)}% {formatBytes(storageInfo.used)} of {formatBytes(storageInfo.quota)} used {downloadedVersions.length} Bible versions downloaded {/* Active Downloads */} {Object.keys(downloads).length > 0 && ( Downloads in Progress {Object.entries(downloads).map(([versionId, progress]) => { const version = availableVersions.find(v => v.id === versionId) return ( {getStatusIcon(progress.status)} {version?.name || versionId} } secondary={ {progress.downloadedChapters} / {progress.totalChapters} chapters ({progress.progress}%) } /> ) })} )} {/* Available Versions for Download */} {isOnline && ( Available for Download {availableVersions .filter(version => !isVersionDownloaded(version.id)) .map((version) => { const downloadProgress = downloads[version.id] const isDownloading = isVersionDownloading(version.id) return ( {isDownloading && downloadProgress && ( {downloadProgress.downloadedChapters} / {downloadProgress.totalChapters} chapters ({downloadProgress.progress}%) )} ) })} {availableVersions.filter(v => !isVersionDownloaded(v.id)).length === 0 && ( All available versions are already downloaded )} )} {/* Delete Confirmation Dialog */} setConfirmDelete(null)} > Delete Bible Version Are you sure you want to delete this Bible version from offline storage? You'll need to download it again to read offline. ) }