import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:provider/provider.dart'; import '../providers/notification_provider.dart'; import 'dart:io'; import '../services/notification_service.dart'; import 'package:url_launcher/url_launcher.dart'; import '../providers/theme_provider.dart'; import '../theme/adaptive_theme.dart'; import '../widgets/glassmorphism_card.dart'; import '../theme/app_colors.dart'; import '../widgets/native_ad_widget.dart'; class SettingsScreen extends StatelessWidget { const SettingsScreen({super.key}); // 알림 시점 라디오 버튼 생성 헬퍼 메서드 Widget _buildReminderDayRadio(BuildContext context, NotificationProvider provider, int value, String label) { final isSelected = provider.reminderDays == value; return Expanded( child: InkWell( onTap: () => provider.setReminderDays(value), child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: isSelected ? AppColors.primaryColor.withValues(alpha: 0.2) : Colors.transparent, borderRadius: BorderRadius.circular(8), border: Border.all( color: isSelected ? AppColors.primaryColor : AppColors.textSecondary.withValues(alpha: 0.5), width: isSelected ? 2 : 1, ), ), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, color: isSelected ? AppColors.primaryColor : AppColors.textSecondary, size: 24, ), const SizedBox(height: 6), Text( label, style: TextStyle( fontSize: 14, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, color: isSelected ? AppColors.primaryColor : AppColors.textPrimary, ), ), ], ), ), ), ); } @override Widget build(BuildContext context) { return Column( children: [ Expanded( child: ListView( padding: EdgeInsets.zero, children: [ // toolbar 높이 추가 SizedBox( height: kToolbarHeight + MediaQuery.of(context).padding.top, ), // 광고 위젯 추가 const NativeAdWidget(key: ValueKey('settings_ad')), const SizedBox(height: 16), // 앱 잠금 설정 UI 숨김 // Card( // margin: const EdgeInsets.all(16), // child: Consumer( // builder: (context, provider, child) { // return SwitchListTile( // title: const Text('앱 잠금'), // subtitle: const Text('생체 인증으로 앱 잠금'), // value: provider.isEnabled, // onChanged: (value) async { // if (value) { // final isAuthenticated = await provider.authenticate(); // if (isAuthenticated) { // provider.enable(); // } // } else { // provider.disable(); // } // }, // ); // }, // ), // ), // 알림 설정 GlassmorphismCard( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.all(8), child: Consumer( builder: (context, provider, child) { return Column( children: [ ListTile( title: const Text( '알림 권한', style: TextStyle(color: AppColors.textPrimary), ), subtitle: const Text( '알림을 받으려면 권한이 필요합니다', style: TextStyle(color: AppColors.textSecondary), ), trailing: ElevatedButton( onPressed: () async { final granted = await NotificationService.requestPermission(); if (granted) { await provider.setEnabled(true); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '알림 권한이 거부되었습니다', style: TextStyle( color: AppColors.pureWhite, ), ), backgroundColor: AppColors.dangerColor, ), ); } }, child: const Text('권한 요청'), ), ), const Divider(), // 결제 예정 알림 기본 스위치 SwitchListTile( title: const Text( '결제 예정 알림', style: TextStyle(color: AppColors.textPrimary), ), subtitle: const Text( '결제 예정일 알림 받기', style: TextStyle(color: AppColors.textSecondary), ), value: provider.isPaymentEnabled, onChanged: (value) { provider.setPaymentEnabled(value); }, ), // 알림 세부 설정 (알림 활성화된 경우에만 표시) AnimatedSize( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, child: provider.isPaymentEnabled ? Padding( padding: const EdgeInsets.only( left: 16.0, right: 16.0, bottom: 8.0), child: Card( elevation: 0, color: Theme.of(context) .colorScheme .surfaceVariant .withValues(alpha: 0.3), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: const EdgeInsets.all(12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 알림 시점 선택 (1일전, 2일전, 3일전) const Text('알림 시점', style: TextStyle( fontWeight: FontWeight.bold)), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric( vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildReminderDayRadio(context, provider, 1, '1일 전'), _buildReminderDayRadio(context, provider, 2, '2일 전'), _buildReminderDayRadio(context, provider, 3, '3일 전'), ], ), ), const SizedBox(height: 16), // 알림 시간 선택 const Text('알림 시간', style: TextStyle( fontWeight: FontWeight.bold)), const SizedBox(height: 12), InkWell( onTap: () async { final TimeOfDay? picked = await showTimePicker( context: context, initialTime: TimeOfDay( hour: provider.reminderHour, minute: provider .reminderMinute), ); if (picked != null) { provider.setReminderTime( picked.hour, picked.minute); } }, child: Container( padding: const EdgeInsets.symmetric( vertical: 12, horizontal: 16), decoration: BoxDecoration( border: Border.all( color: Theme.of(context) .colorScheme .outline .withValues(alpha: 0.5), ), borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Expanded( child: Row( children: [ Icon( Icons.access_time, color: Theme.of(context) .colorScheme .primary, size: 22, ), const SizedBox( width: 12), Text( '${provider.reminderHour.toString().padLeft(2, '0')}:${provider.reminderMinute.toString().padLeft(2, '0')}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Theme.of( context) .colorScheme .onSurface, ), ), ], ), ), Icon( Icons.arrow_forward_ios, size: 16, color: Theme.of(context) .colorScheme .outline, ), ], ), ), ), // 반복 알림 스위치 (2일전, 3일전 선택 시에만 활성화) if (provider.reminderDays >= 2) Padding( padding: const EdgeInsets.only( top: 16.0), child: Container( padding: const EdgeInsets.symmetric( vertical: 4, horizontal: 4), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .surfaceVariant .withValues(alpha: 0.3), borderRadius: BorderRadius.circular(8), ), child: SwitchListTile( contentPadding: const EdgeInsets .symmetric( horizontal: 12), title: const Text('1일마다 반복 알림'), subtitle: Text( provider.isDailyReminderEnabled ? '결제일까지 매일 알림을 받습니다' : '결제 ${provider.reminderDays}일 전에 알림을 받습니다', style: TextStyle( color: AppColors .textLight), ), value: provider .isDailyReminderEnabled, activeColor: Theme.of(context) .colorScheme .primary, onChanged: (value) { provider .setDailyReminderEnabled( value); }, ), ), ), ], ), ), ), ) : const SizedBox.shrink(), ), // 미사용 서비스 알림 기능 비활성화 // const Divider(), // SwitchListTile( // title: const Text('미사용 서비스 알림'), // subtitle: const Text('2개월 이상 미사용 시 알림'), // value: provider.isUnusedServiceNotificationEnabled, // onChanged: (value) { // provider.setUnusedServiceNotificationEnabled(value); // }, // ), ], ); }, ), ), // 앱 정보 GlassmorphismCard( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.all(8), child: ListTile( title: const Text( '앱 정보', style: TextStyle(color: AppColors.textPrimary), ), subtitle: const Text( '버전 1.0.0', style: TextStyle(color: AppColors.textSecondary), ), leading: const Icon( Icons.info, color: AppColors.textSecondary, ), onTap: () async { // 웹 환경에서는 기본 다이얼로그 표시 if (kIsWeb) { showAboutDialog( context: context, applicationName: 'Digital Rent Manager', applicationVersion: '1.0.0', applicationIcon: const FlutterLogo(size: 50), children: [ const Text('디지털 월세 관리 앱'), const SizedBox(height: 8), const Text('개발자: Julian Sul'), ], ); return; } // 앱 스토어 링크 String storeUrl = ''; // 플랫폼에 따라 스토어 링크 설정 if (Platform.isAndroid) { // Android - Google Play 스토어 링크 storeUrl = 'https://play.google.com/store/apps/details?id=com.submanager.app'; } else if (Platform.isIOS) { // iOS - App Store 링크 storeUrl = 'https://apps.apple.com/app/submanager/id123456789'; } if (storeUrl.isNotEmpty) { try { final Uri url = Uri.parse(storeUrl); await launchUrl(url, mode: LaunchMode.externalApplication); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '스토어를 열 수 없습니다', style: TextStyle( color: AppColors.pureWhite, ), ), backgroundColor: AppColors.dangerColor, ), ); } } } else { // 스토어 링크를 열 수 없는 경우 기존 정보 다이얼로그 표시 showAboutDialog( context: context, applicationName: 'SubManager', applicationVersion: '1.0.0', applicationIcon: const FlutterLogo(size: 50), children: [ const Text('구독 관리 앱'), const SizedBox(height: 8), const Text('개발자: SubManager Team'), ], ); } }, ), ), // FloatingNavigationBar를 위한 충분한 하단 여백 SizedBox( height: 120 + MediaQuery.of(context).padding.bottom, ), ], ), ), ], ); } String _getThemeModeText(AppThemeMode mode) { switch (mode) { case AppThemeMode.light: return '라이트'; case AppThemeMode.dark: return '다크'; case AppThemeMode.oled: return 'OLED 블랙'; case AppThemeMode.system: return '시스템 설정'; } } IconData _getThemeModeIcon(AppThemeMode mode) { switch (mode) { case AppThemeMode.light: return Icons.light_mode; case AppThemeMode.dark: return Icons.dark_mode; case AppThemeMode.oled: return Icons.phonelink_lock; case AppThemeMode.system: return Icons.settings_brightness; } } }