import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons/lucide_icons.dart'; import 'package:intl/intl.dart'; import 'package:package_info_plus/package_info_plus.dart'; import '../providers/theme_provider.dart'; import '../widgets/settings/app_settings_section.dart'; import '../widgets/settings/other_settings_section.dart'; import '../widgets/settings/backup_settings_section.dart'; class SoulScreen extends ConsumerStatefulWidget { const SoulScreen({super.key}); @override ConsumerState createState() => _SoulScreenState(); } class _SoulScreenState extends ConsumerState { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { final userProfile = ref.watch(userProfileProvider); final themeMode = userProfile.themeMode; final fontPref = userProfile.fontPreference; return Scaffold( appBar: AppBar( title: const Text('マイページ'), centerTitle: true, ), body: ListView( padding: const EdgeInsets.all(16), children: [ // Identity Section _buildSectionHeader('プロフィール (ID)', LucideIcons.fingerprint), Card( child: Column( children: [ ListTile( leading: Icon(LucideIcons.brainCircuit, color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[400] : null), title: const Text('MBTI診断'), subtitle: Text(userProfile.mbti ?? '未設定'), trailing: Icon(LucideIcons.chevronRight, color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[600] : null), onTap: () => _showMbtiDialog(context, userProfile.mbti), ), const Divider(height: 1), ListTile( leading: Icon(LucideIcons.calendar, color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[400] : null), title: const Text('生年月日'), subtitle: Text(userProfile.birthdate != null ? DateFormat('yyyy/MM/dd').format(userProfile.birthdate!) : '未設定 (四柱推命用)'), trailing: Icon(LucideIcons.chevronRight, color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[600] : null), onTap: () => _pickBirthDate(context, userProfile.birthdate), ), ], ), ), const SizedBox(height: 24), // App Settings const AppearanceSettingsSection(), const SizedBox(height: 24), // other Settings const OtherSettingsSection( title: 'データ・その他', ), const SizedBox(height: 24), BackupSettingsSection(), // Roadmap Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primaryContainer.withValues(alpha: 0.1), // Lighter background borderRadius: BorderRadius.circular(12), border: Border.all( color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.2), ), ), child: Row( children: [ Icon(LucideIcons.heartHandshake, color: Theme.of(context).colorScheme.onSurface), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Future Update', style: Theme.of(context).textTheme.labelSmall?.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface, ), ), const SizedBox(height: 4), const Text('カップル共有機能 (開発中)'), ], ), ), ], ), ), const SizedBox(height: 40), ], ), ); } Widget _buildSectionHeader(String title, IconData icon) { final isDark = Theme.of(context).brightness == Brightness.dark; return Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), child: Row( children: [ Icon(icon, size: 20, color: isDark ? Colors.orange[300] : Theme.of(context).primaryColor), const SizedBox(width: 8), Text( title, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: isDark ? Colors.grey[300] : Theme.of(context).primaryColor, ), ), ], ), ); } void _showMbtiDialog(BuildContext context, String? current) { const typesWithLabels = { 'INTJ': '建築家', 'INTP': '論理学者', 'ENTJ': '指揮官', 'ENTP': '討論者', 'INFJ': '提唱者', 'INFP': '仲介者', 'ENFJ': '主人公', 'ENFP': '広報運動家', 'ISTJ': '管理者', 'ISFJ': '擁護者', 'ESTJ': '幹部', 'ESFJ': '領事官', 'ISTP': '巨匠', 'ISFP': '冒険家', 'ESTP': '起業家', 'ESFP': 'エンターテイナー', }; showDialog( context: context, builder: (context) => SimpleDialog( title: const Text('MBTI タイプ選択'), children: [ SizedBox( width: double.maxFinite, height: 400, child: ListView( children: typesWithLabels.entries.map((entry) => SimpleDialogOption( onPressed: () { ref.read(userProfileProvider.notifier).setIdentity(mbti: entry.key); Navigator.pop(context); }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( children: [ Icon( entry.key == current ? Icons.check : Icons.circle_outlined, size: 20, color: entry.key == current ? Theme.of(context).primaryColor : Colors.grey[400], ), const SizedBox(width: 16), Expanded( child: RichText( text: TextSpan( style: DefaultTextStyle.of(context).style.copyWith(fontSize: 16), children: [ TextSpan( text: entry.key, style: const TextStyle(fontWeight: FontWeight.bold), ), TextSpan( text: ' (${entry.value})', style: TextStyle( fontSize: 14, color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[500] : Colors.grey[600], ), ), ], ), ), ), ], ), ), )).toList(), ), ), const Padding( padding: EdgeInsets.all(16.0), child: Text( '※AIによる独自の相性診断です。遊び心としてお楽しみください', style: TextStyle(fontSize: 10, color: Colors.grey), textAlign: TextAlign.center, ), ), ], ), ); } Future _pickBirthDate(BuildContext context, DateTime? current) async { final picked = await showDatePicker( context: context, initialDate: current ?? DateTime(2000), firstDate: DateTime(1900), lastDate: DateTime.now(), locale: const Locale('ja'), // Ensure Japanese locale if initialized ); if (picked != null) { ref.read(userProfileProvider.notifier).setIdentity(birthdate: picked); } } }