import 'package:flutter/foundation.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'models/app_settings.dart'; import 'models/checklist_item.dart'; import 'models/daily_worship_log.dart'; import 'models/dzikir_counter.dart'; import 'models/quran_bookmark.dart'; import 'models/cached_prayer_times.dart'; import 'models/shalat_log.dart'; import 'models/tilawah_log.dart'; import 'models/dzikir_log.dart'; import 'models/puasa_log.dart'; /// Box name constants for Hive. class HiveBoxes { HiveBoxes._(); static const String settings = 'settings'; static const String checklistItems = 'checklist_items'; static const String worshipLogs = 'worship_logs'; static const String dzikirCounters = 'dzikir_counters'; static const String bookmarks = 'bookmarks'; static const String cachedPrayerTimes = 'cached_prayer_times'; } /// Initialize Hive and open all boxes. Future initHive() async { await Hive.initFlutter(); // Register adapters Hive.registerAdapter(AppSettingsAdapter()); Hive.registerAdapter(ChecklistItemAdapter()); Hive.registerAdapter(DailyWorshipLogAdapter()); Hive.registerAdapter(DzikirCounterAdapter()); Hive.registerAdapter(QuranBookmarkAdapter()); Hive.registerAdapter(CachedPrayerTimesAdapter()); Hive.registerAdapter(ShalatLogAdapter()); Hive.registerAdapter(TilawahLogAdapter()); Hive.registerAdapter(DzikirLogAdapter()); Hive.registerAdapter(PuasaLogAdapter()); // Open boxes try { await Hive.openBox(HiveBoxes.settings); } catch (e) { debugPrint('Settings box corrupted, resetting: $e'); if (Hive.isBoxOpen(HiveBoxes.settings)) { await Hive.box(HiveBoxes.settings).close(); } await Hive.deleteBoxFromDisk(HiveBoxes.settings); await Hive.openBox(HiveBoxes.settings); } await Hive.openBox(HiveBoxes.checklistItems); final worshipBox = await Hive.openBox(HiveBoxes.worshipLogs); await Hive.openBox(HiveBoxes.dzikirCounters); await Hive.openBox(HiveBoxes.bookmarks); await Hive.openBox(HiveBoxes.cachedPrayerTimes); // MIGRATION: Delete legacy logs that crash due to type casts (Map vs Map) final keysToDelete = []; for (final key in worshipBox.keys) { try { final log = worshipBox.get(key); if (log != null) { log.shalatLogs.values.toList(); // Force evaluation } } catch (_) { keysToDelete.add(key); } } if (keysToDelete.isNotEmpty) { await worshipBox.deleteAll(keysToDelete); debugPrint('Deleted ${keysToDelete.length} legacy worship logs.'); } } /// Seeds default settings and checklist items on first launch. Future seedDefaults() async { // Seed AppSettings final settingsBox = Hive.box(HiveBoxes.settings); if (settingsBox.isEmpty) { await settingsBox.put('default', AppSettings()); } // Seed default checklist items final checklistBox = Hive.box(HiveBoxes.checklistItems); if (checklistBox.isEmpty) { final defaults = [ ChecklistItem( id: 'fajr', title: 'Sholat Fajr', category: 'sholat_fardhu', sortOrder: 0), ChecklistItem( id: 'dhuhr', title: 'Sholat Dhuhr', category: 'sholat_fardhu', sortOrder: 1), ChecklistItem( id: 'asr', title: 'Sholat Asr', category: 'sholat_fardhu', sortOrder: 2), ChecklistItem( id: 'maghrib', title: 'Sholat Maghrib', category: 'sholat_fardhu', sortOrder: 3), ChecklistItem( id: 'isha', title: 'Sholat Isha', category: 'sholat_fardhu', sortOrder: 4), ChecklistItem( id: 'tilawah', title: 'Tilawah Quran', category: 'tilawah', subtitle: '1 Juz', sortOrder: 5), ChecklistItem( id: 'dzikir_pagi', title: 'Dzikir Pagi', category: 'dzikir', subtitle: '1 session', sortOrder: 6), ChecklistItem( id: 'dzikir_petang', title: 'Dzikir Petang', category: 'dzikir', subtitle: '1 session', sortOrder: 7), ChecklistItem( id: 'rawatib', title: 'Sholat Sunnah Rawatib', category: 'sunnah', sortOrder: 8), ChecklistItem( id: 'shodaqoh', title: 'Shodaqoh', category: 'charity', sortOrder: 9), ]; for (final item in defaults) { await checklistBox.put(item.id, item); } } }