import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import '../../models/subscription_model.dart'; import '../../services/currency_util.dart'; // Glass 제거: Material 3 Card 사용 import '../themed_text.dart'; import '../../l10n/app_localizations.dart'; import '../../theme/color_scheme_ext.dart'; /// 이벤트 할인 현황을 보여주는 카드 위젯 class EventAnalysisCard extends StatelessWidget { final AnimationController animationController; final List subscriptions; const EventAnalysisCard({ super.key, required this.animationController, required this.subscriptions, }); @override Widget build(BuildContext context) { final activeEventSubscriptions = subscriptions.where((sub) => sub.isCurrentlyInEvent).toList(); if (activeEventSubscriptions.isEmpty) { return const SliverToBoxAdapter(child: SizedBox.shrink()); } final totalSavings = activeEventSubscriptions.fold( 0, (sum, sub) => sum + sub.eventSavings, ); return SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: FadeTransition( opacity: CurvedAnimation( parent: animationController, curve: const Interval(0.6, 1.0, curve: Curves.easeOut), ), child: SlideTransition( position: Tween( begin: const Offset(0, 0.2), end: Offset.zero, ).animate( CurvedAnimation( parent: animationController, curve: const Interval(0.6, 1.0, curve: Curves.easeOut), ), ), child: Card( elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: BorderSide( color: Theme.of(context) .colorScheme .outline .withValues(alpha: 0.5), ), ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ThemedText.headline( text: AppLocalizations.of(context).eventDiscountStatus, style: const TextStyle(fontSize: 18), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: Theme.of(context).colorScheme.error, borderRadius: BorderRadius.circular(4), ), child: Row( children: [ FaIcon( FontAwesomeIcons.fire, size: 12, color: Theme.of(context).colorScheme.onError, ), const SizedBox(width: 4), Text( AppLocalizations.of(context).servicesInProgress( activeEventSubscriptions.length), style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onError, ), ), ], ), ), ], ), const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .error .withValues(alpha: 0.05), borderRadius: BorderRadius.circular(12), border: Border.all( color: Theme.of(context) .colorScheme .error .withValues(alpha: 0.2), ), ), child: Row( children: [ Icon( Icons.savings, color: Theme.of(context).colorScheme.error, size: 32, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemedText( AppLocalizations.of(context) .monthlySavingAmount, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 4), ThemedText( CurrencyUtil.formatTotalAmount(totalSavings), style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.error, ), ), ], ), ), ], ), ), const SizedBox(height: 16), ThemedText( AppLocalizations.of(context).eventsInProgress, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), ...activeEventSubscriptions.map((sub) { final savings = sub.originalPrice - (sub.eventPrice ?? sub.originalPrice); final discountRate = ((savings / sub.originalPrice) * 100).round(); return Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .onSurface .withValues(alpha: 0.05), borderRadius: BorderRadius.circular(8), border: Border.all( color: Theme.of(context) .colorScheme .onSurfaceVariant .withValues(alpha: 0.2), ), ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemedText( sub.serviceName, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Row( children: [ FutureBuilder( future: CurrencyUtil.formatAmount( sub.originalPrice, sub.currency), builder: (context, snapshot) { if (snapshot.hasData) { return ThemedText( snapshot.data!, style: TextStyle( fontSize: 12, decoration: TextDecoration.lineThrough, color: Theme.of(context) .colorScheme .onSurfaceVariant, ), ); } return const SizedBox(); }, ), const SizedBox(width: 8), Icon( Icons.arrow_forward, size: 12, color: Theme.of(context) .colorScheme .onSurfaceVariant, ), const SizedBox(width: 8), FutureBuilder( future: CurrencyUtil.formatAmount( sub.eventPrice ?? sub.originalPrice, sub.currency, ), builder: (context, snapshot) { if (snapshot.hasData) { return ThemedText( snapshot.data!, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Theme.of(context) .colorScheme .success, ), ); } return const SizedBox(); }, ), ], ), ], ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .error .withValues(alpha: 0.2), borderRadius: BorderRadius.circular(4), ), child: Text( _formatDiscountPercent(context, discountRate), style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.error, ), ), ), ], ), ); }), ], ), ), ), ), ), ), ); } } String _formatDiscountPercent(BuildContext context, int percent) { final raw = AppLocalizations.of(context).discountPercent; // 우선 @ 플레이스홀더가 있으면 치환 if (raw.contains('@')) { return raw.replaceAll('@', percent.toString()); } // % 마커가 있으면 첫 번째 %를 숫자%로 치환 if (raw.contains('%')) { return raw.replaceFirst('%', '$percent%'); } // 폴백: "99% text" 형태 return '$percent% $raw'; }