import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../providers/user_provider.dart'; import '../../services/health_service.dart'; class PrivacySettingsScreen extends ConsumerStatefulWidget { const PrivacySettingsScreen({super.key}); @override ConsumerState createState() => _PrivacySettingsScreenState(); } class _PrivacySettingsScreenState extends ConsumerState { bool _hasPermissions = false; final HealthService _healthService = HealthService(); @override void initState() { super.initState(); _checkPermissions(); } Future _checkPermissions() async { final hasPermissions = await _healthService .hasPermissions(_healthService.menstruationDataTypes); setState(() { _hasPermissions = hasPermissions; }); } Future _requestPermissions() async { final authorized = await _healthService .requestAuthorization(_healthService.menstruationDataTypes); if (authorized) { _hasPermissions = true; if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Health app access granted!')), ); } } else { _hasPermissions = false; if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Health app access denied.')), ); } } setState(() {}); // Rebuild to update UI } Future _syncPeriodDays(bool sync) async { if (sync) { if (!_hasPermissions) { final authorized = await _healthService .requestAuthorization(_healthService.menstruationDataTypes); if (mounted) { if (!authorized) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Cannot sync without health app permissions.')), ); return; } } else { return; } _hasPermissions = true; } if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Syncing period data...')), ); } final userProfile = ref.read(userProfileProvider); final cycleEntries = ref.read(cycleEntriesProvider); if (userProfile != null) { final success = await _healthService.writeMenstruationData(cycleEntries); if (mounted) { if (success) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Period data synced successfully!')), ); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Failed to sync period data.')), ); } } } } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Period data sync disabled.')), ); } } setState(() {}); } Future _setPin() async { final pin = await _showPinDialog(context, title: 'Set New PIN'); if (pin != null && pin.length >= 4) { final user = ref.read(userProfileProvider); if (user != null) { await ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(privacyPin: pin)); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('PIN Set Successfully'))); } } } } Future _removePin() async { final user = ref.read(userProfileProvider); if (user == null) return; final currentPin = await _showPinDialog(context, title: 'Enter Current PIN'); if (currentPin == user.privacyPin) { await ref.read(userProfileProvider.notifier).updateProfile(user.copyWith( privacyPin: '', isBioProtected: false, isHistoryProtected: false)); if (mounted) { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('PIN Removed'))); } } else { if (mounted) { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('Incorrect PIN'))); } } } Future _showPinDialog(BuildContext context, {required String title}) { final controller = TextEditingController(); return showDialog( context: context, builder: (context) => AlertDialog( title: Text(title), content: TextField( controller: controller, keyboardType: TextInputType.number, obscureText: true, maxLength: 4, decoration: const InputDecoration(hintText: 'Enter 4-digit PIN'), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel')), ElevatedButton( onPressed: () => Navigator.pop(context, controller.text), child: const Text('OK'), ), ], ), ); } @override Widget build(BuildContext context) { final user = ref.watch(userProfileProvider); if (user == null) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } final hasPin = user.privacyPin != null && user.privacyPin!.isNotEmpty; bool syncPeriodToHealth = _hasPermissions; return Scaffold( appBar: AppBar( title: const Text('Privacy Settings'), ), body: ListView( padding: const EdgeInsets.all(16.0), children: [ Text('App Security', style: Theme.of(context) .textTheme .titleMedium ?.copyWith(color: Theme.of(context).colorScheme.primary)), const SizedBox(height: 8), ListTile( title: const Text('Privacy PIN'), subtitle: Text( hasPin ? 'PIN is set' : 'Protect sensitive data with a PIN'), trailing: hasPin ? const Icon(Icons.lock, color: Colors.green) : const Icon(Icons.lock_open), onTap: () { if (hasPin) { showModalBottomSheet( context: context, builder: (context) => Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: const Icon(Icons.edit), title: const Text('Change PIN'), onTap: () { Navigator.pop(context); _setPin(); }, ), ListTile( leading: const Icon(Icons.delete, color: Colors.red), title: const Text('Remove PIN'), onTap: () { Navigator.pop(context); _removePin(); }, ), ], )); } else { _setPin(); } }, ), if (hasPin) ...[ SwitchListTile( title: const Text('Use Biometrics'), subtitle: const Text('Unlock with FaceID / Fingerprint'), value: user.isBioProtected, onChanged: (val) { ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(isBioProtected: val)); }, ), const Divider(), const Text('Protected Features', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.grey)), SwitchListTile( title: const Text('Daily Logs'), value: user.isLogProtected, onChanged: (val) { ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(isLogProtected: val)); }, ), SwitchListTile( title: const Text('Calendar'), value: user.isCalendarProtected, onChanged: (val) { ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(isCalendarProtected: val)); }, ), SwitchListTile( title: const Text('Supplies / Pad Tracker'), value: user.isSuppliesProtected, onChanged: (val) { ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(isSuppliesProtected: val)); }, ), SwitchListTile( title: const Text('Cycle History'), value: user.isHistoryProtected, onChanged: (val) { ref .read(userProfileProvider.notifier) .updateProfile(user.copyWith(isHistoryProtected: val)); }, ), ], const Divider(height: 32), Text('Health App Integration', style: Theme.of(context) .textTheme .titleMedium ?.copyWith(color: Theme.of(context).colorScheme.primary)), const SizedBox(height: 8), ListTile( title: const Text('Health Source'), subtitle: _hasPermissions ? const Text('Connected to Health App.') : const Text('Not connected. Tap to grant access.'), trailing: _hasPermissions ? const Icon(Icons.check_circle, color: Colors.green) : const Icon(Icons.warning, color: Colors.orange), onTap: _requestPermissions, ), SwitchListTile( title: const Text('Sync Period Days'), subtitle: const Text('Automatically sync period dates.'), value: syncPeriodToHealth, onChanged: _hasPermissions ? (value) async { if (value) { await _syncPeriodDays(true); } else { await _syncPeriodDays(false); } setState(() { syncPeriodToHealth = value; }); } : null, ), ], ), ); } }