import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/sake_item.dart'; import '../models/schema/sake_taste_stats.dart'; final shukoDiagnosisServiceProvider = Provider((ref) => ShukoDiagnosisService()); class ShukoDiagnosisService { ShukoProfile diagnose(List items) { if (items.isEmpty) { return ShukoProfile.empty(); } // 1. Calculate Average Stats double totalAroma = 0; double totalRichness = 0; double totalSweetness = 0; double totalAlcohol = 0; double totalFruity = 0; int count = 0; for (var item in items) { final stats = item.hiddenSpecs.sakeTasteStats; totalAroma += stats.aroma; totalRichness += stats.richness; totalSweetness += stats.sweetness; totalAlcohol += stats.alcoholFeeling; totalFruity += stats.fruitiness; count++; } if (count == 0) { return ShukoProfile.empty(); } final avgStats = SakeTasteStats( aroma: totalAroma / count, richness: totalRichness / count, sweetness: totalSweetness / count, alcoholFeeling: totalAlcohol / count, fruitiness: totalFruity / count, ); // 2. Determine Title based on dominant traits final title = _determineTitle(avgStats); return ShukoProfile( title: title.title, description: title.description, avgStats: avgStats, totalSakeCount: items.length, analyzedCount: count, ); } ShukoTitle _determineTitle(SakeTasteStats stats) { // Simple rule-based logic (can be expanded) // High Alcohol + Dry (Low Sweetness) if (stats.alcoholFeeling > 3.5 && stats.sweetness < 2.5) { return const ShukoTitle( title: '辛口サムライ', description: 'キレのある辛口を好む、硬派な日本酒ファン。', ); } // High Fruitiness + High Sweetness if (stats.fruitiness > 3.5 && stats.sweetness > 3.0) { return const ShukoTitle( title: 'フルーティーマスター', description: '果実のような香りと甘みを愛する、華やかな飲み手。', ); } // High Richness if (stats.richness > 3.8) { return const ShukoTitle( title: '旨口探求者', description: 'お米本来の旨みやコクを重視する、通な舌の持ち主。', ); } // High Aroma if (stats.aroma > 4.0) { return const ShukoTitle( title: '香りの貴族', description: '吟醸香など、鼻に抜ける香りを何より楽しむタイプ。', ); } // Balanced (All around 3) if (stats.aroma > 2.5 && stats.aroma < 3.5 && stats.sweetness > 2.5 && stats.sweetness < 3.5) { return const ShukoTitle( title: 'バランスの賢者', description: '偏りなく様々な酒を楽しむ、オールラウンダー。', ); } // Default return const ShukoTitle( title: 'ポシマイ杜氏', description: '自分だけの好みを探索中の、未来の巨匠。', ); } // v1.1: Personalization Logic String getGreeting(String? nickname) { if (nickname == null || nickname.trim().isEmpty) { return 'ようこそ!'; } return 'ようこそ、$nicknameさん'; } ShukoTitle personalizeTitle(ShukoTitle original, String? gender) { if (gender == null) return original; String suffix = ''; String newTitle = original.title; // Simple customization logic if (gender == 'female') { if (newTitle.contains('サムライ')) newTitle = newTitle.replaceAll('サムライ', '麗人'); if (newTitle.contains('貴族')) newTitle = newTitle.replaceAll('貴族', 'プリンセス'); if (newTitle.contains('賢者')) newTitle = newTitle.replaceAll('賢者', 'ミューズ'); if (newTitle.contains('杜氏')) newTitle = newTitle.replaceAll('杜氏', '看板娘'); // Playful } else if (gender == 'male') { if (newTitle.contains('貴族')) newTitle = newTitle.replaceAll('貴族', '貴公子'); } return ShukoTitle( title: newTitle, description: original.description, ); } } class ShukoProfile { final String title; final String description; final SakeTasteStats avgStats; final int totalSakeCount; final int analyzedCount; ShukoProfile({ required this.title, required this.description, required this.avgStats, required this.totalSakeCount, required this.analyzedCount, }); factory ShukoProfile.empty() { return ShukoProfile( title: '旅の始まり', description: 'まずは日本酒を記録して、\n自分の好みを発見しましょう。', avgStats: SakeTasteStats(aroma: 0, richness: 0, sweetness: 0, alcoholFeeling: 0, fruitiness: 0), totalSakeCount: 0, analyzedCount: 0, ); } } class ShukoTitle { final String title; final String description; const ShukoTitle({required this.title, required this.description}); }