import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:provider/provider.dart'; import '../providers/chat_provider.dart'; import '../widgets/message_bubble.dart'; import '../widgets/typing_indicator.dart'; import '../widgets/chat_input.dart'; class ChatScreen extends StatefulWidget { const ChatScreen({super.key}); @override State createState() => _ChatScreenState(); } class _ChatScreenState extends State { final ScrollController _scrollController = ScrollController(); void _scrollToBottom() { if (_scrollController.hasClients) { Future.delayed(const Duration(milliseconds: 100), () { _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, ); }); } } @override Widget build(BuildContext context) { return ScaffoldPage( header: PageHeader( title: Row( children: [ Container( width: 32, height: 32, decoration: BoxDecoration( color: FluentTheme.of(context).accentColor, borderRadius: BorderRadius.circular(8), ), child: const Icon( FluentIcons.robot, color: Colors.white, size: 18, ), ), const SizedBox(width: 12), const Text('AI Chat'), ], ), commandBar: CommandBar( mainAxisAlignment: MainAxisAlignment.end, primaryItems: [ CommandBarButton( icon: const Icon(FluentIcons.add), label: const Text('New Chat'), onPressed: () { context.read().clearMessages(); }, ), ], ), ), content: Column( children: [ Expanded(child: _buildMessageList()), _buildInputArea(), ], ), ); } Widget _buildMessageList() { return Consumer( builder: (context, chatProvider, child) { final messages = chatProvider.messages; final isTyping = chatProvider.isTyping; final currentResponse = chatProvider.currentAiResponse; WidgetsBinding.instance.addPostFrameCallback((_) { _scrollToBottom(); }); if (messages.isEmpty && !isTyping) { return _buildEmptyState(); } return ListView.builder( controller: _scrollController, padding: const EdgeInsets.all(16), itemCount: messages.length + (isTyping ? 1 : 0), itemBuilder: (context, index) { if (index == messages.length && isTyping) { if (currentResponse.isNotEmpty) { return _buildTypingResponse(currentResponse); } return const TypingIndicator(); } return MessageBubble(message: messages[index], showAvatar: true); }, ); }, ); } Widget _buildTypingResponse(String content) { final theme = FluentTheme.of(context); return Padding( padding: const EdgeInsets.only(bottom: 16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 36, height: 36, decoration: BoxDecoration( color: theme.accentColor, borderRadius: BorderRadius.circular(8), ), child: const Icon(FluentIcons.robot, color: Colors.white, size: 18), ), const SizedBox(width: 12), Flexible( child: Card( padding: const EdgeInsets.all(12), child: MarkdownBody( data: content, styleSheet: MarkdownStyleSheet( p: theme.typography.body, h1: theme.typography.title, h2: theme.typography.subtitle, h3: theme.typography.bodyLarge, code: TextStyle( fontFamily: 'Consolas', backgroundColor: theme.cardColor, ), ), ), ), ), const SizedBox(width: 48), ], ), ); } Widget _buildEmptyState() { final theme = FluentTheme.of(context); return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 80, height: 80, decoration: BoxDecoration( color: theme.accentColor, borderRadius: BorderRadius.circular(20), ), child: const Icon(FluentIcons.robot, color: Colors.white, size: 40), ), const SizedBox(height: 24), Text('Hello! I\'m your AI Assistant', style: theme.typography.title), const SizedBox(height: 12), Text( 'How can I help you today?', style: theme.typography.body?.copyWith( color: theme.typography.body?.color?.withAlpha(180), ), ), const SizedBox(height: 32), _buildSuggestionChips(), ], ), ); } Widget _buildSuggestionChips() { final suggestions = [ 'Write a poem', 'Explain quantum computing', 'Help me code', 'Translate to English', ]; return Wrap( spacing: 8, runSpacing: 8, alignment: WrapAlignment.center, children: suggestions.map((suggestion) { return Button( onPressed: () { context.read().sendMessage(suggestion); }, child: Text(suggestion), ); }).toList(), ); } Widget _buildInputArea() { return Consumer( builder: (context, chatProvider, child) { return ChatInput( onSend: (message) { chatProvider.sendMessage(message); }, enabled: !chatProvider.isTyping, ); }, ); } @override void dispose() { _scrollController.dispose(); super.dispose(); } }