ponshu-room-lite/lib/screens/sake_detail/sections/sake_mbti_stamp_section.dart

221 lines
6.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../../../models/sake_item.dart';
import '../../../providers/theme_provider.dart';
import '../../../services/mbti_compatibility_service.dart';
import '../../../theme/app_colors.dart';
import '../../../main.dart'; // For isProVersion
/// MBTI酒向スタンプセクション
///
/// Pro版: MBTI診断結果に基づく相性スタンプを表示
/// Lite版: Pro版限定機能のロック表示
class SakeMbtiStampSection extends ConsumerWidget {
final SakeItem sake;
const SakeMbtiStampSection({
super.key,
required this.sake,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final appColors = Theme.of(context).extension<AppColors>()!;
return Container(
width: double.infinity,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
border: Border.all(
color: isProVersion
? appColors.brandPrimary.withValues(alpha: 0.3)
: appColors.divider,
style: BorderStyle.solid,
width: 2,
),
borderRadius: BorderRadius.circular(16),
color: Theme.of(context).cardColor.withValues(alpha: 0.5),
),
child: isProVersion
? _buildProContent(context, ref, appColors)
: _buildLiteContent(context, appColors),
);
}
/// Pro版: MBTI相性スタンプ表示
Widget _buildProContent(BuildContext context, WidgetRef ref, AppColors appColors) {
final userProfile = ref.watch(userProfileProvider);
final mbtiType = userProfile.mbti;
// MBTI未設定の場合
if (mbtiType == null || mbtiType.isEmpty) {
return Column(
children: [
Icon(LucideIcons.compass, color: appColors.brandAccent, size: 32),
const SizedBox(height: 12),
Text(
'MBTI酒向スタンプ',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: appColors.brandPrimary,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: appColors.surfaceSubtle,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'ソムリエ画面でMBTI診断を完了すると\n相性スタンプが表示されます',
style: TextStyle(
fontSize: 12,
color: appColors.textSecondary,
),
textAlign: TextAlign.center,
),
),
],
);
}
// MBTI相性計算
final result = MBTICompatibilityService.calculateCompatibility(mbtiType, sake);
if (!result.hasResult) {
return Column(
children: [
Icon(LucideIcons.helpCircle, color: appColors.textSecondary, size: 32),
const SizedBox(height: 12),
Text(
'相性データなし',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: appColors.textSecondary,
),
),
],
);
}
// 相性レベルに応じた色
final stampColor = result.starRating >= 4
? appColors.brandPrimary
: result.starRating >= 3
? appColors.brandAccent
: appColors.textSecondary;
return Column(
children: [
// スタンプアイコン
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
stampColor.withValues(alpha: 0.2),
stampColor.withValues(alpha: 0.1),
],
),
border: Border.all(
color: stampColor.withValues(alpha: 0.5),
width: 2,
),
),
child: Text(
result.starDisplay,
style: TextStyle(
fontSize: 24,
color: stampColor,
),
),
),
const SizedBox(height: 12),
// MBTIタイプと相性レベル
Text(
'$mbtiType x この日本酒',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: appColors.brandPrimary,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
result.level,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: stampColor,
),
),
const SizedBox(height: 8),
// パーセント表示
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
decoration: BoxDecoration(
color: stampColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16),
),
child: Text(
'${(result.score * 100).round()}% マッチ',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: stampColor,
),
),
),
// マッチ理由
if (result.reasons.isNotEmpty) ...[
const SizedBox(height: 12),
...result.reasons.take(2).map((reason) => Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(LucideIcons.check, size: 12, color: appColors.textSecondary),
const SizedBox(width: 4),
Text(
reason,
style: TextStyle(
fontSize: 11,
color: appColors.textSecondary,
),
),
],
),
)),
],
],
);
}
/// Lite版: Pro版限定機能のロック表示
Widget _buildLiteContent(BuildContext context, AppColors appColors) {
return Column(
children: [
Icon(LucideIcons.lock, color: appColors.iconSubtle, size: 32),
const SizedBox(height: 12),
Text(
'Pro版限定機能',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: appColors.textSecondary,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'MBTI酒向スタンプは\nPro版でご利用いただけます',
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: appColors.textTertiary),
textAlign: TextAlign.center,
),
],
);
}
}