import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import api from '@/lib/axios';
import { toast } from 'sonner';
import messages from '../../../messages/en.json';
import { handleToastError } from '@/lib/utils';

// Type definitions
export interface InspectionAnswerOption {
    id: number;
    option_text: string;
    question_id: number;
}

export interface InspectionQuestion {
    id: number;
    question_text: string;
    answer_options: InspectionAnswerOption[];
    created_at: string;
    updated_at: string;
}

export interface CreateInspectionQuestionPayload {
    question_text: string;
    answer_options: [];
}

interface InspectionQuestionState {
    items: InspectionQuestion[];
    totalCount: number;
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    error: string | null;
    filters: {
        search: string;
        limit: number;
        skip: number;
    };
}

const initialState: InspectionQuestionState = {
    items: [],
    totalCount: 0,
    status: 'idle',
    error: null,
    filters: {
        search: '',
        limit: 10,
        skip: 0,
    },
};

// Async thunks
export const fetchInspectionQuestions = createAsyncThunk(
    'inspectionQuestions/fetch',
    async (params: any, { rejectWithValue }) => {
        try {
            const response = await api.get('/inspection-questions', { params });
            return response.data.data;
        } catch (err) {
            return rejectWithValue(messages.toasts.error.failed_to_fetch_questions);
        }
    },
);

export const addInspectionQuestion = createAsyncThunk(
    'inspectionQuestions/add',
    async (payload: CreateInspectionQuestionPayload, { rejectWithValue }) => {
        try {
            const response = await api.post('/inspection-questions', payload);
            handleToastError(response);
            return response;
        } catch (err) {
            return rejectWithValue(messages.toasts.error.failed_to_add_question);
        }
    },
);

export const updateInspectionQuestion = createAsyncThunk(
    'inspectionQuestions/update',
    async ({ id, data }: { id: number; data: Partial<CreateInspectionQuestionPayload> }, { rejectWithValue }) => {
        try {
            const response = await api.patch(`/inspection-questions/${id}`, data);
            handleToastError(response);
            return response;
        } catch (err) {
            return rejectWithValue(messages.toasts.error.failed_to_update_question);
        }
    },
);

export const deleteInspectionQuestion = createAsyncThunk(
    'inspectionQuestions/delete',
    async (id: number, { rejectWithValue }) => {
        try {
            const response = await api.delete(`/inspection-questions/${id}`);
            return response.data.code === 200 ? id : rejectWithValue(messages.toasts.error.failed_to_delete_question);
        } catch (err) {
            return rejectWithValue(messages.toasts.error.failed_to_delete_question);
        }
    },
);

export const getInspectionQuestionById = createAsyncThunk(
    'inspectionQuestions/getById',
    async (id: number, { rejectWithValue }) => {
        try {
            const response = await api.get(`/inspection-questions/${id}`);
            return response.data;
        } catch (err) {
            return rejectWithValue(messages.toasts.error.failed_to_fetch_question);
        }
    },
);

// Slice
const inspectionQuestionSlice = createSlice({
    name: 'inspectionQuestions',
    initialState,
    reducers: {
        setFilters(state, action: PayloadAction<Partial<InspectionQuestionState['filters']>>) {
            state.filters = { ...state.filters, ...action.payload };
        },
        resetFilters(state) {
            state.filters = initialState.filters;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchInspectionQuestions.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchInspectionQuestions.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.items = action.payload.data;
                state.totalCount = action.payload.count;
            })
            .addCase(fetchInspectionQuestions.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            })
            .addCase(addInspectionQuestion.fulfilled, (state, action) => {
                state.status = 'succeeded';
                if (action.payload.data.code === 200) {
                    toast.success(messages.toasts.success.question_added);
                }
            })
            .addCase(addInspectionQuestion.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(updateInspectionQuestion.fulfilled, (state, action) => {
                state.status = 'succeeded';
                if (action.payload.data.code === 200) {
                    toast.success(messages.toasts.success.question_updated);
                }
            })
            .addCase(updateInspectionQuestion.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(deleteInspectionQuestion.fulfilled, (state, action) => {
                state.items = state.items.filter((item) => item.id !== action.payload);
                toast.success(messages.toasts.success.question_deleted);
            })
            .addCase(deleteInspectionQuestion.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(getInspectionQuestionById.fulfilled, (state) => {
                state.status = 'succeeded';
            })
            .addCase(getInspectionQuestionById.rejected, (_, action) => {
                toast.error(action.payload as string);
            });
    },
});

export const { setFilters, resetFilters } = inspectionQuestionSlice.actions;
export default inspectionQuestionSlice.reducer;
