import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../core/theme/app_theme.dart'; import '../../core/widgets/step_indicator.dart'; import '../../data/models/models.dart'; import '../../data/services/order_service.dart'; class HandoffScreen extends StatefulWidget { final int orderId; const HandoffScreen({super.key, required this.orderId}); @override State createState() => _HandoffScreenState(); } class _HandoffScreenState extends State { final _service = MockOrderService(); Order? _order; bool _loading = true; bool _finalizing = false; @override void initState() { super.initState(); _load(); } Future _load() async { final order = await _service.getOrderDetail(widget.orderId); if (mounted) setState(() { _order = order; _loading = false; }); } Future _finalize() async { setState(() => _finalizing = true); await _service.finalizeOrder(widget.orderId); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Замовлення видано!'), backgroundColor: AppColors.success), ); context.go('/orders'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_order?.orderNumber ?? ''), leading: IconButton(icon: const Icon(Icons.arrow_back), onPressed: () => context.pop()), ), body: _loading ? const Center(child: CircularProgressIndicator()) : Column( children: [ const StepIndicator(currentStep: BatchStep.handoff), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Summary card _SummaryCard(order: _order!), const SizedBox(height: 16), // Slots summary if (_order!.assignedSlots.isNotEmpty) ...[ const Text('Ячейки зберігання', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), const SizedBox(height: 8), ..._buildSlotChips(_order!.assignedSlots), const SizedBox(height: 16), ], // Items summary const Text('Підсумок збору', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), const SizedBox(height: 8), _ItemsSummary(order: _order!), ], ), ), ), SafeArea( child: Padding( padding: const EdgeInsets.all(16), child: ElevatedButton( onPressed: _finalizing ? null : _finalize, style: ElevatedButton.styleFrom(backgroundColor: AppColors.success), child: _finalizing ? const SizedBox(height: 20, width: 20, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2)) : const Text('Зібрано та видано'), ), ), ), ], ), ); } List _buildSlotChips(List slots) { return [ Wrap( spacing: 8, runSpacing: 8, children: slots.map((slot) { final color = slot.type == StorageSlotType.freezer ? Colors.indigo : slot.type == StorageSlotType.fridge ? AppColors.info : AppColors.primary; return Chip( label: Text(slot.name, style: TextStyle(color: color, fontWeight: FontWeight.w600)), backgroundColor: color.withOpacity(0.1), side: BorderSide(color: color.withOpacity(0.4)), ); }).toList(), ), ]; } } class _SummaryCard extends StatelessWidget { final Order order; const _SummaryCard({required this.order}); @override Widget build(BuildContext context) { final notPicked = order.segments .expand((s) => s.items) .where((i) => i.status == ItemStatus.notFound) .toList(); final replaced = order.segments .expand((s) => s.items) .where((i) => i.status == ItemStatus.replaced) .toList(); return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.person, color: AppColors.primary), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(order.customer.name, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), Text(order.customer.phone, style: const TextStyle(color: AppColors.textSecondary)), ], ), ), ], ), const Divider(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _stat('Зібрано', '${order.pickedItems}/${order.totalItems}', AppColors.success), if (replaced.isNotEmpty) _stat('Замінено', '${replaced.length}', AppColors.warning), if (notPicked.isNotEmpty) _stat('Відсутні', '${notPicked.length}', AppColors.error), _stat('Сума', '${order.amount.toStringAsFixed(0)} грн', AppColors.primary), ], ), if (order.customer.comment != null) ...[ const Divider(height: 20), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.comment, size: 16, color: AppColors.warning), const SizedBox(width: 4), Expanded(child: Text(order.customer.comment!, style: const TextStyle(fontSize: 13, color: AppColors.warning))), ], ), ], ], ), ), ); } Widget _stat(String label, String value, Color color) => Column( children: [ Text(value, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: color)), Text(label, style: const TextStyle(fontSize: 11, color: AppColors.textSecondary)), ], ); } class _ItemsSummary extends StatelessWidget { final Order order; const _ItemsSummary({required this.order}); @override Widget build(BuildContext context) { final allItems = order.segments.expand((s) => s.items).toList(); return Column( children: allItems.map((item) { final icon = item.status == ItemStatus.picked ? Icons.check_circle : item.status == ItemStatus.replaced ? Icons.swap_horiz : Icons.cancel; final color = item.status == ItemStatus.picked ? AppColors.success : item.status == ItemStatus.replaced ? AppColors.warning : AppColors.error; return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( children: [ Icon(icon, size: 18, color: color), const SizedBox(width: 8), Expanded(child: Text(item.name, style: const TextStyle(fontSize: 14))), Text('${item.actualQty}/${item.planQty}', style: const TextStyle(fontSize: 13, color: AppColors.textSecondary)), ], ), ); }).toList(), ); } }