import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../models/subscription.dart'; import '../../providers/category_provider.dart'; import '../../providers/locale_provider.dart'; import '../../widgets/glassmorphism_card.dart'; import '../../widgets/themed_text.dart'; import '../../widgets/common/buttons/primary_button.dart'; import '../../widgets/common/buttons/secondary_button.dart'; import '../../widgets/common/form_fields/base_text_field.dart'; import '../../widgets/common/form_fields/category_selector.dart'; import '../../widgets/common/snackbar/app_snackbar.dart'; import '../../widgets/native_ad_widget.dart'; import '../../theme/app_colors.dart'; import '../../services/currency_util.dart'; import '../../utils/sms_scan/date_formatter.dart'; import '../../utils/sms_scan/category_icon_mapper.dart'; import '../../l10n/app_localizations.dart'; class SubscriptionCardWidget extends StatefulWidget { final Subscription subscription; final TextEditingController websiteUrlController; final String? selectedCategoryId; final Function(String?) onCategoryChanged; final VoidCallback onAdd; final VoidCallback onSkip; const SubscriptionCardWidget({ super.key, required this.subscription, required this.websiteUrlController, this.selectedCategoryId, required this.onCategoryChanged, required this.onAdd, required this.onSkip, }); @override State createState() => _SubscriptionCardWidgetState(); } class _SubscriptionCardWidgetState extends State { @override void initState() { super.initState(); // URL 필드 자동 설정 if (widget.websiteUrlController.text.isEmpty && widget.subscription.websiteUrl != null) { widget.websiteUrlController.text = widget.subscription.websiteUrl!; } } void _handleCardTap() { // 디버그 로그 추가 print('[SubscriptionCard] Card tapped! Service: ${widget.subscription.serviceName}'); // 구독 카드 클릭 시 처리 AppSnackBar.showInfo( context: context, message: '이 기능은 곧 출시됩니다', // 임시로 하드코딩 icon: Icons.info_outline, ); } @override Widget build(BuildContext context) { final categoryProvider = Provider.of(context); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 광고 위젯 추가 const NativeAdWidget(key: ValueKey('sms_scan_result_ad')), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 구독 정보 카드 GlassmorphismCard( width: double.infinity, padding: EdgeInsets.zero, child: Column( children: [ // 클릭 가능한 정보 영역 GestureDetector( behavior: HitTestBehavior.opaque, onTap: _handleCardTap, child: Padding( padding: const EdgeInsets.all(16.0), child: _buildInfoSection(categoryProvider), ), ), // 구분선 Container( height: 1, color: AppColors.navyGray.withValues(alpha: 0.1), ), // 클릭 불가능한 액션 영역 Padding( padding: const EdgeInsets.all(16.0), child: _buildActionSection(categoryProvider), ), ], ), ), ], ), ), ], ); } // 정보 섹션 (클릭 가능) Widget _buildInfoSection(CategoryProvider categoryProvider) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemedText( AppLocalizations.of(context).foundSubscription, fontSize: 18, fontWeight: FontWeight.bold, forceDark: true, ), const SizedBox(height: 24), // 서비스명 ThemedText( AppLocalizations.of(context).serviceName, fontWeight: FontWeight.w500, opacity: 0.7, forceDark: true, ), const SizedBox(height: 4), ThemedText( widget.subscription.serviceName, fontSize: 22, fontWeight: FontWeight.bold, forceDark: true, ), const SizedBox(height: 16), // 금액 및 결제 주기 Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemedText( AppLocalizations.of(context).monthlyCost, fontWeight: FontWeight.w500, opacity: 0.7, forceDark: true, ), const SizedBox(height: 4), // 언어별 통화 표시 FutureBuilder( future: CurrencyUtil.formatAmountWithLocale( widget.subscription.monthlyCost, widget.subscription.currency, context.read().locale.languageCode, ), builder: (context, snapshot) { return ThemedText( snapshot.data ?? '-', fontSize: 18, fontWeight: FontWeight.bold, forceDark: true, ); }, ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemedText( AppLocalizations.of(context).billingCycle, fontWeight: FontWeight.w500, opacity: 0.7, forceDark: true, ), const SizedBox(height: 4), ThemedText( widget.subscription.billingCycle, fontSize: 16, fontWeight: FontWeight.w500, forceDark: true, ), ], ), ), ], ), const SizedBox(height: 16), // 다음 결제일 ThemedText( AppLocalizations.of(context).nextBillingDateLabel, fontWeight: FontWeight.w500, opacity: 0.7, forceDark: true, ), const SizedBox(height: 4), ThemedText( SmsDateFormatter.getNextBillingText( context, widget.subscription.nextBillingDate, widget.subscription.billingCycle, ), fontSize: 16, fontWeight: FontWeight.w500, forceDark: true, ), ], ); } // 액션 섹션 (클릭 불가능) Widget _buildActionSection(CategoryProvider categoryProvider) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 카테고리 선택 ThemedText( AppLocalizations.of(context).category, fontWeight: FontWeight.w500, opacity: 0.7, forceDark: true, ), const SizedBox(height: 8), CategorySelector( categories: categoryProvider.categories, selectedCategoryId: widget.selectedCategoryId ?? widget.subscription.category, onChanged: widget.onCategoryChanged, baseColor: _getCategoryColor(categoryProvider), isGlassmorphism: true, ), const SizedBox(height: 24), // 웹사이트 URL 입력 필드 BaseTextField( controller: widget.websiteUrlController, label: AppLocalizations.of(context).websiteUrlAuto, hintText: AppLocalizations.of(context).websiteUrlHint, prefixIcon: Icon( Icons.language, color: AppColors.navyGray, ), style: TextStyle( color: AppColors.darkNavy, ), fillColor: AppColors.pureWhite.withValues(alpha: 0.8), ), const SizedBox(height: 32), // 작업 버튼 Row( children: [ Expanded( child: SecondaryButton( text: AppLocalizations.of(context).skip, onPressed: widget.onSkip, height: 48, ), ), const SizedBox(width: 16), Expanded( child: PrimaryButton( text: AppLocalizations.of(context).add, onPressed: widget.onAdd, height: 48, ), ), ], ), ], ); } Color? _getCategoryColor(CategoryProvider categoryProvider) { final categoryId = widget.selectedCategoryId ?? widget.subscription.category; if (categoryId == null) return null; final category = categoryProvider.getCategoryById(categoryId); if (category == null) return null; return CategoryIconMapper.getCategoryColor(category); } }