import 'package:flutter/material.dart'; import 'package:asciineverdie/src/core/l10n/game_data_l10n.dart'; import 'package:asciineverdie/src/core/model/hall_of_fame.dart'; import 'package:asciineverdie/src/shared/retro_colors.dart'; /// 아레나 순위 카드 위젯 /// /// 명예의 전당 캐릭터를 순위와 함께 표시 class ArenaRankCard extends StatelessWidget { const ArenaRankCard({ super.key, required this.entry, required this.rank, required this.score, this.isSelected = false, this.isHighlighted = false, this.compact = false, this.onTap, }); /// 캐릭터 엔트리 final HallOfFameEntry entry; /// 순위 (1-based) final int rank; /// 아레나 점수 final int score; /// 선택 상태 (상대로 선택됨) final bool isSelected; /// 하이라이트 상태 (내 캐릭터 표시) final bool isHighlighted; /// 컴팩트 모드 (작은 사이즈) final bool compact; /// 탭 콜백 final VoidCallback? onTap; @override Widget build(BuildContext context) { final rankColor = _getRankColor(rank); final rankIcon = _getRankIcon(rank); // 배경색 결정 Color bgColor; Color borderColor; if (isSelected) { bgColor = Colors.red.withValues(alpha: 0.15); borderColor = Colors.red; } else if (isHighlighted) { bgColor = Colors.blue.withValues(alpha: 0.15); borderColor = Colors.blue; } else { bgColor = RetroColors.panelBgOf(context); borderColor = RetroColors.borderOf(context); } return Card( margin: EdgeInsets.symmetric( vertical: compact ? 2 : 4, horizontal: compact ? 0 : 8, ), color: bgColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(compact ? 6 : 8), side: BorderSide( color: borderColor, width: (isSelected || isHighlighted) ? 2 : 1, ), ), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(compact ? 6 : 8), child: Padding( padding: EdgeInsets.all(compact ? 8 : 12), child: Row( children: [ // 순위 배지 _buildRankBadge(rankColor, rankIcon), SizedBox(width: compact ? 8 : 12), // 캐릭터 정보 Expanded(child: _buildCharacterInfo(context)), // 점수 if (!compact) _buildScoreColumn(context), ], ), ), ), ); } Widget _buildRankBadge(Color color, IconData? icon) { final size = compact ? 24.0 : 36.0; final iconSize = compact ? 12.0 : 18.0; final fontSize = compact ? 7.0 : 10.0; return Container( width: size, height: size, decoration: BoxDecoration( color: color.withValues(alpha: 0.2), shape: BoxShape.circle, border: Border.all(color: color, width: compact ? 1.5 : 2), ), child: Center( child: icon != null ? Icon(icon, color: color, size: iconSize) : Text( '$rank', style: TextStyle( fontFamily: 'PressStart2P', fontSize: fontSize, color: color, fontWeight: FontWeight.bold, ), ), ), ); } Widget _buildCharacterInfo(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 이름 Text( entry.characterName, style: TextStyle( fontFamily: 'PressStart2P', fontSize: compact ? 6 : 9, color: RetroColors.textPrimaryOf(context), ), overflow: TextOverflow.ellipsis, maxLines: 1, ), SizedBox(height: compact ? 2 : 4), // 종족/클래스 + 레벨 Text( compact ? 'Lv.${entry.level}' : '${GameDataL10n.getRaceName(context, entry.race)} ' '${GameDataL10n.getKlassName(context, entry.klass)} ' 'Lv.${entry.level}', style: TextStyle( fontFamily: 'PressStart2P', fontSize: compact ? 5 : 7, color: RetroColors.textSecondaryOf(context), ), ), ], ); } Widget _buildScoreColumn(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '$score', style: TextStyle( fontFamily: 'PressStart2P', fontSize: 10, color: RetroColors.goldOf(context), fontWeight: FontWeight.bold, ), ), Text( 'SCORE', style: TextStyle( fontFamily: 'PressStart2P', fontSize: 6, color: RetroColors.textMutedOf(context), ), ), ], ); } Color _getRankColor(int rank) { switch (rank) { case 1: return Colors.amber.shade700; case 2: return Colors.grey.shade500; case 3: return Colors.brown.shade400; default: return Colors.blue.shade400; } } IconData? _getRankIcon(int rank) { switch (rank) { case 1: return Icons.emoji_events; case 2: return Icons.workspace_premium; case 3: return Icons.military_tech; default: return null; } } }