import {FC, ReactNode, useEffect, useState} from "react";
import {TaskStatus} from "../../shared/enums/TaskStatus";
import usePollingEffect from "../../hooks/usePollingEffect.tsx";
import {RootState, useAppDispatch} from "../../redux/store.ts";
import {useSelector} from "react-redux";
import {TaskService} from "../../client";
import {addTask, failTask, successTask, Task} from "../../features/tasksSlice.tsx";

type Props = {
    children: ReactNode;
};

const POLLING_STATUSES = [
    TaskStatus.RETRY,
    TaskStatus.STARTED,
    TaskStatus.PENDING,
] as string[];

const TasksProvider: FC<Props> = ({children}) => {
    const [isPooling, setIsPooling] = useState(false);
    const tasks = useSelector((state: RootState) => state.tasks.tasks);
    const notificationTaskMap = useSelector((state: RootState) => state.tasks.notificationTaskMap);
    const dispatch = useAppDispatch();
    const poolTasks = async () => {
        // get statuses of all tasks
        const taskInfos = await Promise.all(
            tasks.map((task) => TaskService.getTaskInfo({taskId: task.id}))
        );
        taskInfos.forEach(({taskId, status}) => {
            if (POLLING_STATUSES.includes(status)) return;
            const task = tasks.find((task) => task.id === taskId);
            if (!task) return;
            if (status === TaskStatus.FAILURE) {
                dispatch(failTask(task));
            } else if (status === TaskStatus.SUCCESS) {
                dispatch(successTask(task));
            }
        })
    }

    usePollingEffect(
        poolTasks,
        [tasks, notificationTaskMap, isPooling],
        {interval: 1000, isActive: isPooling && tasks.length > 0}
    )
    useEffect(() => {
        if (tasks.length === 0) {
            setIsPooling(false);
            return
        }
        setIsPooling(true);
    }, [tasks]);
    useEffect(() => {
        // loading from localstorage
        const tasks = JSON.parse(localStorage.getItem("tasks") || "[]");
        tasks.forEach((task: Task) => {
            dispatch(addTask(task));
        });
    }, []);
    return <>
        {children}
    </>;
};

export default TasksProvider;