import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../domain/entities/create_todo_params.dart'; import '../../domain/entities/update_todo_params.dart'; import '../providers/todo_providers.dart'; class TodoDetailScreen extends ConsumerStatefulWidget { final String? todoId; const TodoDetailScreen({super.key, this.todoId}); @override ConsumerState createState() => _TodoDetailScreenState(); } class _TodoDetailScreenState extends ConsumerState { final _formKey = GlobalKey(); late final TextEditingController _titleController; late final TextEditingController _descriptionController; String _priority = 'medium'; DateTime? _dueDate; bool _isLoading = false; bool get isEditing => widget.todoId != null; @override void initState() { super.initState(); _titleController = TextEditingController(); _descriptionController = TextEditingController(); if (isEditing) { _loadTodo(); } } Future _loadTodo() async { final todoAsync = ref.read(todoDetailProvider(widget.todoId!)); todoAsync.whenData((todo) { _titleController.text = todo.title; _descriptionController.text = todo.description ?? ''; _priority = todo.priority; _dueDate = todo.dueDate; }); } @override void dispose() { _titleController.dispose(); _descriptionController.dispose(); super.dispose(); } Future _save() async { if (!_formKey.currentState!.validate()) return; setState(() => _isLoading = true); try { if (isEditing) { await ref.read(todoListProvider.notifier).updateTodo( widget.todoId!, UpdateTodoParams( title: _titleController.text, description: _descriptionController.text.isEmpty ? null : _descriptionController.text, priority: _priority, dueDate: _dueDate, ), ); } else { await ref.read(todoListProvider.notifier).createTodo( CreateTodoParams( title: _titleController.text, description: _descriptionController.text.isEmpty ? null : _descriptionController.text, priority: _priority, dueDate: _dueDate, ), ); } if (mounted) context.pop(); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to save: $e')), ); } } finally { if (mounted) setState(() => _isLoading = false); } } Future _pickDueDate() async { final date = await showDatePicker( context: context, initialDate: _dueDate ?? DateTime.now().add(const Duration(days: 1)), firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365)), ); if (date != null) { setState(() => _dueDate = date); } } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: Text(isEditing ? 'Edit Todo' : 'New Todo'), ), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16), children: [ TextFormField( controller: _titleController, decoration: const InputDecoration( labelText: 'Title', border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Title is required'; } return null; }, autofocus: !isEditing, ), const SizedBox(height: 16), TextFormField( controller: _descriptionController, decoration: const InputDecoration( labelText: 'Description (optional)', border: OutlineInputBorder(), ), maxLines: 3, ), const SizedBox(height: 16), DropdownButtonFormField( initialValue: _priority, decoration: const InputDecoration( labelText: 'Priority', border: OutlineInputBorder(), ), items: const [ DropdownMenuItem(value: 'low', child: Text('Low')), DropdownMenuItem(value: 'medium', child: Text('Medium')), DropdownMenuItem(value: 'high', child: Text('High')), ], onChanged: (value) { if (value != null) setState(() => _priority = value); }, ), const SizedBox(height: 16), InkWell( onTap: _pickDueDate, child: InputDecorator( decoration: const InputDecoration( labelText: 'Due Date (optional)', border: OutlineInputBorder(), suffixIcon: Icon(Icons.calendar_today), ), child: Text( _dueDate != null ? '${_dueDate!.year}-${_dueDate!.month.toString().padLeft(2, '0')}-${_dueDate!.day.toString().padLeft(2, '0')}' : 'No date selected', style: theme.textTheme.bodyLarge?.copyWith( color: _dueDate != null ? null : theme.colorScheme.onSurfaceVariant, ), ), ), ), if (_dueDate != null) TextButton( onPressed: () => setState(() => _dueDate = null), child: const Text('Clear date'), ), const SizedBox(height: 24), FilledButton( onPressed: _isLoading ? null : _save, child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : Text(isEditing ? 'Save Changes' : 'Create Todo'), ), ], ), ), ); } }