import 'package:flutter/material.dart'; import 'package:drift/drift.dart'; import 'package:trainhub_flutter/database/database.dart'; class ChatProvider extends ChangeNotifier { final AppDatabase database; List _sessions = []; List _currentMessages = []; ChatSession? _activeSession; List get sessions => _sessions; List get currentMessages => _currentMessages; ChatSession? get activeSession => _activeSession; bool _isTyping = false; bool get isTyping => _isTyping; ChatProvider(this.database) { _loadSessions(); } Future _loadSessions() async { _sessions = await (database.select(database.chatSessions)..orderBy([ (t) => OrderingTerm( expression: t.createdAt, mode: OrderingMode.desc, ), ])) .get(); notifyListeners(); } Future createSession() async { final id = DateTime.now().toIso8601String(); final session = ChatSessionsCompanion.insert( id: id, title: const Value('New Chat'), createdAt: DateTime.now().toIso8601String(), updatedAt: DateTime.now().toIso8601String(), ); await database.into(database.chatSessions).insert(session); await _loadSessions(); await loadSession(id); } Future deleteSession(String id) async { await (database.delete( database.chatSessions, )..where((t) => t.id.equals(id))).go(); if (_activeSession?.id == id) { _activeSession = null; _currentMessages = []; } await _loadSessions(); } Future loadSession(String id) async { final session = await (database.select( database.chatSessions, )..where((t) => t.id.equals(id))).getSingleOrNull(); if (session != null) { _activeSession = session; await _loadMessages(id); } } Future _loadMessages(String sessionId) async { _currentMessages = await (database.select(database.chatMessages) ..where((t) => t.sessionId.equals(sessionId)) ..orderBy([ (t) => OrderingTerm( expression: t.createdAt, mode: OrderingMode.asc, ), ])) .get(); notifyListeners(); } Future sendMessage(String content) async { if (_activeSession == null) { await createSession(); } final sessionId = _activeSession!.id; // User Message final userMsgId = DateTime.now().toIso8601String(); await database .into(database.chatMessages) .insert( ChatMessagesCompanion.insert( id: userMsgId, sessionId: sessionId, role: 'user', content: content, createdAt: DateTime.now().toIso8601String(), ), ); await _loadMessages(sessionId); // AI Response (Mock) _isTyping = true; notifyListeners(); await Future.delayed(const Duration(seconds: 1)); // Simulate latency final aiMsgId = DateTime.now().toIso8601String(); final response = _getMockResponse(content); await database .into(database.chatMessages) .insert( ChatMessagesCompanion.insert( id: aiMsgId, sessionId: sessionId, role: 'assistant', content: response, createdAt: DateTime.now().toIso8601String(), ), ); // Update session title if it's the first message if (_currentMessages.length <= 2) { final newTitle = content.length > 30 ? '${content.substring(0, 30)}...' : content; await (database.update(database.chatSessions) ..where((t) => t.id.equals(sessionId))) .write(ChatSessionsCompanion(title: Value(newTitle))); await _loadSessions(); } _isTyping = false; await _loadMessages(sessionId); } String _getMockResponse(String input) { input = input.toLowerCase(); if (input.contains('plan') || input.contains('program')) { return "I can help you design a training plan! What are your goals? Strength, hypertrophy, or endurance?"; } else if (input.contains('squat') || input.contains('bench')) { return "Compound movements are great. Remember to maintain proper form. For squats, keep your chest up and knees tracking over toes."; } else if (input.contains('nutrition') || input.contains('eat')) { return "Nutrition is key. Aim for 1.6-2.2g of protein per kg of bodyweight if you're training hard."; } return "I'm your AI training assistant. How can I help you today?"; } }