import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons/lucide_icons.dart'; import '../../providers/sake_list_provider.dart'; import '../../models/schema/item_type.dart'; import '../../services/api_usage_service.dart'; import '../../theme/app_colors.dart'; class ActivityStats extends ConsumerWidget { const ActivityStats({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final allSakeAsync = ref.watch(allSakeItemsProvider); final apiUsageAsync = ref.watch(apiUsageCountProvider); return allSakeAsync.when( data: (sakes) { final individualSakes = sakes.where((s) => s.itemType == ItemType.sake).toList(); final totalSakes = individualSakes.length; final favoriteCount = individualSakes.where((s) => s.userData.isFavorite).length; final dates = individualSakes.map((s) { final d = s.metadata.createdAt; return DateTime(d.year, d.month, d.day); }).toSet(); final recordingDays = dates.length; final apiCount = apiUsageAsync.asData?.value ?? 0; final remaining = (ApiUsageService.dailyLimit - apiCount).clamp(0, ApiUsageService.dailyLimit); final isExhausted = remaining == 0; final isLow = remaining <= 5 && !isExhausted; final appColors = Theme.of(context).extension()!; final apiColor = isExhausted ? appColors.error : isLow ? appColors.warning : appColors.brandPrimary; // Bento Grid: 総登録数を大カード、お気に入り・撮影日数を小カード2枚横並び return Column( children: [ // 大カード — 総登録数 _BentoCard( child: Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: appColors.brandPrimary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), ), child: Icon(LucideIcons.wine, size: 28, color: appColors.brandPrimary), ), const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$totalSakes本', style: TextStyle( fontSize: 32, fontWeight: FontWeight.w900, color: appColors.brandPrimary, height: 1.0, ), ), const SizedBox(height: 4), Text( '総登録数', style: TextStyle( fontSize: 12, color: appColors.textSecondary, fontWeight: FontWeight.w500, ), ), ], ), ], ), ), const SizedBox(height: 8), // 小カード2枚横並び Row( children: [ Expanded( child: _BentoCard( child: Row( children: [ Icon(LucideIcons.heart, size: 20, color: appColors.brandAccent), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$favoriteCount本', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w900, color: appColors.textPrimary, height: 1.0, ), ), const SizedBox(height: 3), Text( 'お気に入り', style: TextStyle(fontSize: 11, color: appColors.textSecondary), ), ], ), ], ), ), ), const SizedBox(width: 8), Expanded( child: _BentoCard( child: Row( children: [ Icon(LucideIcons.calendar, size: 20, color: appColors.iconDefault), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$recordingDays日', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w900, color: appColors.textPrimary, height: 1.0, ), ), const SizedBox(height: 3), Text( '撮影日数', style: TextStyle(fontSize: 11, color: appColors.textSecondary), ), ], ), ], ), ), ), ], ), const SizedBox(height: 8), // AI 使用状況カード _BentoCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(LucideIcons.sparkles, size: 14, color: apiColor), const SizedBox(width: 6), Text( '今日のAI解析', style: TextStyle(fontSize: 11, color: appColors.textSecondary), ), const Spacer(), Text( '$apiCount / ${ApiUsageService.dailyLimit}回', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: apiColor, ), ), ], ), const SizedBox(height: 8), ClipRRect( borderRadius: BorderRadius.circular(4), child: LinearProgressIndicator( value: apiCount / ApiUsageService.dailyLimit, backgroundColor: appColors.surfaceSubtle, valueColor: AlwaysStoppedAnimation(apiColor), minHeight: 5, ), ), if (isExhausted) ...[ const SizedBox(height: 6), Text( '本日の上限に達しました。写真は保存されています。', style: TextStyle(fontSize: 10, color: appColors.error), ), ] else if (isLow) ...[ const SizedBox(height: 6), Text( '残り$remaining回です。', style: TextStyle(fontSize: 10, color: appColors.warning), ), ], ], ), ), ], ); }, loading: () => const SizedBox.shrink(), error: (_, _) => const SizedBox.shrink(), ); } } class _BentoCard extends StatelessWidget { const _BentoCard({required this.child}); final Widget child; @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(16), border: Border.all( color: Theme.of(context).dividerColor.withValues(alpha: 0.1), ), ), child: child, ); } }