import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:kifi_app/core/widgets/smart_search_dropdown.dart'; import 'package:kifi_app/features/inventory/providers/products_provider.dart'; import 'package:kifi_app/features/inventory/domain/product_bom.dart'; import 'package:kifi_app/features/inventory/domain/product.dart'; class BomTab extends ConsumerStatefulWidget { final int productId; const BomTab({super.key, required this.productId}); @override ConsumerState createState() => _BomTabState(); } class _BomTabState extends ConsumerState { bool _isLoading = true; List _bomItems = []; @override void initState() { super.initState(); _loadBom(); } Future _loadBom() async { setState(() => _isLoading = true); try { final items = await ref.read(productsProvider.notifier).fetchProductBom(widget.productId); setState(() { _bomItems = items; }); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error loading BOM: $e'))); } } finally { if (mounted) setState(() => _isLoading = false); } } void _showAddComponentSheet() { final productsState = ref.read(productsProvider); final availableProducts = (productsState.value ?? []).where((p) => p.id != widget.productId).toList(); Product? selectedProduct; final qtyCtrl = TextEditingController(text: '1'); showModalBottomSheet( context: context, isScrollControlled: true, builder: (context) => StatefulBuilder( builder: (context, setSheetState) { return Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, left: 24, right: 24, top: 24, ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text("Add Component", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), const SizedBox(height: 16), SmartSearchDropdown( hintText: 'Select Product', value: selectedProduct, items: availableProducts, itemAsString: (p) => p.name, onChanged: (val) { setSheetState(() { selectedProduct = val; }); }, ), const SizedBox(height: 16), TextField( controller: qtyCtrl, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration( labelText: 'Quantity Required', border: OutlineInputBorder(), ), ), const SizedBox(height: 24), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () async { if (selectedProduct == null) return; final qty = double.tryParse(qtyCtrl.text) ?? 1.0; final bomItem = ProductBom( parentProductId: widget.productId, componentProductId: selectedProduct!.id!, quantity: qty, ); try { await ref.read(productsProvider.notifier).addBomItem(widget.productId, bomItem); if (context.mounted) Navigator.pop(context); _loadBom(); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error adding component: $e'))); } } }, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), backgroundColor: Colors.blue, foregroundColor: Colors.white, ), child: const Text('Add to BOM'), ), ), const SizedBox(height: 24), ], ), ); } ), ); } @override Widget build(BuildContext context) { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } final productsState = ref.watch(productsProvider); final allProducts = productsState.value ?? []; return Stack( children: [ if (_bomItems.isEmpty) const Center(child: Text("No components added yet.", style: TextStyle(color: Colors.grey))) else ListView.builder( padding: const EdgeInsets.all(16).copyWith(bottom: 80), itemCount: _bomItems.length, itemBuilder: (context, index) { final item = _bomItems[index]; final component = allProducts.firstWhere( (p) => p.id == item.componentProductId, orElse: () => Product(name: 'Unknown Product', priceCalcRule: 'MANUAL'), ); return Card( margin: const EdgeInsets.only(bottom: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: ListTile( title: Text(component.name, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text('Quantity Required: ${item.quantity}'), trailing: IconButton( icon: const Icon(Icons.delete, color: Colors.red), onPressed: () async { try { await ref.read(productsProvider.notifier).deleteBomItem(item.id!); _loadBom(); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error deleting component: $e'))); } } }, ), ), ); }, ), Positioned( bottom: 90, right: 16, child: FloatingActionButton.extended( heroTag: 'add_bom_btn', onPressed: _showAddComponentSheet, backgroundColor: Colors.indigo, icon: const Icon(Icons.add), label: const Text("Add Component"), ), ), ], ); } }