import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import {
    getItems,
    getItem,
    createItem,
    updateItem,
    deleteItem,
    getJSONConfig,
    getPolicyConfigurationsIds
} from './thunks';

interface CmdbItem {
    value?: any;
    comment?: string;
    tags?: string[];
    name: string;
    type?: string;
    key: string;
}

export interface CmdbState {
    items: CmdbItem[];
    currentItem: CmdbItem | null;
    jsonConfig: any;
    policyConfigurationIds: [];
    loading: boolean;
    error: string | null;
    identifier: string | null;
    cmdbServiceUrl: string | null;
    page: number | null;
    total: number | null;
    perPage: number | null;
    loadingStates: {
        getItems: boolean;
        getItem: boolean;
        createItem: boolean;
        updateItem: boolean;
        deleteItem: boolean;
    };
}

const initialState: CmdbState = {
    items: [],
    currentItem: null,
    jsonConfig: null,
    policyConfigurationIds: [],
    loading: false,
    error: null,
    identifier: null,
    cmdbServiceUrl: '/cmdb',
    page: 1,
    total: null,
    perPage: 6,
    loadingStates: {
        getItems: false,
        getItem: false,
        createItem: false,
        updateItem: false,
        deleteItem: false,
    },
};

const cmdbSlice = createSlice({
    name: 'cmdb',
    initialState,
    reducers: {
        clearError: (state) => {
            state.error = null;
        },
        clearCurrentItem: (state) => {
            state.currentItem = null;
        },
        clearJsonConfig: (state) => {
            state.jsonConfig = null;
        },
        setCurrentItem: (state, action: PayloadAction<CmdbItem>) => {
            state.currentItem = action.payload;
        },
        setIdentifier: (state, action: PayloadAction<string>) => {
            state.identifier = action.payload;
        },
        setCmdbServiceUrl: (state, action: PayloadAction<string>) => {
            state.cmdbServiceUrl = action.payload;
        },
        setPage: (state, action: PayloadAction<number>) => {
            state.page = action.payload;
        }
    },
    extraReducers: (builder) => {
        // Get Items
        builder
            .addCase(getItems.pending, (state) => {
                state.loadingStates.getItems = true;
                state.loading = true;
                state.error = null;
            })
            .addCase(getItems.fulfilled, (state, action) => {
                state.loadingStates.getItems = false;
                state.loading = false;
                state.items = action.payload.data;
                state.page = action.payload.meta.page;
                state.total = action.payload.meta.total;
            })
            .addCase(getItems.rejected, (state, action) => {
                state.loadingStates.getItems = false;
                state.loading = false;
                state.error = action.error.message || 'Failed to fetch items.';
            });

        // Get Item
        builder
            .addCase(getItem.pending, (state) => {
                state.loadingStates.getItem = true;
                state.loading = true;
                state.error = null;
            })
            .addCase(getItem.fulfilled, (state, action) => {
                state.loadingStates.getItem = false;
                state.loading = false;
                state.currentItem = action.payload;
            })
            .addCase(getItem.rejected, (state, action) => {
                state.loadingStates.getItem = false;
                state.loading = false;
                state.error = action.error.message || 'Failed to fetch item.';
            });

        // Create Item
        builder
            .addCase(createItem.pending, (state) => {
                state.loadingStates.createItem = true;
                state.loading = true;
                state.error = null;
            })
            .addCase(createItem.fulfilled, (state, action) => {
                state.loadingStates.createItem = false;
                state.loading = false;
            })
            .addCase(createItem.rejected, (state, action) => {
                state.loadingStates.createItem = false;
                state.loading = false;
                state.error = action.error.message || 'Failed to create item.';
            });

        // Update Item
        builder
            .addCase(updateItem.pending, (state) => {
                state.loadingStates.updateItem = true;
                state.loading = true;
                state.error = null;
            })
            .addCase(updateItem.fulfilled, (state, action) => {
                state.loadingStates.updateItem = false;
                state.loading = false;
            })
            .addCase(updateItem.rejected, (state, action) => {
                state.loadingStates.updateItem = false;
                state.loading = false;
                state.error = action.error.message || 'Failed to update item.';
            });

        // Delete Item
        builder
            .addCase(deleteItem.pending, (state) => {
                state.loadingStates.deleteItem = true;
                state.loading = true;
                state.error = null;
            })
            .addCase(deleteItem.fulfilled, (state, action) => {
                state.loadingStates.deleteItem = false;
                state.loading = false;
                state.currentItem = null;
            })
            .addCase(deleteItem.rejected, (state, action) => {
                state.loadingStates.deleteItem = false;
                state.loading = false;
                state.error = action.error.message || 'Failed to delete item.';
            });

        // Get JSON Config
        builder
            .addCase(getJSONConfig.pending, (state) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(getJSONConfig.fulfilled, (state, action) => {
                state.loading = false;
                state.jsonConfig = JSON.stringify(action.payload, null, 2);
            })
            .addCase(getJSONConfig.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || 'Failed to fetch JSON config.';
            });

        // Get existing policy configuration IDS
        builder
            .addCase(getPolicyConfigurationsIds.pending, (state) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(getPolicyConfigurationsIds.fulfilled, (state, action) => {
                state.loading = false;
                state.policyConfigurationIds = action.payload;
            })
            .addCase(getPolicyConfigurationsIds.rejected, (state, action) => {
                state.loading = false;
                state.error = action.error.message || 'Failed to fetch policy configuration information.';
            });
    },
});

export const { clearError, clearCurrentItem, clearJsonConfig, setCurrentItem, setIdentifier, setCmdbServiceUrl, setPage } = cmdbSlice.actions;
export default cmdbSlice.reducer;
