import 'package:flutter/material.dart'; import 'package:line_icons/line_icons.dart'; import 'package:intl/intl.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/analytic/analytic.dart'; import '../../../components/spacer/spacer.dart'; class InventoryIngredientTile extends StatelessWidget { final InventoryIngredient item; const InventoryIngredientTile({super.key, required this.item}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColor.surface, borderRadius: BorderRadius.circular(16), border: Border.all( color: _getStatusColor().withOpacity(0.2), width: 1.5, ), boxShadow: [ BoxShadow( color: _getStatusColor().withOpacity(0.08), blurRadius: 12, offset: const Offset(0, 4), ), BoxShadow( color: AppColor.textLight.withOpacity(0.06), blurRadius: 6, offset: const Offset(0, 2), ), ], ), child: Column( children: [ // Main Row Row( children: [ // Enhanced Icon Container Container( width: 65, height: 65, decoration: BoxDecoration( gradient: LinearGradient( colors: _getGradientColors(), begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: _getStatusColor().withOpacity(0.2), blurRadius: 8, offset: const Offset(0, 3), ), ], ), child: Stack( children: [ Center( child: Icon( _getIngredientIcon(), size: 28, color: AppColor.white, ), ), // Status indicator dot Positioned( top: 6, right: 6, child: Container( width: 12, height: 12, decoration: BoxDecoration( color: AppColor.white, shape: BoxShape.circle, border: Border.all( color: _getStatusColor(), width: 2, ), ), child: Center( child: Container( width: 4, height: 4, decoration: BoxDecoration( color: _getStatusColor(), shape: BoxShape.circle, ), ), ), ), ), ], ), ), const SpaceWidth(16), // Content Section Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Ingredient Name Text( item.ingredientName, style: AppStyle.lg.copyWith( fontWeight: FontWeight.w700, color: AppColor.textPrimary, height: 1.2, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), SpaceHeight(6), // Stock Information Row Row( children: [ Icon( LineIcons.warehouse, size: 14, color: AppColor.textSecondary, ), const SpaceWidth(4), Text( 'Stok: ', style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), Text( '${NumberFormat('#,###', 'id_ID').format(item.quantity)} ${item.unitName}', style: AppStyle.sm.copyWith( color: _getQuantityColor(), fontWeight: FontWeight.w700, ), ), ], ), SpaceHeight(4), // Reorder Level Information Row( children: [ Icon( LineIcons.exclamationTriangle, size: 14, color: AppColor.warning, ), const SpaceWidth(4), Text( 'Min: ', style: AppStyle.sm.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), Text( '${NumberFormat('#,###', 'id_ID').format(item.reorderLevel)} ${item.unitName}', style: AppStyle.sm.copyWith( color: AppColor.warning, fontWeight: FontWeight.w700, ), ), ], ), SpaceHeight(6), // Unit Cost Row( children: [ Icon( LineIcons.dollarSign, size: 14, color: AppColor.success, ), const SpaceWidth(4), Text( item.unitCost.currencyFormatRp, style: AppStyle.sm.copyWith( color: AppColor.success, fontWeight: FontWeight.w700, ), ), Text( '/${item.unitName}', style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), ], ), ], ), ), // Status Badge Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), decoration: BoxDecoration( color: _getStatusColor(), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: _getStatusColor().withOpacity(0.3), blurRadius: 6, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( _getStatusText(), style: AppStyle.sm.copyWith( fontWeight: FontWeight.w700, color: AppColor.white, fontSize: 11, ), ), ], ), ), ], ), // Additional Information Card (if low stock or has movements) if (item.isLowStock || item.totalIn > 0 || item.totalOut > 0) ...[ SpaceHeight(12), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.background, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColor.borderLight, width: 0.5), ), child: Column( children: [ // Warning message for low stock if (item.isLowStock && !item.isZeroStock) ...[ Row( children: [ Icon( LineIcons.exclamationTriangle, size: 16, color: AppColor.warning, ), const SpaceWidth(6), Expanded( child: Text( 'Stok mendekati batas minimum (${item.reorderLevel} ${item.unitName})', style: AppStyle.xs.copyWith( color: AppColor.warning, fontWeight: FontWeight.w600, ), ), ), ], ), if (item.totalIn > 0 || item.totalOut > 0) SpaceHeight(8), ], // Movement Information if (item.totalIn > 0 || item.totalOut > 0) Row( children: [ // Stock In if (item.totalIn > 0) ...[ Expanded( child: Row( children: [ Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: AppColor.success.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), child: Icon( LineIcons.arrowUp, size: 12, color: AppColor.success, ), ), const SpaceWidth(6), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Masuk', style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), Text( '${NumberFormat('#,###', 'id_ID').format(item.totalIn)} ${item.unitName}', style: AppStyle.xs.copyWith( color: AppColor.success, fontWeight: FontWeight.w700, ), ), ], ), ], ), ), ], // Stock Out if (item.totalOut > 0) ...[ if (item.totalIn > 0) const SpaceWidth(16), Expanded( child: Row( children: [ Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: AppColor.error.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), child: Icon( LineIcons.arrowDown, size: 12, color: AppColor.error, ), ), const SpaceWidth(6), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Keluar', style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), Text( '${NumberFormat('#,###', 'id_ID').format(item.totalOut)} ${item.unitName}', style: AppStyle.xs.copyWith( color: AppColor.error, fontWeight: FontWeight.w700, ), ), ], ), ], ), ), ], // Total Value if (item.totalValue > 0) ...[ const SpaceWidth(16), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( 'Nilai Total', style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w500, ), ), Text( _formatCurrencyShort(item.totalValue), style: AppStyle.xs.copyWith( color: AppColor.info, fontWeight: FontWeight.w700, ), ), ], ), ], ], ), ], ), ), ], ], ), ); } // Helper methods Color _getStatusColor() { if (item.isZeroStock) return AppColor.error; if (item.isLowStock) return AppColor.warning; return AppColor.success; } List _getGradientColors() { if (item.isZeroStock) { return [AppColor.error, AppColor.error.withOpacity(0.7)]; } if (item.isLowStock) { return [AppColor.warning, AppColor.warning.withOpacity(0.7)]; } return [AppColor.success, AppColor.success.withOpacity(0.7)]; } Color _getQuantityColor() { if (item.isZeroStock) return AppColor.error; if (item.isLowStock) return AppColor.warning; return AppColor.textPrimary; } String _getStatusText() { if (item.isZeroStock) return 'HABIS'; if (item.isLowStock) return 'MINIM'; return 'TERSEDIA'; } IconData _getIngredientIcon() { final name = item.ingredientName.toLowerCase(); // Food ingredients if (name.contains('tepung') || name.contains('flour')) { return LineIcons.breadSlice; } else if (name.contains('gula') || name.contains('sugar')) { return LineIcons.cube; } else if (name.contains('garam') || name.contains('salt')) { return LineIcons.breadSlice; } else if (name.contains('minyak') || name.contains('oil')) { return LineIcons.tint; } else if (name.contains('susu') || name.contains('milk')) { return LineIcons.glasses; } else if (name.contains('telur') || name.contains('egg')) { return LineIcons.egg; } else if (name.contains('daging') || name.contains('meat')) { return LineIcons.hamburger; } else if (name.contains('sayur') || name.contains('vegetable')) { return LineIcons.carrot; } else if (name.contains('bumbu') || name.contains('spice')) { return LineIcons.leaf; } else if (name.contains('buah') || name.contains('fruit')) { return LineIcons.apple; } else if (name.contains('beras') || name.contains('rice')) { return LineIcons.seedling; } else if (name.contains('kopi') || name.contains('coffee')) { return LineIcons.coffee; } // Default ingredient icon return LineIcons.utensils; } String _formatCurrencyShort(int amount) { if (amount.abs() >= 1000000000) { return 'Rp ${(amount / 1000000000).toStringAsFixed(1)}B'; } else if (amount.abs() >= 1000000) { return 'Rp ${(amount / 1000000).toStringAsFixed(1)}M'; } else if (amount.abs() >= 1000) { return 'Rp ${(amount / 1000).toStringAsFixed(0)}K'; } else { return 'Rp ${NumberFormat('#,###', 'id_ID').format(amount)}'; } } }