import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:household_keeper/core/providers/database_provider.dart'; import 'package:household_keeper/features/rooms/domain/room_icons.dart'; import 'package:household_keeper/features/rooms/presentation/icon_picker_sheet.dart'; import 'package:household_keeper/features/rooms/presentation/room_providers.dart'; import 'package:household_keeper/features/tasks/domain/frequency.dart'; import 'package:household_keeper/features/tasks/presentation/task_providers.dart'; import 'package:household_keeper/features/templates/data/task_templates.dart'; import 'package:household_keeper/features/templates/presentation/template_picker_sheet.dart'; import 'package:household_keeper/l10n/app_localizations.dart'; /// Full-screen form for creating and editing rooms. /// /// Pass [roomId] to edit an existing room, or leave null to create a new one. class RoomFormScreen extends ConsumerStatefulWidget { const RoomFormScreen({super.key, this.roomId}); final int? roomId; bool get isEditing => roomId != null; @override ConsumerState createState() => _RoomFormScreenState(); } class _RoomFormScreenState extends ConsumerState { final _formKey = GlobalKey(); final _nameController = TextEditingController(); String _selectedIconName = curatedRoomIcons.first.name; bool _isLoading = false; bool _isSaving = false; @override void initState() { super.initState(); if (widget.isEditing) { _loadRoom(); } } Future _loadRoom() async { setState(() => _isLoading = true); try { final db = ref.read(appDatabaseProvider); final room = await db.roomsDao.getRoomById(widget.roomId!); _nameController.text = room.name; setState(() { _selectedIconName = room.iconName; _isLoading = false; }); } catch (e) { if (mounted) { setState(() => _isLoading = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Fehler beim Laden: $e')), ); } } } Future _save() async { if (!_formKey.currentState!.validate()) return; setState(() => _isSaving = true); try { final roomActions = ref.read(roomActionsProvider.notifier); final name = _nameController.text.trim(); if (widget.isEditing) { // Edit mode: update and pop (no template prompt). final db = ref.read(appDatabaseProvider); final existing = await db.roomsDao.getRoomById(widget.roomId!); await roomActions.updateRoom(existing.copyWith( name: name, iconName: _selectedIconName, )); if (mounted) context.pop(); } else { // Create mode: save room, then offer template selection if type matches. final roomId = await roomActions.createRoom(name, _selectedIconName); if (!mounted) return; final roomType = detectRoomType(name); if (roomType != null) { final templates = roomTemplates[roomType]; if (templates != null && templates.isNotEmpty) { final selected = await showTemplatePickerSheet( context: context, roomType: roomType, templates: templates, ); if (selected != null && selected.isNotEmpty && mounted) { await _createTasksFromTemplates(roomId, selected); } } } if (mounted) context.go('/rooms/$roomId'); } } catch (e) { if (mounted) { setState(() => _isSaving = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Fehler beim Speichern: $e')), ); } } } /// Creates tasks from the selected templates in the newly created room. Future _createTasksFromTemplates( int roomId, List templates, ) async { final taskActions = ref.read(taskActionsProvider.notifier); final today = DateTime.now(); final todayDateOnly = DateTime(today.year, today.month, today.day); for (final template in templates) { await taskActions.createTask( roomId: roomId, name: template.name, description: template.description, intervalType: template.intervalType, intervalDays: template.intervalDays, anchorDay: _anchorDayForType(template.intervalType, todayDateOnly), effortLevel: template.effortLevel, nextDueDate: todayDateOnly, ); } } /// Returns the anchor day for calendar-anchored interval types. /// /// Monthly/quarterly/yearly intervals anchor to today's day-of-month. /// Day-count based intervals don't need an anchor. int? _anchorDayForType(IntervalType type, DateTime today) { switch (type) { case IntervalType.monthly: case IntervalType.everyNMonths: case IntervalType.quarterly: case IntervalType.yearly: return today.day; case IntervalType.daily: case IntervalType.everyNDays: case IntervalType.weekly: case IntervalType.biweekly: return null; } } @override void dispose() { _nameController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: Text( widget.isEditing ? l10n.roomFormEditTitle : l10n.roomFormCreateTitle, ), actions: [ IconButton( onPressed: _isSaving ? null : _save, icon: _isSaving ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.check), ), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16), children: [ // Room name field TextFormField( controller: _nameController, autofocus: !widget.isEditing, textCapitalization: TextCapitalization.sentences, decoration: InputDecoration( labelText: l10n.roomFormNameLabel, hintText: l10n.roomFormNameHint, border: const OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return l10n.roomFormNameRequired; } if (value.trim().length > 100) { return 'Maximal 100 Zeichen'; } return null; }, ), const SizedBox(height: 24), // Icon picker preview Text( l10n.roomFormIconLabel, style: theme.textTheme.titleSmall, ), const SizedBox(height: 8), InkWell( onTap: () async { final selected = await showIconPickerSheet( context: context, selectedIconName: _selectedIconName, ); if (selected != null) { setState(() => _selectedIconName = selected); } }, borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: theme.colorScheme.surfaceContainerLow, borderRadius: BorderRadius.circular(12), border: Border.all( color: theme.colorScheme.outline.withValues(alpha: 0.3), ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: theme.colorScheme.primaryContainer, borderRadius: BorderRadius.circular(8), ), child: Icon( mapIconName(_selectedIconName), size: 28, color: theme.colorScheme.onPrimaryContainer, ), ), const SizedBox(width: 16), Expanded( child: Text( l10n.roomFormIconLabel, style: theme.textTheme.bodyLarge, ), ), Icon( Icons.chevron_right, color: theme.colorScheme.onSurfaceVariant, ), ], ), ), ), ], ), ), ); } }