import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:uuid/uuid.dart'; import '../models/mindmap_model.dart'; import '../core/admin_access_service.dart'; import '../core/deepseek_service.dart'; // Provider для получения текущего email пользователя final currentUserEmailProvider = Provider((ref) { return FirebaseAuth.instance.currentUser?.email; }); // Provider проверки является ли пользователь админом final isAdminProvider = Provider((ref) { final email = ref.watch(currentUserEmailProvider); if (email == null) return false; return AdminAccessService.adminEmails.contains(email.toLowerCase()); }); // Provider списка mind maps final mindMapsProvider = StreamProvider>((ref) { return FirebaseFirestore.instance .collection('mind_maps') .orderBy('createdAt', descending: true) .snapshots() .map((snapshot) { return snapshot.docs.map((doc) { return MindMapModel.fromFirestore(doc); }).toList(); }); }); // Notifier для управления mind maps class MindMapsNotifier extends StateNotifier>> { final Ref ref; final FirebaseFirestore _firestore = FirebaseFirestore.instance; final FirebaseAuth _auth = FirebaseAuth.instance; MindMapsNotifier(this.ref) : super(const AsyncValue.loading()) { _listenToMindMaps(); } void _listenToMindMaps() { _firestore .collection('mind_maps') .orderBy('createdAt', descending: true) .snapshots() .listen( (snapshot) { final mindMaps = snapshot.docs.map((doc) { return MindMapModel.fromFirestore(doc); }).toList(); state = AsyncValue.data(mindMaps); }, onError: (error, st) { state = AsyncValue.error(error, st); }, ); } // Создание новой mind map Future createMindMap({ required String title, String description = '', required List> nodes, bool isMain = false, }) async { try { final userEmail = _auth.currentUser?.email ?? 'unknown'; final now = DateTime.now(); final id = const Uuid().v4(); final mindMap = MindMapModel( id: id, title: title, description: description, ownerEmail: userEmail, isMain: isMain, nodes: nodes, createdAt: now, updatedAt: now, ); await _firestore.collection('mind_maps').doc(id).set(mindMap.toFirestore()); return id; } catch (e, st) { state = AsyncValue.error(e, st); rethrow; } } // Удаление mind map (админы могут удалять любые, обычные - только свои) Future deleteMindMap(String id, String ownerEmail) async { try { final isAdmin = ref.read(isAdminProvider); final currentUserEmail = _auth.currentUser?.email ?? ''; // Проверка прав if (!isAdmin && ownerEmail != currentUserEmail) { throw Exception('Нет прав для удаления этой mind map'); } await _firestore.collection('mind_maps').doc(id).delete(); } catch (e, st) { state = AsyncValue.error(e, st); rethrow; } } // Обновление mind map Future updateMindMap(String id, MindMapModel mindMap) async { try { final isAdmin = ref.read(isAdminProvider); final currentUserEmail = _auth.currentUser?.email ?? ''; // Проверка прав if (!isAdmin && mindMap.ownerEmail != currentUserEmail) { throw Exception('Нет прав для редактирования этой mind map'); } await _firestore .collection('mind_maps') .doc(id) .update(mindMap.copyWith(updatedAt: DateTime.now()).toFirestore()); } catch (e, st) { state = AsyncValue.error(e, st); rethrow; } } // AI генерация mind map Future generateWithAI({ required String title, required String description, }) async { try { final nodesData = await deepSeekService.generateMindMap( projectName: title, description: description, ); final nodes = >[]; for (var i = 0; i < nodesData.length; i++) { final nodeData = nodesData[i]; nodes.add({ 'id': 'node_$i', 'level': nodeData['level'] ?? 0, 'parentId': nodeData['parentId'], 'title': nodeData['title'] ?? '', 'color': _getColorForLevel(nodeData['level'] ?? 0), }); } return await createMindMap( title: title, description: description, nodes: nodes, ); } catch (e, st) { state = AsyncValue.error(e, st); rethrow; } } String _getColorForLevel(int level) { final colors = [ '#2196F3', '#4CAF50', '#FF9800', '#E91E63', '#9C27B0', '#00BCD4' ]; return colors[level % colors.length]; } } final mindMapsNotifierProvider = StateNotifierProvider>>( (ref) => MindMapsNotifier(ref), );