// public/js/services/taskService.js import eventBus from '../utils/eventBus.js'; import { db, appId } from '../firebase-init.js'; // Import db, appId // --- Hàm cho collection Tasks --- export async function getTasks() { console.log('taskService: getTasks called'); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: getTasks - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { // Example: Get all tasks, you might want to add filtering/ordering later const snapshot = await db.collection('artifacts').doc(appId).collection('tasks').get(); // Sử dụng db, appId đã import const tasks = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); console.log('taskService: getTasks - Fetched', tasks.length, 'tasks'); return tasks; } catch (error) { console.error('taskService: Error getting tasks:', error); throw error; } } /** * Fetches all comments for a given task from Firestore. * @param {string} taskId - The ID of the task to get comments for. * @returns {Promise>} A promise that resolves with an array of comment data objects.\n */ export async function getTaskCommentsFromService(taskId) { // Renamed to avoid conflict console.log('taskService: getTaskCommentsFromService called for taskId', taskId); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: Firebase or appId not initialized.'); throw new Error('Firebase not initialized.'); } try { const snapshot = await db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments').orderBy('createdAt').get(); // Sử dụng db, appId đã import // --- Thêm log chi tiết tại đây --- console.log('taskService: getTaskCommentsFromService - RAW Snapshot:', snapshot); // Log toàn bộ snapshot object console.log('taskService: getTaskCommentsFromService - Snapshot empty:', snapshot.empty); // Kiểm tra snapshot rỗng console.log('taskService: getTaskCommentsFromService - Snapshot size:', snapshot.size); // Kiểm tra kích thước snapshot if (!snapshot.empty) { console.log('taskService: getTaskCommentsFromService - Snapshot docs:', snapshot.docs); // Log mảng các DocumentSnapshot snapshot.docs.forEach((doc, index) => { console.log(`taskService: getTaskCommentsFromService - Doc ${index} ID:`, doc.id); console.log(`taskService: getTaskCommentsFromService - Doc ${index} Data:`, doc.data()); console.log(`taskService: getTaskCommentsFromService - Doc ${index} Exists:`, doc.exists); // Kiểm tra tài liệu có tồn tại không }); } // --- Kết thúc log chi tiết --- const comments = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); console.log('taskService: getTaskCommentsFromService successful. Found', comments.length, 'comments.'); return comments; } catch (error) { console.error('taskService: getTaskCommentsFromService error:', error); throw error; } } /** * Creates a new comment for a given task in Firestore. * @param {string} taskId - The ID of the task the comment belongs to.\n * @param {object} commentData - The data for the new comment (e.g., text, userId, timestamp).\n * @returns {Promise} A promise that resolves with the new comment data object including ID.\n */ export async function createCommentForTask(taskId, commentData) { // Renamed console.log('taskService: createCommentForTask called for taskId', taskId, 'with data', commentData); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: Firebase or appId not initialized.'); throw new Error('Firebase not initialized.'); } try { const commentsCollectionRef = db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments'); // Sử dụng db, appId đã import const docRef = await commentsCollectionRef.add(commentData); const newCommentSnapshot = await docRef.get(); const newCommentData = { id: newCommentSnapshot.id, ...newCommentSnapshot.data() }; console.log('taskService: createCommentForTask successful. New comment:', newCommentData); return newCommentData; } catch (error) { console.error('taskService: createCommentForTask error:', error); throw error; } } /** * Updates an existing comment in Firestore. * @param {string} taskId - The ID of the task the comment belongs to. * @param {string} commentId - The ID of the comment to update. * @param {object} updateData - The data to update (e.g., { text: 'new text' }).\n * @returns {Promise} A promise that resolves when the update is complete.\n */ export async function updateTaskComment(taskId, commentId, updateData) { console.log('taskService: updateTaskComment called for taskId', taskId, 'commentId', commentId, 'with data', updateData); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: Firebase or appId not initialized.'); throw new Error('Firebase not initialized.'); } try { const commentDocRef = db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments').doc(commentId); // Sử dụng db, appId đã import await commentDocRef.update(updateData); console.log('taskService: updateTaskComment successful for commentId', commentId); // Return void or success status } catch (error) { console.error('taskService: updateTaskComment error:', error); throw error; } } /** * Deletes a comment from Firestore. * @param {string} taskId - The ID of the task the comment belongs to. * @param {string} commentId - The ID of the comment to delete. * @returns {Promise} A promise that resolves when the deletion is complete.\n */ export async function deleteTaskComment(taskId, commentId) { // Renamed console.log('taskService: deleteTaskComment called for taskId', taskId, 'commentId', commentId); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: Firebase or appId not initialized.'); throw new Error('Firebase not initialized.'); } try { const commentDocRef = db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments').doc(commentId); // Sử dụng db, appId đã import await commentDocRef.delete(); console.log('taskService: deleteTaskComment successful for taskId', taskId, 'commentId', commentId); } catch (error) { console.error('taskService: deleteTaskComment error:', error); throw error; } } export async function createTask(taskData) { console.log('taskService: createTask called with data', taskData); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: createTask - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { taskData.createdAt = firebase.firestore.FieldValue.serverTimestamp(); // Giữ lại FieldValue nếu Firebase compat được load toàn cục const docRef = await db.collection('artifacts').doc(appId).collection('tasks').add(taskData); // Sử dụng db, appId đã import const newTask = { id: docRef.id, ...taskData }; console.log('taskService: createTask - Task created with ID:', docRef.id);eventBus.publish('taskCreated', newTask); // Publish event return newTask; } catch (error) { console.error('taskService: Error creating task:', error); throw error; } } export async function updateTask(taskId, taskData) { console.log('taskService: updateTask called for ID', taskId, 'with data', taskData); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: updateTask - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { await db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).update(taskData); // Sử dụng db, appId đã import const updatedTask = { id: taskId, ...taskData };console.log('taskService: updateTask - Task updated successfully'); eventBus.publish('taskUpdated', updatedTask); // Publish event return updatedTask; } catch (error) { console.error('taskService: Error updating task:', error); throw error; } } export async function deleteTask(taskId) { console.log('taskService: deleteTask called for ID', taskId); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: deleteTask - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { await db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).delete(); // Sử dụng db, appId đã import eventBus.publish('taskDeleteCompleted', taskId); // Publish event console.log('taskService: deleteTask - Task deleted successfully'); return taskId; } catch (error) { console.error('taskService: Error deleting task:', error); throw error; } } // --- Hàm cho subcollection Comments --- export async function getTaskComments(taskId) { console.log('taskService: getTaskComments called for Task ID', taskId); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: getTaskComments - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { console.log('taskService: getTaskComments - Using appId:', appId, 'and taskId:', taskId); console.log('taskService: getTaskComments - Firestore path:', `artifacts/${appId}/tasks/${taskId}/comments`); const snapshot = await db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments').orderBy('createdAt').get(); // Sử dụng db, appId đã import // --- Thêm log chi tiết tại đây --- console.log('taskService: getTaskComments - RAW Snapshot:', snapshot); // Log toàn bộ snapshot object console.log('taskService: getTaskComments - Snapshot empty:', snapshot.empty); // Kiểm tra snapshot rỗng console.log('taskService: getTaskComments - Snapshot size:', snapshot.size); // Kiểm tra kích thước snapshot if (!snapshot.empty) { console.log('taskService: getTaskComments - Snapshot docs:', snapshot.docs); // Log mảng các DocumentSnapshot snapshot.docs.forEach((doc, index) => { console.log(`taskService: getTaskComments - Doc ${index} ID:`, doc.id); console.log(`taskService: getTaskComments - Doc ${index} Data:`, doc.data()); console.log(`taskService: getTaskComments - Doc ${index} Exists:`, doc.exists); // Kiểm tra tài liệu có tồn tại không }); } // --- Kết thúc log chi tiết --- const comments = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); console.log('taskService: getTaskComments - Fetched', comments.length, 'comments for Task ID', taskId); console.log('taskService: getTaskComments - Fetched comments data:', comments); return comments; } catch (error) { console.error('taskService: Error getting comments for Task ID', taskId, ':', error); throw error; } } export async function addCommentToTask(taskId, commentData) { console.log('taskService: addCommentToTask called for Task ID', taskId, 'with data', commentData); // const db = firebase.firestore(); // Removed // const appId = firebase.app().options.appId; // Removed if (!db || !appId) { // Sử dụng db, appId đã import console.error('taskService: addCommentToTask - Firebase or appId not initialized.'); throw new Error('Firebase or App ID not available.'); } try { const docRef = await db.collection('artifacts').doc(appId).collection('tasks').doc(taskId).collection('comments').add(commentData); // Sử dụng db, appId đã import console.log('taskService: addCommentToTask - Comment added with ID:', docRef.id); const newCommentSnapshot = await docRef.get(); const newCommentData = { id: newCommentSnapshot.id, ...newCommentSnapshot.data() }; console.log('taskService: addCommentToTask - Fetched new comment data:', newCommentData); return newCommentData; // Change return value } catch (error) { console.error('taskService: Error adding comment to Task ID', taskId, ':', error); throw error; } } // Note: Soft delete is handled in the comments.js file by calling this updateTaskComment // function with { deleted: true, ... }. You could also create a dedicated softDeleteTaskComment // function here if preferred.