import 'package:flutter/material.dart'; import '../../game/models.dart'; import '../../game/enums.dart'; import '../../utils.dart'; import '../../game/config.dart'; class ItemCardWidget extends StatelessWidget { final Item item; final VoidCallback? onTap; final bool showPrice; final bool canBuy; final bool compact; const ItemCardWidget({ super.key, required this.item, this.onTap, this.showPrice = false, this.canBuy = true, this.compact = false, }); @override Widget build(BuildContext context) { return InkWell( onTap: onTap, child: Card( color: ThemeConfig.shopItemCardBg, // Configurable if needed shape: item.rarity != ItemRarity.normal ? RoundedRectangleBorder( side: BorderSide( color: ItemUtils.getRarityColor(item.rarity), width: 2.0, ), borderRadius: BorderRadius.circular(8.0), ) : null, child: Stack( fit: StackFit.expand, children: [ // Background Watermark/Silhouette Icon (Top-Left) Positioned( left: compact ? 4 : 8, top: compact ? 4 : 8, child: Image.asset( ItemUtils.getIconPath(item.slot), width: compact ? 24 : 32, height: compact ? 24 : 32, fit: BoxFit.contain, color: Colors.black12, // Shadow silhouette ), ), // Main Content (Centered) Center( child: Padding( padding: EdgeInsets.all(compact ? 2.0 : 4.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ if (!compact) const SizedBox(height: 12), Text( item.name, maxLines: 1, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: FontWeight.bold, color: ItemUtils.getRarityColor(item.rarity), fontSize: compact ? 10 : 12, ), ), if (item.weaponType != null) Text( item.weaponType == WeaponType.oneHanded ? "1-Handed" : "2-Handed", style: const TextStyle(fontSize: 9, color: ThemeConfig.textColorGrey), ), SizedBox(height: compact ? 1 : 4), // Show Item Stats if (compact) _buildCompactItemStatText(item) else FittedBox( fit: BoxFit.scaleDown, child: _buildItemStatText(item), ), if (showPrice) ...[ const SizedBox(height: 4), Text( "${item.price} G", textAlign: TextAlign.center, style: TextStyle( color: canBuy ? ThemeConfig.statGoldColor : ThemeConfig.textColorGrey, fontWeight: FontWeight.bold, fontSize: 12, ), ), ], ], ), ), ), ], ), ), ); } Widget _buildCompactItemStatText(Item item) { final stats = []; if (item.atkBonus != 0) { stats.add("${_sign(item.atkBonus)}${item.atkBonus}A"); } if (item.hpBonus != 0) { stats.add("${_sign(item.hpBonus)}${item.hpBonus}H"); } if (item.armorBonus != 0) { stats.add("${_sign(item.armorBonus)}${item.armorBonus}D"); } if (item.luck != 0) { stats.add("${_sign(item.luck)}${item.luck}L"); } final effect = item.effects.isNotEmpty ? item.effects.first.type.name.toUpperCase() : null; final text = [ if (stats.isNotEmpty) stats.join(" "), if (effect != null) effect, ].join(" "); if (text.isEmpty) return const SizedBox.shrink(); return Text( text, maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: const TextStyle( fontSize: ThemeConfig.fontSizeTiny, color: ThemeConfig.statAtkColor, ), ); } String _sign(int value) => value > 0 ? "+" : ""; Widget _buildItemStatText(Item item) { List stats = []; // Helper to format stat string String formatStat(int value, String label) { String sign = _sign(value); // Negative values already have '-' return "$sign$value $label"; } if (item.atkBonus != 0) { stats.add(formatStat(item.atkBonus, AppStrings.atk)); } if (item.hpBonus != 0) { stats.add(formatStat(item.hpBonus, AppStrings.hp)); } if (item.armorBonus != 0) { stats.add(formatStat(item.armorBonus, AppStrings.def)); } if (item.luck != 0) { stats.add(formatStat(item.luck, AppStrings.luck)); } List effectTexts = item.effects.map((e) => e.description).toList(); if (stats.isEmpty && effectTexts.isEmpty) return const SizedBox.shrink(); return Column( children: [ if (stats.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 2.0, bottom: 2.0), child: Text( stats.join(", "), style: const TextStyle( fontSize: ThemeConfig.fontSizeSmall, color: ThemeConfig.statAtkColor, ), textAlign: TextAlign.center, ), ), if (effectTexts.isNotEmpty) Padding( padding: const EdgeInsets.only(bottom: 2.0), child: Text( effectTexts.join("\n"), style: const TextStyle( fontSize: ThemeConfig.fontSizeTiny, color: ThemeConfig.rarityLegendary, ), ), ), ], ); } }