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";
import assign from "@react-native-community/cli-config/build/assign";

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];

export const getNextDailyDates = (date, includeToday) => {
    const today = new Date();
    const dates = [];

    for (let weekOffset = 0; weekOffset < 52; weekOffset++) {
        const targetDate = addWeeks(date, weekOffset);

        if (includeToday) {
            dates.push(targetDate);
        } else {
            if (targetDate > today) {
                dates.push(targetDate);
            }
        }
    }

    return dates;
};

export const getNextWeeklyDates = (selectedDays, date) => {
    const today = new Date();
    const currentDay = date.getDay();
    const dates = [];

    for (let week = 0; week < 52; 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;
};

export const getNextMonthlyDates = (date, includeToday) => {
    const today = new Date();
    const dates = [];

    for (let monthOffset = 0; monthOffset < 12; monthOffset++) {
        const targetDate = addMonths(date, monthOffset);
        if (includeToday) {
            dates.push(targetDate);
        } else {
            if (targetDate > today) {
                dates.push(targetDate);
            }
        }
    }

    return dates;
};

export const getNextYearlyDates = (date, includeToday) => {
    const today = new Date();
    const dates = [];

    for (let yearOffset = 0; yearOffset < 5; yearOffset++) {
        const nextYear = addYears(date, yearOffset);
        if (includeToday) {
            dates.push(nextYear);
        } else {
            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<IToDo>) => {
            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, false);
                    } 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, false);
                    } else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
                        nextDates = getNextYearlyDates(todoData.date, false);
                    }

                    const todosRef = firestore().collection("Todos");
                    const ruleDocRef = todosRef.doc();
                    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 + 1) % todoData.assignees.length];
                            }

                            const nextTodo = {
                                ...todoData,
                                date: date,
                                id: newDocRef.id,
                                familyId: profileData?.familyId,
                                creatorId: currentUser?.uid,
                                connectedTodoId: ruleDocRef.id,
                                assignees: todoData.assignees,
                                currentAssignee: assignee
                            }

                            batch.set(newDocRef, nextTodo)
                        }
                    );

                    await batch.commit();
                }
            } catch (e) {
                console.error(e)
            }
        },
        onSuccess: () => {
            queryClients.invalidateQueries({queryKey: ["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;
}