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

// Define types
export interface VehicleModel {
    id: number;
    name: string;
    vehicle_manufacture_id: number;
    vehicle_type_id: number;
    status: number;
    details: any;
    capacity: string;
    created_at: string;
    vehicle_manufacture: {
        id: number;
        name: string;
    };
    vehicle_type: {
        id: number;
        name: string;
    };
}

interface VehicleModelsState {
    items: VehicleModel[];
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    error: string | null;
    filters: {
        search: string;
        sortBy?: string;
        sortOrder?: 'ASC' | 'DESC';
        manufacturer_ids: number[];
        type_ids: number[];
    };
    totalCount: number;
    details: any;
}

// Initial state
const initialState: VehicleModelsState = {
    items: [],
    status: 'idle',
    error: null,
    filters: {
        search: '',
        sortBy: '',
        sortOrder: 'ASC',
        manufacturer_ids: [],
        type_ids: [],
    },
    details: null,
    totalCount: 0,
};

// Async thunks for API calls
export const fetchVehicleModels = createAsyncThunk(
    'vehicleModels/fetchVehicleModels',
    async (params: {
        skip?: number;
        limit?: number;
        search?: string;
        manufacturer_ids?: number[];
        type_ids?: number[];
        sortBy?: string;
        sortOrder?: 'ASC' | 'DESC';
    }) => {
        try {
            const response = await api.get(`/vehicle-models`, {
                params: {
                    skip: params.skip || 0,
                    limit: params.limit || 10,
                    search: params.search || '',
                    sortBy: params.sortBy,
                    sortOrder: params.sortOrder,
                    'manufacturer_ids[]': params.manufacturer_ids,
                    'type_ids[]': params.type_ids,
                },
            });
            return response.data.data;
        } catch (error: any) {
            return error.response;
        }
    },
);

export const addVehicleModel = createAsyncThunk(
    'vehicleModels/addVehicleModel',
    async (data: { name: string; vehicle_manufacture_id: number; vehicle_type_id: number }) => {
        try {
            const response = await api.post(`/vehicle-models`, data, {});
            return response;
        } catch (error: any) {
            return error.response;
        }
    },
);

export const updateVehicleModel = createAsyncThunk(
    'vehicleModels/updateVehicleModel',
    async ({
        id,
        data,
    }: {
        id: number;
        data: {
            name: string;
            vehicle_manufacture_id: number;
            vehicle_type_id: number;
            capacity: string;
        };
    }) => {
        try {
            const response = await api.patch(`/vehicle-models/${id}`, data, {});
            return response.data;
        } catch (error: any) {
            return error.response;
        }
    },
);

export const deleteVehicleModel = createAsyncThunk('vehicleModels/deleteVehicleModel', async (id: number) => {
    try {
        const response = await api.delete(`/vehicle-models/${id}`);
        return response.data;
    } catch (error: any) {
        return error.response;
    }
});

export const fetchVehicleModelDetails = createAsyncThunk('vehicleModels/fetchDetails', async (id: number) => {
    try {
        const response = await api.get(`/vehicle-models/${id}`);

        return response.data;
    } catch (error: any) {
        toast.error(error.response?.data?.message || messages.toasts.error.failed_to_fetch_vehicle_model);
        throw error;
    }
});

// Create the slice
const vehicleModelsSlice = createSlice({
    name: 'vehicleModels',
    initialState,
    reducers: {
        updateFilters: (state, action: PayloadAction<Partial<VehicleModelsState['filters']>>) => {
            state.filters = { ...state.filters, ...action.payload };
        },
        resetFilters: (state) => {
            state.filters = initialState.filters;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchVehicleModels.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchVehicleModels.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.items = action.payload?.data;
                state.totalCount = action.payload?.count;
            })
            .addCase(fetchVehicleModels.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            })
            .addCase(addVehicleModel.fulfilled, (state, action) => {
                const code = action.payload?.data?.code;

                if (code === 200 || code === 201) {
                    toast.success(messages.toasts.success.vehicle_model_added);
                } else if (code === 422) {
                    toast.error(messages.toasts.error.vehicle_model_exists);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
            })
            .addCase(updateVehicleModel.fulfilled, (state, action) => {
                const code = action.payload?.code;

                if (code === 200 || code === 201) {
                    toast.success(messages.toasts.success.vehicle_model_updated);
                } else if (code === 422) {
                    toast.error(messages.toasts.error.vehicle_model_exists);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
            })
            .addCase(deleteVehicleModel.fulfilled, (state, action) => {
                toast.success(messages.toasts.success.vehicle_model_deleted);
            })
            .addCase(fetchVehicleModelDetails.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchVehicleModelDetails.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.details = action.payload?.data;
            })
            .addCase(fetchVehicleModelDetails.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.error.message || 'Failed to fetch vehicle model details';
            });
    },
});

export const { updateFilters, resetFilters } = vehicleModelsSlice.actions;

export default vehicleModelsSlice.reducer;
