import 'package:flutter/material.dart'; import '../../core/service_locator.dart'; import '../../core/logger.dart'; import '../../data/recipes/models/bookmark_category_model.dart'; /// Dialog for selecting or creating a bookmark category. class BookmarkDialog extends StatefulWidget { final String recipeId; final List currentCategories; const BookmarkDialog({ super.key, required this.recipeId, required this.currentCategories, }); @override State createState() => _BookmarkDialogState(); } class _BookmarkDialogState extends State { final TextEditingController _categoryNameController = TextEditingController(); List _allCategories = []; bool _isLoading = false; bool _isCreating = false; @override void initState() { super.initState(); _loadCategories(); } @override void dispose() { _categoryNameController.dispose(); super.dispose(); } Future _loadCategories() async { setState(() => _isLoading = true); try { final recipeService = ServiceLocator.instance.recipeService; if (recipeService != null) { final categories = await recipeService.getAllBookmarkCategories(); setState(() { _allCategories = categories; _isLoading = false; }); } } catch (e) { Logger.error('Failed to load bookmark categories', e); setState(() => _isLoading = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to load bookmarks: $e')), ); } } } Future _createCategory() async { final name = _categoryNameController.text.trim(); if (name.isEmpty) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Bookmark name cannot be empty')), ); } return; } setState(() => _isCreating = true); try { final recipeService = ServiceLocator.instance.recipeService; if (recipeService != null) { final category = await recipeService.createBookmarkCategory(name: name); await recipeService.addRecipeToCategory( recipeId: widget.recipeId, categoryId: category.id, ); if (mounted) { Navigator.of(context).pop(category); } } } catch (e) { Logger.error('Failed to create bookmark category', e); setState(() => _isCreating = false); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to create bookmark: $e')), ); } } } Future _selectCategory(BookmarkCategory category) async { try { final recipeService = ServiceLocator.instance.recipeService; if (recipeService != null) { final isInCategory = widget.currentCategories .any((c) => c.id == category.id); if (isInCategory) { // Remove from category await recipeService.removeRecipeFromCategory( recipeId: widget.recipeId, categoryId: category.id, ); } else { // Add to category await recipeService.addRecipeToCategory( recipeId: widget.recipeId, categoryId: category.id, ); } if (mounted) { Navigator.of(context).pop(category); } } } catch (e) { Logger.error('Failed to update bookmark', e); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to update bookmark: $e')), ); } } } Color _parseColor(String hexColor) { try { return Color(int.parse(hexColor.replaceAll('#', '0xFF'))); } catch (e) { return Colors.blue; } } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('Bookmark Recipe'), content: SizedBox( width: double.maxFinite, child: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Existing categories if (_allCategories.isNotEmpty) ...[ const Text( 'Add to bookmark:', style: TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), ConstrainedBox( constraints: const BoxConstraints(maxHeight: 200), child: ListView.builder( shrinkWrap: true, itemCount: _allCategories.length, itemBuilder: (context, index) { final category = _allCategories[index]; final isSelected = widget.currentCategories .any((c) => c.id == category.id); return CheckboxListTile( title: Text(category.name), value: isSelected, onChanged: (_) => _selectCategory(category), secondary: category.color != null ? Container( width: 24, height: 24, decoration: BoxDecoration( color: _parseColor(category.color!), shape: BoxShape.circle, ), ) : const Icon(Icons.bookmark), ); }, ), ), const SizedBox(height: 16), ], // Create new category const Text( 'Or create new bookmark:', style: TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), TextField( controller: _categoryNameController, decoration: const InputDecoration( hintText: 'Bookmark name', border: OutlineInputBorder(), ), enabled: !_isCreating, onSubmitted: (_) => _createCategory(), ), ], ), ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel'), ), if (!_isLoading) TextButton( onPressed: _isCreating ? null : _createCategory, child: _isCreating ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Create & Add'), ), ], ); } }