import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons/lucide_icons.dart'; import 'package:screenshot/screenshot.dart'; import 'package:share_plus/share_plus.dart'; import 'package:path_provider/path_provider.dart'; import '../../providers/sake_list_provider.dart'; import '../../services/shuko_diagnosis_service.dart'; import '../../theme/app_theme.dart'; import '../../widgets/sake_radar_chart.dart'; class SommelierScreen extends ConsumerStatefulWidget { const SommelierScreen({super.key}); @override ConsumerState createState() => _SommelierScreenState(); } class _SommelierScreenState extends ConsumerState { final ScreenshotController _screenshotController = ScreenshotController(); bool _isSharing = false; Future _shareCard() async { setState(() { _isSharing = true; }); try { final image = await _screenshotController.capture( delay: const Duration(milliseconds: 10), pixelRatio: 3.0, // High res for sharing ); if (image == null) return; final directory = await getTemporaryDirectory(); final imagePath = await File('${directory.path}/sommelier_card.png').create(); await imagePath.writeAsBytes(image); // Share the file await Share.shareXFiles( [XFile(imagePath.path)], text: '私の酒向タイプはこれ! #ポンシュルーム', ); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('シェアに失敗しました: $e')), ); } } finally { if (mounted) { setState(() { _isSharing = false; }); } } } @override Widget build(BuildContext context) { final sakeListAsync = ref.watch(sakeListProvider); final diagnosisService = ref.watch(shukoDiagnosisServiceProvider); return Scaffold( appBar: AppBar( title: const Text('AIソムリエ診断'), centerTitle: true, ), body: sakeListAsync.when( data: (sakeList) { final profile = diagnosisService.diagnose(sakeList); return SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Column( children: [ Screenshot( controller: _screenshotController, child: _buildShukoCard(context, profile), ), const SizedBox(height: 32), _buildActionButtons(context), ], ), ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('エラー: $err')), ), ); } Widget _buildShukoCard(BuildContext context, ShukoProfile profile) { final isDark = Theme.of(context).brightness == Brightness.dark; return Container( width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), // Premium Card Gradient gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: isDark ? [const Color(0xFF2C3E50), const Color(0xFF000000)] : [const Color(0xFFE0EAFC), const Color(0xFFCFDEF3)], ), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: Stack( children: [ // Background Pattern (Optional subtle decoration) Positioned( right: -20, top: -20, child: Icon( LucideIcons.sparkles, size: 150, color: isDark ? Colors.white.withValues(alpha: 0.05) : Colors.blue.withValues(alpha: 0.05), ), ), // Subtle Sake Emoji Positioned( left: 20, top: 20, child: Opacity( opacity: 0.3, // Subtle child: const Text( '🍶', style: TextStyle(fontSize: 40), ), ), ), Padding( padding: const EdgeInsets.all(32.0), child: Column( children: [ // 1. Header (Name & Rank) Text( 'あなたの酒向タイプ', style: Theme.of(context).textTheme.bodySmall?.copyWith(letterSpacing: 1.5), ), const SizedBox(height: 16), // 2. Title Text( profile.title, textAlign: TextAlign.center, style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: AppTheme.posimaiBlue, shadows: [ Shadow( color: AppTheme.posimaiBlue.withValues(alpha: 0.3), blurRadius: 10, offset: const Offset(0, 2), ), ], ), ), const SizedBox(height: 16), Text( profile.description, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( height: 1.5, ), ), const SizedBox(height: 32), SizedBox( height: 200, child: SakeRadarChart( tasteStats: { 'aroma': (profile.avgStats.aroma).round(), 'bitterness': (profile.avgStats.richness).round(), 'sweetness': (profile.avgStats.sweetness).round(), 'acidity': (profile.avgStats.alcoholFeeling).round(), 'body': (profile.avgStats.fruitiness).round(), }, primaryColor: AppTheme.posimaiBlue, ), ), const SizedBox(height: 24), // 4. Stats Footer Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(12), ), child: Text( '分析対象: ${profile.analyzedCount} / ${profile.totalSakeCount} 本', style: Theme.of(context).textTheme.bodySmall, ), ), ], ), ), ], ), ); } Widget _buildActionButtons(BuildContext context) { return Column( children: [ SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: _isSharing ? null : _shareCard, icon: _isSharing ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2)) : const Icon(LucideIcons.share2), label: const Padding( padding: EdgeInsets.symmetric(vertical: 12.0), child: Text('カードをシェアする'), ), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.posimaiBlue, foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ), ), const SizedBox(height: 16), TextButton( onPressed: () { // Chat entry point (Plan B) ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('AIソムリエとの会話は次のステップです')), ); }, child: const Text('AIソムリエに詳しく聞く'), ), ], ); } }