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

// Maintenance type
export interface Maintenance {
    id: number;
    vehicle_id: number;
    maintenance_type: string;
    maintenance_date: string;
    cost: number;
    description?: string;
    garage_name?: string;
    status: 'completed' | 'scheduled' | 'overdue';
    next_scheduled_maintenance: string;
    performed_by: string;
    vehicleName?: string;
    document?: string;
}

// State interface
export interface MaintenanceState {
    items: Maintenance[];
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    error: string | null;
    totalCount: number;
    filters: {
        search: string;
        limit: number;
        skip: number;
        sortBy: string;
        sortOrder: string;
    };
}

// Initial state
const initialState: MaintenanceState = {
    items: [],
    status: 'idle',
    error: null,
    totalCount: 0,
    filters: {
        search: '',
        limit: 10,
        skip: 0,
        sortBy: 'maintenance_date',
        sortOrder: 'DESC',
    },
};

// Add Maintenance payload
export interface AddMaintenancePayload {
    vehicle_id: number;
    maintenance_type: string;
    maintenance_date: string;
    cost: number;
    description?: string;
    performedBy?: string;
    status: 'completed' | 'scheduled' | 'overdue';
    nextScheduled: string;
    document?: File;
}

// Fetch maintenances with pagination parameters
export interface FetchMaintenancesParams {
    fleet_id: number;
    limit?: number;
    skip?: number;
    search?: string;
    sortBy?: string;
    sortOrder?: string;
}

// Thunks

export const fetchMaintenances = createAsyncThunk(
    'maintenance/fetchAll',
    async (params: FetchMaintenancesParams, { rejectWithValue }) => {
        try {
            const { fleet_id, limit = 10, skip = 0, search = '', sortBy = 'maintenance_date', sortOrder = 'DESC' } = params;

            const queryParams = new URLSearchParams({
                fleet_id: fleet_id.toString(),
                limit: limit.toString(),
                skip: skip.toString(),
                sortBy,
                sortOrder,
            });

            if (search) {
                queryParams.append('search', search);
            }

            const response = await api.get(`vehicle-maintenance?${queryParams.toString()}`);
            return response.data.data;
        } catch (error: any) {
            return rejectWithValue(error?.response?.data?.message || 'Failed to fetch maintenance records');
        }
    },
);

export const addMaintenance = createAsyncThunk('maintenance/add', async (payload: FormData, { rejectWithValue }) => {
    try {
        const response = await api.post('vehicle-maintenance/create', payload, {
            headers: {
                'Content-Type': 'multipart/form-data',
            },
        });
        return response.data;
    } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || 'Failed to add maintenance');
    }
});

export const updateMaintenance = createAsyncThunk(
    'maintenance/update',
    async ({ id, payload }: { id: number; payload: Partial<AddMaintenancePayload> }, { rejectWithValue }) => {
        try {
            const response = await api.patch(`vehicle-maintenance/${id}`, payload, {
                headers: {
                    'Content-Type': 'multipart/form-data',
                },
            });
            return response.data;
        } catch (error: any) {
            return rejectWithValue(error?.response?.data?.message || 'Failed to update maintenance');
        }
    },
);

export const deleteMaintenance = createAsyncThunk('maintenance/delete', async (id: number, { rejectWithValue }) => {
    try {
        const response = await api.delete(`vehicle-maintenance/${id}`);
        if (response.data.code === 200) {
            toast.success(messages.toasts.success.maintenance_deleted);
            return id;
        } else {
            toast.error(messages.toasts.error.failed_to_delete_maintenance);
            return rejectWithValue(messages.toasts.error.failed_to_delete_maintenance);
        }
    } catch (error: any) {
        toast.error(messages.toasts.error.failed_to_delete_maintenance);
        return rejectWithValue(error?.response?.data?.message || messages.toasts.error.failed_to_delete_maintenance);
    }
});

export const getMaintenanceDetail = createAsyncThunk('maintenance/detail', async (id: number, { rejectWithValue }) => {
    try {
        const response = await api.get(`vehicle-maintenance/${id}`);
        return response.data.data;
    } catch (error: any) {
        return rejectWithValue(error?.response?.data?.message || 'Failed to fetch maintenance details');
    }
});

// Slice
const maintenanceSlice = createSlice({
    name: 'maintenance',
    initialState,
    reducers: {
        setFilters: (state, action: PayloadAction<Partial<MaintenanceState['filters']>>) => {
            state.filters = { ...state.filters, ...action.payload };
        },
        resetFilters: (state) => {
            state.filters = initialState.filters;
        },
        setPage: (state, action: PayloadAction<number>) => {
            state.filters.skip = action.payload * state.filters.limit;
        },
        setItemsPerPage: (state, action: PayloadAction<number>) => {
            state.filters.limit = action.payload;
            state.filters.skip = 0; // Reset to first page when changing items per page
        },
        setSearch: (state, action: PayloadAction<string>) => {
            state.filters.search = action.payload;
            state.filters.skip = 0; // Reset to first page when searching
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchMaintenances.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchMaintenances.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.items = action.payload.data;
                state.totalCount = action.payload.count;
            })
            .addCase(fetchMaintenances.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            })

            .addCase(addMaintenance.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(addMaintenance.fulfilled, (state, action) => {
                const code = action.payload.code;
                if (code === 200 || code === 201) {
                    toast.success(messages.toasts.success.maintenance_added);
                } else if (code === 422) {
                    toast.error(messages.toasts.error.maintenance_exists);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
                state.status = 'succeeded';
            })
            .addCase(addMaintenance.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
                toast.error(action.payload as string);
            })

            .addCase(updateMaintenance.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(updateMaintenance.fulfilled, (state, action) => {
                const code = action.payload.code;
                if (code === 200 || code === 201) {
                    toast.success(messages.toasts.success.maintenance_updated);
                } else if (code === 422) {
                    toast.error(messages.toasts.error.maintenance_exists);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
                state.status = 'succeeded';
            })
            .addCase(updateMaintenance.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
                toast.error(action.payload as string);
            })

            .addCase(deleteMaintenance.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(deleteMaintenance.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.items = state.items.filter((item) => item.id !== action.payload);
            })
            .addCase(deleteMaintenance.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            })

            .addCase(getMaintenanceDetail.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(getMaintenanceDetail.fulfilled, (state) => {
                state.status = 'succeeded';
            })
            .addCase(getMaintenanceDetail.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            });
    },
});

export const { setFilters, resetFilters, setPage, setItemsPerPage, setSearch } = maintenanceSlice.actions;

export default maintenanceSlice.reducer;
