import { configureStore, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import type {
    Clan,
    ClanListParams,
    Crew,
    CrewListParams,
    NinjaSageLoginUser,
    NinjaSageLoginUserListParams,
    PaginatedMeta,
    ShadowWar,
    ShadowWarListParams,
} from "./api";
import { fetchClans, fetchCrews, fetchLoginUsers, fetchShadowWars } from "./api";

type LoadState<T> = {
    items: T[];
    meta: PaginatedMeta | null;
    rev: number | null;
    loading: boolean;
    error: string | null;
    lastParams: Record<string, unknown> | null;
};

const initialLoadState = <T,>(): LoadState<T> => ({
    items: [],
    meta: null,
    rev: null,
    loading: false,
    error: null,
    lastParams: null,
});

export const loadClans = createAsyncThunk(
    "clans/load",
    async (params: ClanListParams) => {
        const data = await fetchClans(params);
        return { data, params };
    },
);

const clansSlice = createSlice({
    name: "clans",
    initialState: initialLoadState<Clan>(),
    reducers: {
        clearClanError(state) {
            state.error = null;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(loadClans.pending, (state, action) => {
                state.loading = true;
                state.error = null;
                state.lastParams = action.meta.arg as any;
            })
            .addCase(loadClans.fulfilled, (state, action) => {
                state.loading = false;
                state.items = action.payload.data.data;
                state.meta = action.payload.data.meta;
            })
            .addCase(loadClans.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || "Gagal memuat data.";
            });
    },
});

export const loadCrews = createAsyncThunk(
    "crews/load",
    async (params: CrewListParams) => {
        const data = await fetchCrews(params);
        return { data, params };
    },
);

const crewsSlice = createSlice({
    name: "crews",
    initialState: initialLoadState<Crew>(),
    reducers: {
        clearCrewError(state) {
            state.error = null;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(loadCrews.pending, (state, action) => {
                state.loading = true;
                state.error = null;
                state.lastParams = action.meta.arg as any;
            })
            .addCase(loadCrews.fulfilled, (state, action) => {
                state.loading = false;
                state.items = action.payload.data.data;
                state.meta = action.payload.data.meta;
            })
            .addCase(loadCrews.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || "Gagal memuat data.";
            });
    },
});

export const loadShadowWars = createAsyncThunk(
    "shadowWars/load",
    async (params: ShadowWarListParams) => {
        const data = await fetchShadowWars(params);
        return { data, params };
    },
);

const shadowWarsSlice = createSlice({
    name: "shadowWars",
    initialState: initialLoadState<ShadowWar>(),
    reducers: {
        clearShadowWarError(state) {
            state.error = null;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(loadShadowWars.pending, (state, action) => {
                state.loading = true;
                state.error = null;
                state.lastParams = action.meta.arg as any;
            })
            .addCase(loadShadowWars.fulfilled, (state, action) => {
                state.loading = false;
                state.items = action.payload.data.data;
                state.meta = action.payload.data.meta;
            })
            .addCase(loadShadowWars.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || "Gagal memuat data.";
            });
    },
});

export const loadLoginUsers = createAsyncThunk(
    "loginUsers/load",
    async (params: NinjaSageLoginUserListParams) => {
        const data = await fetchLoginUsers(params);
        return { data, params };
    },
);

const loginUsersSlice = createSlice({
    name: "loginUsers",
    initialState: initialLoadState<NinjaSageLoginUser>(),
    reducers: {
        clearLoginUserError(state) {
            state.error = null;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(loadLoginUsers.pending, (state, action) => {
                state.loading = true;
                state.error = null;
                state.lastParams = action.meta.arg as any;
            })
            .addCase(loadLoginUsers.fulfilled, (state, action) => {
                state.loading = false;
                state.items = action.payload.data.data;
                state.meta = action.payload.data.meta;
                state.rev = (action.payload.data as any).rev ?? null;
            })
            .addCase(loadLoginUsers.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || "Gagal memuat data.";
            });
    },
});

export const store = configureStore({
    reducer: {
        clans: clansSlice.reducer,
        crews: crewsSlice.reducer,
        shadowWars: shadowWarsSlice.reducer,
        loginUsers: loginUsersSlice.reducer,
    },
});

export const actions = {
    clans: clansSlice.actions,
    crews: crewsSlice.actions,
    shadowWars: shadowWarsSlice.actions,
    loginUsers: loginUsersSlice.actions,
};

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
