import 'package:hive_flutter/hive_flutter.dart'; import 'package:lunchpick/domain/repositories/settings_repository.dart'; import 'package:lunchpick/domain/entities/user_settings.dart'; class SettingsRepositoryImpl implements SettingsRepository { static const String _boxName = 'settings'; // Setting keys static const String _keyDaysToExclude = 'days_to_exclude'; static const String _keyMaxDistanceRainy = 'max_distance_rainy'; static const String _keyMaxDistanceNormal = 'max_distance_normal'; static const String _keyNotificationDelayMinutes = 'notification_delay_minutes'; static const String _keyNotificationEnabled = 'notification_enabled'; static const String _keyDarkModeEnabled = 'dark_mode_enabled'; static const String _keyFirstRun = 'first_run'; static const String _keyCategoryWeights = 'category_weights'; // Default values static const int _defaultDaysToExclude = 7; static const int _defaultMaxDistanceRainy = 500; static const int _defaultMaxDistanceNormal = 1000; static const int _defaultNotificationDelayMinutes = 90; static const bool _defaultNotificationEnabled = true; static const bool _defaultDarkModeEnabled = false; static const bool _defaultFirstRun = true; Future get _box async => await Hive.openBox(_boxName); @override Future getUserSettings() async { final box = await _box; // 저장된 설정값들을 읽어옴 final revisitPreventionDays = box.get(_keyDaysToExclude, defaultValue: _defaultDaysToExclude); final notificationEnabled = box.get(_keyNotificationEnabled, defaultValue: _defaultNotificationEnabled); final notificationDelayMinutes = box.get(_keyNotificationDelayMinutes, defaultValue: _defaultNotificationDelayMinutes); // 카테고리 가중치 읽기 (Map으로 저장됨) final categoryWeightsData = box.get(_keyCategoryWeights); Map categoryWeights = {}; if (categoryWeightsData != null) { categoryWeights = Map.from(categoryWeightsData); } // 알림 시간은 분을 시간:분 형식으로 변환 final hours = notificationDelayMinutes ~/ 60; final minutes = notificationDelayMinutes % 60; final notificationTime = '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}'; return UserSettings( revisitPreventionDays: revisitPreventionDays, notificationEnabled: notificationEnabled, notificationTime: notificationTime, categoryWeights: categoryWeights, notificationDelayMinutes: notificationDelayMinutes, ); } @override Future updateUserSettings(UserSettings settings) async { final box = await _box; // 각 설정값 저장 await box.put(_keyDaysToExclude, settings.revisitPreventionDays); await box.put(_keyNotificationEnabled, settings.notificationEnabled); await box.put(_keyNotificationDelayMinutes, settings.notificationDelayMinutes); // 카테고리 가중치 저장 await box.put(_keyCategoryWeights, settings.categoryWeights); } @override Future getDaysToExclude() async { final box = await _box; return box.get(_keyDaysToExclude, defaultValue: _defaultDaysToExclude); } @override Future setDaysToExclude(int days) async { final box = await _box; await box.put(_keyDaysToExclude, days); } @override Future getMaxDistanceRainy() async { final box = await _box; return box.get(_keyMaxDistanceRainy, defaultValue: _defaultMaxDistanceRainy); } @override Future setMaxDistanceRainy(int meters) async { final box = await _box; await box.put(_keyMaxDistanceRainy, meters); } @override Future getMaxDistanceNormal() async { final box = await _box; return box.get(_keyMaxDistanceNormal, defaultValue: _defaultMaxDistanceNormal); } @override Future setMaxDistanceNormal(int meters) async { final box = await _box; await box.put(_keyMaxDistanceNormal, meters); } @override Future getNotificationDelayMinutes() async { final box = await _box; return box.get(_keyNotificationDelayMinutes, defaultValue: _defaultNotificationDelayMinutes); } @override Future setNotificationDelayMinutes(int minutes) async { final box = await _box; await box.put(_keyNotificationDelayMinutes, minutes); } @override Future isNotificationEnabled() async { final box = await _box; return box.get(_keyNotificationEnabled, defaultValue: _defaultNotificationEnabled); } @override Future setNotificationEnabled(bool enabled) async { final box = await _box; await box.put(_keyNotificationEnabled, enabled); } @override Future isDarkModeEnabled() async { final box = await _box; return box.get(_keyDarkModeEnabled, defaultValue: _defaultDarkModeEnabled); } @override Future setDarkModeEnabled(bool enabled) async { final box = await _box; await box.put(_keyDarkModeEnabled, enabled); } @override Future isFirstRun() async { final box = await _box; return box.get(_keyFirstRun, defaultValue: _defaultFirstRun); } @override Future setFirstRun(bool isFirst) async { final box = await _box; await box.put(_keyFirstRun, isFirst); } @override Future resetSettings() async { final box = await _box; await box.clear(); // 기본값으로 재설정 await box.put(_keyDaysToExclude, _defaultDaysToExclude); await box.put(_keyMaxDistanceRainy, _defaultMaxDistanceRainy); await box.put(_keyMaxDistanceNormal, _defaultMaxDistanceNormal); await box.put(_keyNotificationDelayMinutes, _defaultNotificationDelayMinutes); await box.put(_keyNotificationEnabled, _defaultNotificationEnabled); await box.put(_keyDarkModeEnabled, _defaultDarkModeEnabled); await box.put(_keyFirstRun, false); // 리셋 후에는 첫 실행이 아님 } @override Stream> watchSettings() async* { final box = await _box; // 초기 값 전송 yield await _getCurrentSettings(); // 변경사항 감시 yield* box.watch().asyncMap((_) async => await _getCurrentSettings()); } Future> _getCurrentSettings() async { return { _keyDaysToExclude: await getDaysToExclude(), _keyMaxDistanceRainy: await getMaxDistanceRainy(), _keyMaxDistanceNormal: await getMaxDistanceNormal(), _keyNotificationDelayMinutes: await getNotificationDelayMinutes(), _keyNotificationEnabled: await isNotificationEnabled(), _keyDarkModeEnabled: await isDarkModeEnabled(), _keyFirstRun: await isFirstRun(), }; } @override Stream watchUserSettings() async* { final box = await _box; // 초기 값 전송 yield await getUserSettings(); // 변경사항 감시 yield* box.watch().asyncMap((_) async => await getUserSettings()); } }