import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lunchpick/domain/repositories/settings_repository.dart'; import 'package:lunchpick/domain/entities/user_settings.dart'; import 'package:lunchpick/presentation/providers/di_providers.dart'; /// 재방문 금지 일수 Provider final daysToExcludeProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.getDaysToExclude(); }); /// 우천시 최대 거리 Provider final maxDistanceRainyProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.getMaxDistanceRainy(); }); /// 평상시 최대 거리 Provider final maxDistanceNormalProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.getMaxDistanceNormal(); }); /// 알림 지연 시간 Provider final notificationDelayMinutesProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.getNotificationDelayMinutes(); }); /// 알림 활성화 여부 Provider final notificationEnabledProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.isNotificationEnabled(); }); /// 스크린샷 모드 활성화 여부 Provider final screenshotModeEnabledProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.isScreenshotModeEnabled(); }); /// 다크모드 활성화 여부 Provider final darkModeEnabledProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.isDarkModeEnabled(); }); /// 첫 실행 여부 Provider final isFirstRunProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.isFirstRun(); }); /// 설정 스트림 Provider final settingsStreamProvider = StreamProvider>((ref) { final repository = ref.watch(settingsRepositoryProvider); return repository.watchSettings(); }); /// UserSettings Provider final userSettingsProvider = FutureProvider((ref) async { final repository = ref.watch(settingsRepositoryProvider); return repository.getUserSettings(); }); /// UserSettings 스트림 Provider final userSettingsStreamProvider = StreamProvider((ref) { final repository = ref.watch(settingsRepositoryProvider); return repository.watchUserSettings(); }); /// 설정 관리 StateNotifier class SettingsNotifier extends StateNotifier> { final SettingsRepository _repository; SettingsNotifier(this._repository) : super(const AsyncValue.data(null)); /// 재방문 금지 일수 설정 Future setDaysToExclude(int days) async { state = const AsyncValue.loading(); try { await _repository.setDaysToExclude(days); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 우천시 최대 거리 설정 Future setMaxDistanceRainy(int meters) async { state = const AsyncValue.loading(); try { await _repository.setMaxDistanceRainy(meters); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 평상시 최대 거리 설정 Future setMaxDistanceNormal(int meters) async { state = const AsyncValue.loading(); try { await _repository.setMaxDistanceNormal(meters); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 알림 지연 시간 설정 Future setNotificationDelayMinutes(int minutes) async { state = const AsyncValue.loading(); try { await _repository.setNotificationDelayMinutes(minutes); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 알림 활성화 설정 Future setNotificationEnabled(bool enabled) async { state = const AsyncValue.loading(); try { await _repository.setNotificationEnabled(enabled); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 스크린샷 모드 설정 Future setScreenshotModeEnabled(bool enabled) async { state = const AsyncValue.loading(); try { await _repository.setScreenshotModeEnabled(enabled); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 다크모드 설정 Future setDarkModeEnabled(bool enabled) async { state = const AsyncValue.loading(); try { await _repository.setDarkModeEnabled(enabled); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 첫 실행 상태 업데이트 Future setFirstRun(bool isFirst) async { state = const AsyncValue.loading(); try { await _repository.setFirstRun(isFirst); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// 설정 초기화 Future resetSettings() async { state = const AsyncValue.loading(); try { await _repository.resetSettings(); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } /// UserSettings 업데이트 Future updateUserSettings(UserSettings settings) async { state = const AsyncValue.loading(); try { await _repository.updateUserSettings(settings); state = const AsyncValue.data(null); } catch (e, stack) { state = AsyncValue.error(e, stack); } } } /// SettingsNotifier Provider final settingsNotifierProvider = StateNotifierProvider>((ref) { final repository = ref.watch(settingsRepositoryProvider); return SettingsNotifier(repository); }); /// 설정 프리셋 enum SettingsPreset { normal( name: '일반 모드', daysToExclude: 7, maxDistanceNormal: 1000, maxDistanceRainy: 500, ), economic( name: '절약 모드', daysToExclude: 3, maxDistanceNormal: 500, maxDistanceRainy: 300, ), convenience( name: '편의 모드', daysToExclude: 14, maxDistanceNormal: 2000, maxDistanceRainy: 1000, ); final String name; final int daysToExclude; final int maxDistanceNormal; final int maxDistanceRainy; const SettingsPreset({ required this.name, required this.daysToExclude, required this.maxDistanceNormal, required this.maxDistanceRainy, }); } /// 프리셋 적용 Provider final applyPresetProvider = Provider.family, SettingsPreset>(( ref, preset, ) async { final notifier = ref.read(settingsNotifierProvider.notifier); await notifier.setDaysToExclude(preset.daysToExclude); await notifier.setMaxDistanceNormal(preset.maxDistanceNormal); await notifier.setMaxDistanceRainy(preset.maxDistanceRainy); }); /// 현재 위치 Provider final currentLocationProvider = StateProvider<({double latitude, double longitude})?>((ref) => null); /// 선호 카테고리 Provider final preferredCategoriesProvider = StateProvider>((ref) => []); /// 제외 카테고리 Provider final excludedCategoriesProvider = StateProvider>((ref) => []); /// 언어 설정 Provider final languageProvider = StateProvider((ref) => 'ko'); /// 위치 권한 상태 Provider final locationPermissionProvider = StateProvider((ref) => false); /// 알림 권한 상태 Provider final notificationPermissionProvider = StateProvider((ref) => false); /// 모든 설정 상태를 통합한 Provider final allSettingsProvider = Provider>((ref) { final daysToExclude = ref.watch(daysToExcludeProvider).value ?? 7; final maxDistanceRainy = ref.watch(maxDistanceRainyProvider).value ?? 500; final maxDistanceNormal = ref.watch(maxDistanceNormalProvider).value ?? 1000; final notificationDelay = ref.watch(notificationDelayMinutesProvider).value ?? 90; final notificationEnabled = ref.watch(notificationEnabledProvider).value ?? false; final darkMode = ref.watch(darkModeEnabledProvider).value ?? false; final currentLocation = ref.watch(currentLocationProvider); final preferredCategories = ref.watch(preferredCategoriesProvider); final excludedCategories = ref.watch(excludedCategoriesProvider); final language = ref.watch(languageProvider); return { 'daysToExclude': daysToExclude, 'maxDistanceRainy': maxDistanceRainy, 'maxDistanceNormal': maxDistanceNormal, 'notificationDelayMinutes': notificationDelay, 'notificationEnabled': notificationEnabled, 'darkModeEnabled': darkMode, 'currentLocation': currentLocation, 'preferredCategories': preferredCategories, 'excludedCategories': excludedCategories, 'language': language, }; });