import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../theme/app_theme.dart'; class ConfigCard extends StatefulWidget { final Map config; final Future Function(Map) onConfigUpdate; const ConfigCard({ super.key, required this.config, required this.onConfigUpdate, }); @override State createState() => _ConfigCardState(); } class _ConfigCardState extends State { final _formKey = GlobalKey(); late TextEditingController _codingXpController; late TextEditingController _researchXpController; late TextEditingController _meetingXpController; late TextEditingController _focusBonusController; bool _isLoading = false; @override void initState() { super.initState(); _initializeControllers(); } void _initializeControllers() { final xpRewards = widget.config['xp_rewards'] as Map? ?? {}; final baseMultipliers = xpRewards['base_multipliers'] as Map? ?? {}; final focusBonuses = xpRewards['focus_session_bonuses'] as Map? ?? {}; _codingXpController = TextEditingController( text: (baseMultipliers['coding'] ?? 10).toString(), ); _researchXpController = TextEditingController( text: (baseMultipliers['research'] ?? 8).toString(), ); _meetingXpController = TextEditingController( text: (baseMultipliers['meeting'] ?? 3).toString(), ); _focusBonusController = TextEditingController( text: (focusBonuses['base_xp_per_minute'] ?? 5).toString(), ); } @override void didUpdateWidget(ConfigCard oldWidget) { super.didUpdateWidget(oldWidget); if (widget.config != oldWidget.config) { _initializeControllers(); } } @override void dispose() { _codingXpController.dispose(); _researchXpController.dispose(); _meetingXpController.dispose(); _focusBonusController.dispose(); super.dispose(); } Future _saveConfig() async { if (!_formKey.currentState!.validate()) return; setState(() { _isLoading = true; }); try { final updates = { 'xp_rewards.base_multipliers.coding': int.parse(_codingXpController.text), 'xp_rewards.base_multipliers.research': int.parse(_researchXpController.text), 'xp_rewards.base_multipliers.meeting': int.parse(_meetingXpController.text), 'xp_rewards.focus_session_bonuses.base_xp_per_minute': int.parse(_focusBonusController.text), }; await widget.onConfigUpdate(updates); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Configuration saved successfully!'), backgroundColor: AppTheme.successColor, ), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to save configuration: $e'), backgroundColor: AppTheme.errorColor, ), ); } } finally { if (mounted) { setState(() { _isLoading = false; }); } } } @override Widget build(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(20), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.settings, color: AppTheme.primaryColor), const SizedBox(width: 8), Text( 'XP Configuration', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 16), _ConfigField( label: 'Coding XP Multiplier', controller: _codingXpController, icon: Icons.code, ), const SizedBox(height: 12), _ConfigField( label: 'Research XP Multiplier', controller: _researchXpController, icon: Icons.search, ), const SizedBox(height: 12), _ConfigField( label: 'Meeting XP Multiplier', controller: _meetingXpController, icon: Icons.groups, ), const SizedBox(height: 12), _ConfigField( label: 'Focus Bonus (XP/min)', controller: _focusBonusController, icon: Icons.psychology, ), const SizedBox(height: 20), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _isLoading ? null : _saveConfig, child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : const Text('Save Configuration'), ), ), ], ), ), ), ); } } class _ConfigField extends StatelessWidget { final String label; final TextEditingController controller; final IconData icon; const _ConfigField({ required this.label, required this.controller, required this.icon, }); @override Widget build(BuildContext context) { return TextFormField( controller: controller, decoration: InputDecoration( labelText: label, prefixIcon: Icon(icon, color: AppTheme.primaryColor), border: const OutlineInputBorder(), ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, ], validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a value'; } final intValue = int.tryParse(value); if (intValue == null || intValue < 0) { return 'Please enter a valid positive number'; } return null; }, ); } }