import {createSlice, PayloadAction} from "@reduxjs/toolkit";
import {notifications} from "../shared/lib/notifications.ts";
import {IconCheck, IconX} from "@tabler/icons-react";
import {rem} from "@mantine/core";

export type TaskData = {
    title: string;
    message: string;
};

export type TaskConfig = {
    onSuccessData: TaskData;
    onErrorData: TaskData;
    onLoadingData: TaskData;
};

export type Task = {
    id: string;
    config: TaskConfig;
    info: Record<string, unknown>;
};

interface TasksState {
    tasks: Task[];
    notificationTaskMap: { [key: string]: string };
}

const initialState: TasksState = {
    tasks: [],
    notificationTaskMap: {},
};

const tasksSlice = createSlice({
    name: "tasks",
    initialState,
    reducers: {
        addTask: (state, action: PayloadAction<Task>) => {
            const task = action.payload;
            state.notificationTaskMap[task.id] = notifications.show({
                loading: true,
                title: task.config.onLoadingData.title,
                message: task.config.onLoadingData.message,
                autoClose: false,
                withCloseButton: false,
                withBorder: true,
                radius: "sm"
            });
            state.tasks.push(task);
            localStorage.setItem("tasks", JSON.stringify(state.tasks));
        },
        removeTask: (state, action: PayloadAction<string>) => {
            state.tasks = state.tasks.filter((task) => task.id !== action.payload);
            localStorage.setItem("tasks", JSON.stringify(state.tasks));
        },
        failTask: (state, action: PayloadAction<Task>) => {
            const task = action.payload;
            const notificationId = state.notificationTaskMap[task.id];

            if (!notificationId) return;
            notifications.update({
                id: notificationId,
                color: 'red',
                title: task.config.onErrorData.title,
                message: task.config.onErrorData.message,
                icon: <IconX style={{width: rem(18), height: rem(18)}}/>,
                loading: false,
                autoClose: 2000,
            })
            state.tasks = state.tasks.filter((task) => task.id !== action.payload.id);
            state.notificationTaskMap = Object.fromEntries(
                Object.entries(state.notificationTaskMap).filter(([taskId]) => taskId !== task.id)
            );
            localStorage.setItem("tasks", JSON.stringify(state.tasks));
        },
        successTask: (state, action: PayloadAction<Task>) => {
            const task = action.payload;
            const notificationId = state.notificationTaskMap[task.id];

            if (!notificationId) return;
            notifications.update({
                id: notificationId,
                color: 'teal',
                title: task.config.onSuccessData.title,
                message: task.config.onSuccessData.message,
                icon: <IconCheck style={{width: rem(18), height: rem(18)}}/>,
                loading: false,
                autoClose: 2000,
            })
            state.tasks = state.tasks.filter((task) => task.id !== action.payload.id);
            state.notificationTaskMap = Object.fromEntries(
                Object.entries(state.notificationTaskMap).filter(([taskId]) => taskId !== task.id)
            );

            localStorage.setItem("tasks", JSON.stringify(state.tasks));
        }
    },
});

export const {addTask, removeTask, successTask, failTask} = tasksSlice.actions;

export default tasksSlice.reducer;