import 'package:dietary_guard/controllers/alert.dart'; import 'package:dietary_guard/models/alert_configuration.dart'; import 'package:dietary_guard/models/food_data.dart'; import 'package:dietary_guard/widgets/alert_detect_result.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class FoodDetailsScreen extends StatefulWidget { final FoodData item; const FoodDetailsScreen({super.key, required this.item}); @override State createState() => _FoodDetailsScreenState(); } class _FoodDetailsScreenState extends State { final List _alertDetectResult = List.empty(growable: true); @override void initState() { super.initState(); _detectAlert(); } void _detectAlert() { final AlertController alert = Get.find(); if (alert.configuration.isEmpty) return; for (final item in alert.configuration) { bool isUndetected = true; bool isOutOfRange = false; double? difference; String name = 'undetected'.tr; String? unitName; FoodNutrient? current; for (final nutrient in widget.item.foodNutrients) { if (item.nutrientId != nutrient.nutrientId) continue; name = nutrient.nutrientName; unitName = unitNameValues.reverse[nutrient.unitName]; if (nutrient.value != null) { current = nutrient; final value = nutrient.value!; if (value > item.maxValue) { difference = value - item.maxValue; isOutOfRange = true; } else if (value < item.minValue) { difference = value - item.minValue; isOutOfRange = true; } isUndetected = false; } } _alertDetectResult.add(AlertDetectResult( config: item, nutrient: current, name: name, unitName: unitName, difference: difference, isOutOfRange: isOutOfRange, isUndetected: isUndetected, )); } } Widget _buildShowAlertResultButton() { return IconButton( icon: const Icon(Icons.assignment), onPressed: () { showModalBottomSheet( useRootNavigator: true, isScrollControlled: true, context: context, builder: (context) => AlertDetectResultDialog( result: _alertDetectResult, ), ); }, ); } @override Widget build(BuildContext context) { return Material( color: Theme.of(context).colorScheme.surface, child: Scaffold( appBar: AppBar( title: Text(widget.item.description), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (_alertDetectResult.isEmpty) MaterialBanner( padding: const EdgeInsets.only(left: 24, right: 8), content: Text('alertEmpty'.tr), actions: const [SizedBox()], dividerColor: Colors.transparent, ) else if (_alertDetectResult.any((x) => x.isOutOfRange)) MaterialBanner( leading: const Icon(Icons.close), backgroundColor: Colors.red, padding: const EdgeInsets.only(left: 24, right: 8), content: Text('alertOutOfRange'.trParams({ 'count': _alertDetectResult .where((x) => x.isOutOfRange) .length .toString() })), actions: [_buildShowAlertResultButton()], dividerColor: Colors.transparent, ) else if (_alertDetectResult.any((x) => x.isUndetected)) MaterialBanner( leading: const Icon(Icons.question_mark), backgroundColor: Colors.grey, padding: const EdgeInsets.only(left: 24, right: 8), content: Text('alertUnclear'.trParams({ 'count': _alertDetectResult .where((x) => x.isUndetected) .length .toString() })), actions: [_buildShowAlertResultButton()], dividerColor: Colors.transparent, ) else MaterialBanner( leading: const Icon(Icons.check), backgroundColor: Colors.green, padding: const EdgeInsets.only(left: 24, right: 8), content: Text('alertSafe'.tr), actions: [_buildShowAlertResultButton()], dividerColor: Colors.transparent, ), const SizedBox(height: 16), Text('nutrients'.tr).paddingOnly(left: 24, right: 24, bottom: 8), Expanded( child: ListView.builder( itemCount: widget.item.foodNutrients.length, itemBuilder: (context, idx) { final entry = widget.item.foodNutrients[idx]; final unitName = unitNameValues.reverse[entry.unitName]; return ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 24), title: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(entry.nutrientName), const SizedBox(width: 6), Badge(label: Text('#${entry.nutrientId}')) ], ), subtitle: Text( '${entry.value?.toString() ?? '-'} $unitName', ), ); }, ), ) ], ), ), ); } }