import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/auth/auth_notifier.dart'; import '../../core/chat/active_session_notifier.dart'; import '../../core/pairing/pairing_notifier.dart'; import '../chat/widgets/pricing_bottom_sheet.dart'; import '../chat/widgets/topic_selection_bottom_sheet.dart'; class HomeScreen extends ConsumerStatefulWidget { const HomeScreen({super.key}); @override ConsumerState createState() => _HomeScreenState(); } class _HomeScreenState extends ConsumerState with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { // Re-fetch in case a session ended/started while backgrounded. ref.read(activeSessionProvider.notifier).refresh(); } } Future _onStartChatPressed(BuildContext context) async { final topic = await TopicSelectionBottomSheet.show(context); if (topic == null || !context.mounted) return; await PricingBottomSheet.show(context, topicSensitivity: topic); } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); final authData = authState.valueOrNull; final activeSessionAsync = ref.watch(activeSessionProvider); final displayName = switch (authData) { AuthAuthenticatedData d => d.profile['display_name'] as String? ?? '', AuthAnonymousData d => d.displayName, _ => '', }; ref.listen(pairingProvider, (prev, next) { if (next is PairingSearchingData) { context.go('/chat/searching'); } else if (next is PairingNoBestieData) { context.go('/chat/no-bestie'); } else if (next is PairingErrorData) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(next.message)), ); } }); return Scaffold( appBar: AppBar( title: const Text('Halo Bestie'), actions: [ IconButton( icon: const Icon(Icons.history), onPressed: () => context.push('/chat/history'), ), IconButton( icon: const Icon(Icons.logout), onPressed: () => ref.read(authProvider.notifier).logout(), ), ], ), body: Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Halo, $displayName!', style: const TextStyle(fontSize: 24)), const SizedBox(height: 32), activeSessionAsync.when( loading: () => const CircularProgressIndicator(), error: (_, __) => _StartChatButton(onPressed: () => _onStartChatPressed(context)), data: (snapshot) { // Hide the "Sesi Aktif" CTA when the session is in `closing` // — the conversation is over, only the goodbye composer // remains. Backend auto-completes such sessions after a // grace period; until then the user shouldn't be invited // back into them from home. final status = snapshot.session?['status'] as String?; final isCurhatable = snapshot.hasSession && status != 'closing'; if (isCurhatable) { return _ActiveSessionCard( mitraName: snapshot.mitraName, unreadCount: snapshot.unreadCount, onTap: () { final sessionId = snapshot.sessionId; if (sessionId == null) return; context.push('/chat/session/$sessionId', extra: snapshot.mitraName); }, ); } return _StartChatButton(onPressed: () => _onStartChatPressed(context)); }, ), ], ), ), ), ); } } class _StartChatButton extends StatelessWidget { final VoidCallback onPressed; const _StartChatButton({required this.onPressed}); @override Widget build(BuildContext context) { return Column( children: [ const SizedBox(height: 16), ElevatedButton( style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 48, vertical: 16), ), onPressed: onPressed, child: const Text('Mulai Curhat', style: TextStyle(fontSize: 18)), ), ], ); } } class _ActiveSessionCard extends StatelessWidget { final String mitraName; final int unreadCount; final VoidCallback onTap; const _ActiveSessionCard({ required this.mitraName, required this.unreadCount, required this.onTap, }); @override Widget build(BuildContext context) { return Card( elevation: 2, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(20), child: Row( children: [ Badge( isLabelVisible: unreadCount > 0, label: Text('$unreadCount'), child: const CircleAvatar( backgroundColor: Colors.green, child: Icon(Icons.chat, color: Colors.white), ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Sesi Aktif', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( 'Sedang curhat dengan $mitraName', style: const TextStyle(fontSize: 14, color: Colors.grey), ), ], ), ), const Icon(Icons.chevron_right), ], ), ), ), ); } }