import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/server_config.dart'; import '../providers/providers.dart'; import '../services/websocket_service.dart'; import '../services/wol_service.dart'; import '../theme/app_theme.dart'; import '../widgets/status_dot.dart'; class SettingsScreen extends ConsumerStatefulWidget { const SettingsScreen({super.key}); @override ConsumerState createState() => _SettingsScreenState(); } class _SettingsScreenState extends ConsumerState { final _formKey = GlobalKey(); late final TextEditingController _localHostController; late final TextEditingController _remoteHostController; late final TextEditingController _portController; late final TextEditingController _macController; bool _isWaking = false; @override void initState() { super.initState(); final config = ref.read(serverConfigProvider); _localHostController = TextEditingController(text: config?.localHost ?? ''); _remoteHostController = TextEditingController(text: config?.host ?? ''); _portController = TextEditingController(text: '${config?.port ?? 8765}'); _macController = TextEditingController(text: config?.macAddress ?? ''); } @override void dispose() { _localHostController.dispose(); _remoteHostController.dispose(); _portController.dispose(); _macController.dispose(); super.dispose(); } Future _save() async { if (!_formKey.currentState!.validate()) return; final config = ServerConfig( host: _remoteHostController.text.trim(), port: int.tryParse(_portController.text.trim()) ?? 8765, localHost: _localHostController.text.trim().isEmpty ? null : _localHostController.text.trim(), macAddress: _macController.text.trim().isEmpty ? null : _macController.text.trim(), ); await ref.read(serverConfigProvider.notifier).save(config); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Server configuration saved'), duration: Duration(seconds: 2), ), ); } } Future _wakeMac() async { final mac = _macController.text.trim(); if (mac.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('No MAC address configured')), ); return; } setState(() => _isWaking = true); try { await WolService.wake(mac); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Wake-on-LAN packet sent')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('WoL failed: $e')), ); } } finally { if (mounted) setState(() => _isWaking = false); } } @override Widget build(BuildContext context) { final wsStatus = ref.watch(wsStatusProvider); return Scaffold( appBar: AppBar( title: const Text('Settings'), ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Connection status card Card( child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ StatusDot(status: wsStatus), const SizedBox(width: 12), Text( _statusText(wsStatus), style: Theme.of(context).textTheme.bodyLarge, ), ], ), ), ), const SizedBox(height: 24), // Local address Text('Local Address', style: Theme.of(context).textTheme.bodyMedium), const SizedBox(height: 4), TextFormField( controller: _localHostController, decoration: const InputDecoration( hintText: '192.168.1.100', ), keyboardType: TextInputType.url, ), const SizedBox(height: 16), // Remote address Text('Remote Address', style: Theme.of(context).textTheme.bodyMedium), const SizedBox(height: 4), TextFormField( controller: _remoteHostController, decoration: const InputDecoration( hintText: 'your-server.example.com', ), keyboardType: TextInputType.url, validator: (v) => (v == null || v.trim().isEmpty) ? 'Required' : null, ), const SizedBox(height: 16), // Port Text('Port', style: Theme.of(context).textTheme.bodyMedium), const SizedBox(height: 4), TextFormField( controller: _portController, decoration: const InputDecoration( hintText: '8765', ), keyboardType: TextInputType.number, ), const SizedBox(height: 16), // MAC address Text('MAC Address (for Wake-on-LAN)', style: Theme.of(context).textTheme.bodyMedium), const SizedBox(height: 4), TextFormField( controller: _macController, decoration: const InputDecoration( hintText: 'AA:BB:CC:DD:EE:FF', ), ), const SizedBox(height: 24), // Save button ElevatedButton( onPressed: _save, style: ElevatedButton.styleFrom( backgroundColor: AppColors.accent, foregroundColor: Colors.white, ), child: const Text('Save Configuration'), ), const SizedBox(height: 12), // Wake Mac button OutlinedButton.icon( onPressed: _isWaking ? null : _wakeMac, icon: _isWaking ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.power_settings_new), label: const Text('Wake Mac'), ), const SizedBox(height: 12), ], ), ), ), ); } String _statusText(ConnectionStatus status) { switch (status) { case ConnectionStatus.connected: return 'Connected'; case ConnectionStatus.connecting: return 'Connecting...'; case ConnectionStatus.reconnecting: return 'Reconnecting...'; case ConnectionStatus.disconnected: return 'Disconnected'; } } }