import 'package:cloud_firestore/cloud_firestore.dart'; import '../models/task_model.dart'; import '../models/project_model.dart'; import '../models/mind_map_model.dart'; import '../models/calendar_event_model.dart'; import '../models/alarm_model.dart'; import '../models/user_model.dart'; class FirestoreService { final FirebaseFirestore _db = FirebaseFirestore.instance; // === USERS === Future createUser(UserModel user) async { await _db.collection('users').doc(user.id).set(user.toFirestore()); } Future getUser(String userId) async { final doc = await _db.collection('users').doc(userId).get(); return doc.exists ? UserModel.fromFirestore(doc) : null; } Future updateUser(UserModel user) async { await _db.collection('users').doc(user.id).update(user.toFirestore()); } Stream watchUser(String userId) { return _db.collection('users').doc(userId).snapshots().map((doc) { return doc.exists ? UserModel.fromFirestore(doc) : null; }); } // === PROJECTS === Future createProject(ProjectModel project) async { await _db.collection('projects').doc(project.id).set(project.toFirestore()); } Future> getProjectsByTeam(String teamId) async { final snapshot = await _db .collection('projects') .where('teamId', isEqualTo: teamId) .orderBy('createdAt', descending: true) .get(); return snapshot.docs.map((doc) => ProjectModel.fromFirestore(doc)).toList(); } Future> getProjectsByUser(String userId) async { final snapshot = await _db .collection('projects') .where('memberIds', arrayContains: userId) .get(); return snapshot.docs.map((doc) => ProjectModel.fromFirestore(doc)).toList(); } Stream> watchProjectsByUser(String userId) { return _db .collection('projects') .where('memberIds', arrayContains: userId) .snapshots() .map((snapshot) => snapshot.docs .map((doc) => ProjectModel.fromFirestore(doc)) .toList()); } // === TASKS === Future createTask(TaskModel task) async { await _db.collection('tasks').doc(task.id).set(task.toFirestore()); } Future> getTasksByProject(String projectId) async { final snapshot = await _db .collection('tasks') .where('projectId', isEqualTo: projectId) .orderBy('createdAt', descending: true) .get(); return snapshot.docs.map((doc) => TaskModel.fromFirestore(doc)).toList(); } Future> getTasksByAssignee(String assigneeId) async { final snapshot = await _db .collection('tasks') .where('assigneeId', isEqualTo: assigneeId) .where('status', whereIn: ['todo', 'inProgress', 'review']).get(); return snapshot.docs.map((doc) => TaskModel.fromFirestore(doc)).toList(); } Future> getAllTasks() async { final snapshot = await _db .collection('tasks') .orderBy('createdAt', descending: true) .get(); return snapshot.docs.map((doc) => TaskModel.fromFirestore(doc)).toList(); } Future updateTask(TaskModel task) async { await _db.collection('tasks').doc(task.id).update(task.toFirestore()); } Future deleteTask(String taskId) async { await _db.collection('tasks').doc(taskId).delete(); } // Задачи с поддержкой иерархии (для mind-map) Future> getTaskHierarchy(String projectId) async { final snapshot = await _db .collection('tasks') .where('projectId', isEqualTo: projectId) .get(); return snapshot.docs.map((doc) => TaskModel.fromFirestore(doc)).toList(); } // Поток задач для реального времени Stream> watchTasks(String? projectId) { Query query = _db.collection('tasks'); if (projectId != null && projectId.isNotEmpty) { query = query.where('projectId', isEqualTo: projectId); } return query.orderBy('createdAt', descending: true).snapshots().map( (snapshot) => snapshot.docs.map((doc) => TaskModel.fromFirestore(doc)).toList()); } // === MIND MAPS === Future createMindMapNode(MindMapNode node) async { await _db .collection('mindmaps') .doc(node.projectId) .collection('nodes') .doc(node.id) .set(node.toFirestore()); } Future> getMindMapNodes(String projectId) async { final snapshot = await _db .collection('mindmaps') .doc(projectId) .collection('nodes') .orderBy('level') .get(); return snapshot.docs.map((doc) => MindMapNode.fromFirestore(doc)).toList(); } Future updateMindMapNode(MindMapNode node) async { await _db .collection('mindmaps') .doc(node.projectId) .collection('nodes') .doc(node.id) .update(node.toFirestore()); } Future deleteMindMapNode(String projectId, String nodeId) async { await _db .collection('mindmaps') .doc(projectId) .collection('nodes') .doc(nodeId) .delete(); } // === CALENDAR EVENTS === Future createEvent(CalendarEventModel event) async { await _db.collection('events').doc(event.id).set(event.toFirestore()); } Future> getEventsByDateRange({ required DateTime start, required DateTime end, String? userId, }) async { Query query = _db .collection('events') .where('startTime', isLessThanOrEqualTo: Timestamp.fromDate(end)) .where('endTime', isGreaterThanOrEqualTo: Timestamp.fromDate(start)); if (userId != null) { query = query.where('attendeeIds', arrayContains: userId); } final snapshot = await query.get(); return snapshot.docs .map((doc) => CalendarEventModel.fromFirestore(doc)) .toList(); } Future updateEvent(CalendarEventModel event) async { await _db.collection('events').doc(event.id).update(event.toFirestore()); } Future deleteEvent(String eventId) async { await _db.collection('events').doc(eventId).delete(); } Stream> watchEvents(String userId) { return _db .collection('events') .where('attendeeIds', arrayContains: userId) .orderBy('startTime') .snapshots() .map((snapshot) => snapshot.docs .map((doc) => CalendarEventModel.fromFirestore(doc)) .toList()); } // === ALARMS === Future createAlarm(AlarmModel alarm) async { await _db.collection('alarms').doc(alarm.id).set(alarm.toFirestore()); } Future> getAlarmsByUser(String userId) async { final snapshot = await _db .collection('alarms') .where('isEnabled', isEqualTo: true) .orderBy('dateTime') .get(); return snapshot.docs.map((doc) => AlarmModel.fromFirestore(doc)).toList(); } Future updateAlarm(AlarmModel alarm) async { await _db.collection('alarms').doc(alarm.id).update(alarm.toFirestore()); } Future deleteAlarm(String alarmId) async { await _db.collection('alarms').doc(alarmId).delete(); } // === BATCH OPERATIONS === Future syncTasks(List tasks) async { final batch = _db.batch(); for (final task in tasks) { batch.set(_db.collection('tasks').doc(task.id), task.toFirestore()); } await batch.commit(); } // === TEAMS === Future createTeam(String teamId, String name, String ownerId) async { await _db.collection('teams').doc(teamId).set({ 'name': name, 'ownerId': ownerId, 'memberIds': [ownerId], 'createdAt': Timestamp.now(), 'updatedAt': Timestamp.now(), }); } Future addTeamMember(String teamId, String userId) async { await _db.collection('teams').doc(teamId).update({ 'memberIds': FieldValue.arrayUnion([userId]), 'updatedAt': Timestamp.now(), }); } Future removeTeamMember(String teamId, String userId) async { await _db.collection('teams').doc(teamId).update({ 'memberIds': FieldValue.arrayRemove([userId]), 'updatedAt': Timestamp.now(), }); } Stream>> watchTeamMembers(String teamId) { return _db.collection('teams').doc(teamId).snapshots().map((doc) { if (!doc.exists) return []; final data = doc.data() as Map; return List>.from(data['memberIds'] ?? []); }); } } final firestoreService = FirestoreService();