import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import { NewsChannel } from "../model/NewsChannel";
import { serverUrl } from "../utils/request";

interface NewsChannelState {
    all: Array<NewsChannel>;
    newsChannel: NewsChannel;
    status: string;
}

const initialState: NewsChannelState = {
    all: [],
    newsChannel: {} as NewsChannel,
    status: "idle",
};

const TIMEOUT = 5000;

export const fetchNewsChannels = createAsyncThunk<
    Array<NewsChannel>
>('newsChannels', async () => {
    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), TIMEOUT);

    const response = await fetch(serverUrl() + '/api/news-channel', { signal: controller.signal });
    clearTimeout(id);

    return (await response.json()).newsChannels as Array<NewsChannel>;
});

export const fetchNewsChannel = createAsyncThunk<
    NewsChannel,
    number
>('newsChannel', async (id: number) => {
    const controller = new AbortController();
    const idTimeout = setTimeout(() => controller.abort(), TIMEOUT);

    const response = await fetch(serverUrl() + `/api/news-channel/${id}`, { signal: controller.signal });
    clearTimeout(idTimeout);

    return (await response.json()).newsChannel as NewsChannel;
});

export const newsChannelSlice = createSlice({
    name: "newsChannel",
    initialState,
    reducers: {
        setAll(state: NewsChannelState, action: PayloadAction<Array<NewsChannel>>) {
            state.all = action.payload;
        },
        setNewsChannel(state: NewsChannelState, action: PayloadAction<NewsChannel>) {
            state.newsChannel = action.payload;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchNewsChannels.pending, (state: NewsChannelState) => {
                state.status = 'loading';
            })
            .addCase(fetchNewsChannels.fulfilled, (state: NewsChannelState, action: PayloadAction<Array<NewsChannel>>) => {
                state.all = action.payload;
                state.status = 'idle';
            })
            .addCase(fetchNewsChannels.rejected, (state: NewsChannelState) => {
                state.status = 'failed';
            })
            .addCase(fetchNewsChannel.pending, (state: NewsChannelState) => {
                state.status = 'loading';
            })
            .addCase(fetchNewsChannel.fulfilled, (state: NewsChannelState, action: PayloadAction<NewsChannel>) => {
                state.newsChannel = action.payload;
                state.status = 'idle';
            })
            .addCase(fetchNewsChannel.rejected, (state: NewsChannelState) => {
                state.status = 'failed';
            });
    },
});

export default newsChannelSlice.reducer;