import { useMutation, useQueryClient } from "@tanstack/react-query"; import firestore from "@react-native-firebase/firestore"; import { useAuthContext } from "@/contexts/AuthContext"; import { DAYS_OF_WEEK_ENUM, IToDo, REPEAT_TYPE } from "@/hooks/firebase/types/todoData"; import { addMonths, addWeeks, addYears } from "date-fns"; export const daysOfWeek = [ DAYS_OF_WEEK_ENUM.MONDAY, DAYS_OF_WEEK_ENUM.TUESDAY, DAYS_OF_WEEK_ENUM.WEDNESDAY, DAYS_OF_WEEK_ENUM.THURSDAY, DAYS_OF_WEEK_ENUM.FRIDAY, DAYS_OF_WEEK_ENUM.SATURDAY, DAYS_OF_WEEK_ENUM.SUNDAY]; const getNextDailyDates = (date) => { const today = new Date(); const dates = []; for (let weekOffset = 0; weekOffset < 2; weekOffset++) { const targetDate = addWeeks(date, weekOffset); if (targetDate > today) { dates.push(targetDate); } } return dates; }; const getNextWeeklyDates = (selectedDays, date) => { const today = new Date(); const currentDay = date.getDay(); const dates = []; for (let week = 0; week < 2; week++) { selectedDays.forEach((day) => { const targetDay = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].indexOf(day); const diff = (targetDay - currentDay + 7) % 7 + week * 7; // Move to the next week const nextDate = new Date(today); nextDate.setDate(date.getDate() + diff); dates.push(nextDate); }); } return dates; }; const getNextMonthlyDates = (date) => { const today = new Date(); const dates = []; for (let monthOffset = 0; monthOffset < 12; monthOffset++) { const targetDate = addMonths(date, monthOffset); if (targetDate > today) { dates.push(targetDate); } } return dates; }; const getNextYearlyDates = (date) => { const today = new Date(); const dates = []; for (let yearOffset = 0; yearOffset < 5; yearOffset++) { const nextYear = addYears(date, yearOffset); if (nextYear > today) { dates.push(nextYear); } } return dates; }; export const useCreateTodo = () => { const { user: currentUser, profileData } = useAuthContext(); const queryClients = useQueryClient(); return useMutation({ mutationKey: ["createTodo"], mutationFn: async (todoData: Partial) => { try { if (todoData.repeatType === REPEAT_TYPE.NONE) { const newDoc = firestore().collection('Todos').doc(); let originalTodo = {...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid} await firestore() .collection("Todos") .add(originalTodo); } else { let nextDates; if (todoData.repeatType === REPEAT_TYPE.DAILY) { nextDates = getNextDailyDates(todoData.date); } else if (todoData.repeatType === REPEAT_TYPE.EVERY_WEEK) { nextDates = getNextWeeklyDates(todoData.repeatDays, todoData.date); } else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_MONTH) { nextDates = getNextMonthlyDates(todoData.date); } else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) { nextDates = getNextYearlyDates(todoData.date); } const todosRef = firestore().collection("Todos"); const ruleDocRef = todosRef.doc(); const ruleDoc = await todosRef.add( {...todoData, id: ruleDocRef.id, familyId: profileData?.familyId, creatorId: currentUser?.uid, connectedTodoId: ruleDocRef.id,} ); const batch = firestore().batch(); nextDates.forEach((date, index) => { const newDocRef = todosRef.doc(); let assignee; if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) { assignee = todoData.assignees[index % todoData.assignees.length]; } const nextTodo = { ...todoData, date: date, id: newDocRef.id, familyId: profileData?.familyId, creatorId: currentUser?.uid, connectedTodoId: ruleDocRef.id, assignees: assignee ? [assignee] : null } batch.set(newDocRef, nextTodo) } ); await batch.commit(); } } catch (e) { console.error(e) } }, onSuccess: () => { queryClients.invalidateQueries("todos") } }) } export const resolveTodoAlternatingAssignees = (todoData, newTodo, i) => { if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) { const assignees = todoData.assignees; const assignee = assignees[i % assignees.length]; newTodo = {...newTodo, assignees: [assignee]}; } return newTodo; }