import 'package:flutter/material.dart'; import 'package:askiineverdie/data/game_text_l10n.dart' as l10n; import 'package:askiineverdie/data/potion_data.dart'; import 'package:askiineverdie/src/core/model/potion.dart'; /// 물약 인벤토리 패널 /// /// 보유 중인 물약 목록과 수량을 표시. /// HP 물약은 빨간색, MP 물약은 파란색으로 구분. class PotionInventoryPanel extends StatelessWidget { const PotionInventoryPanel({ super.key, required this.inventory, this.usedInBattle = const {}, }); final PotionInventory inventory; final Set usedInBattle; @override Widget build(BuildContext context) { final potionEntries = _buildPotionEntries(); if (potionEntries.isEmpty) { return Center( child: Text( l10n.uiNoPotions, style: const TextStyle( fontSize: 11, color: Colors.grey, fontStyle: FontStyle.italic, ), ), ); } return ListView.builder( itemCount: potionEntries.length, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), itemBuilder: (context, index) { final entry = potionEntries[index]; return _PotionRow( potion: entry.potion, quantity: entry.quantity, isUsedThisBattle: usedInBattle.contains(entry.potion.type), ); }, ); } /// 물약 엔트리 목록 생성 /// /// HP 물약 먼저, MP 물약 나중에 정렬 List<_PotionEntry> _buildPotionEntries() { final entries = <_PotionEntry>[]; for (final potionId in inventory.potions.keys) { final quantity = inventory.potions[potionId] ?? 0; if (quantity <= 0) continue; final potion = PotionData.getById(potionId); if (potion == null) continue; entries.add(_PotionEntry(potion: potion, quantity: quantity)); } // HP 물약 우선, 같은 타입 내에서는 티어순 entries.sort((a, b) { final typeCompare = a.potion.type.index.compareTo(b.potion.type.index); if (typeCompare != 0) return typeCompare; return a.potion.tier.compareTo(b.potion.tier); }); return entries; } } /// 물약 엔트리 class _PotionEntry { const _PotionEntry({required this.potion, required this.quantity}); final Potion potion; final int quantity; } /// 물약 행 위젯 class _PotionRow extends StatelessWidget { const _PotionRow({ required this.potion, required this.quantity, this.isUsedThisBattle = false, }); final Potion potion; final int quantity; final bool isUsedThisBattle; @override Widget build(BuildContext context) { final color = _getPotionColor(); final opacity = isUsedThisBattle ? 0.5 : 1.0; return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Opacity( opacity: opacity, child: Row( children: [ // 물약 아이콘 _PotionIcon(type: potion.type, tier: potion.tier), const SizedBox(width: 4), // 물약 이름 (번역 적용) Expanded( child: Text( l10n.translateSpell(potion.name), style: TextStyle( fontSize: 11, color: color, fontWeight: FontWeight.w500, ), overflow: TextOverflow.ellipsis, ), ), // 회복량 표시 _HealBadge(potion: potion), const SizedBox(width: 4), // 수량 Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: color.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(8), ), child: Text( 'x$quantity', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold, color: color, ), ), ), // 전투 중 사용 불가 표시 if (isUsedThisBattle) ...[ const SizedBox(width: 4), const Icon(Icons.block, size: 12, color: Colors.grey), ], ], ), ), ); } Color _getPotionColor() { return switch (potion.type) { PotionType.hp => Colors.red.shade700, PotionType.mp => Colors.blue.shade700, }; } } /// 물약 아이콘 class _PotionIcon extends StatelessWidget { const _PotionIcon({required this.type, required this.tier}); final PotionType type; final int tier; @override Widget build(BuildContext context) { final color = type == PotionType.hp ? Colors.red.shade400 : Colors.blue.shade400; // 티어에 따른 아이콘 크기 조절 final size = 12.0 + tier * 1.0; return Container( width: 18, height: 18, alignment: Alignment.center, child: Icon( type == PotionType.hp ? Icons.favorite : Icons.bolt, size: size.clamp(12, 18), color: color, ), ); } } /// 회복량 배지 class _HealBadge extends StatelessWidget { const _HealBadge({required this.potion}); final Potion potion; @override Widget build(BuildContext context) { final healText = _buildHealText(); return Container( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(4), ), child: Text( healText, style: TextStyle(fontSize: 9, color: Colors.grey.shade700), ), ); } String _buildHealText() { final parts = []; if (potion.healAmount > 0) { parts.add('+${potion.healAmount}'); } if (potion.healPercent > 0) { final percent = (potion.healPercent * 100).round(); parts.add('+$percent%'); } return parts.join(' '); } }