import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
import http from "../../lib/https";
import { toast } from "sonner";

// Define the structure for carDetails
interface CarDetails {
	name: string;
	number: string;
	model: string;
}

interface Booking {
	id: number;
	slotId: number;
	stationId: string;
	stationName: string;
	stationLocation: string;
	date: string;
	startTime: string;
	endTime: string;
	carDetails: CarDetails;
	carNames: string[]; // For car names
	carPorts: string[]; // For car ports
}

interface BookingState {
	bookings: Booking[];
	loading: boolean;
	error: string | null;
	carNames: string[]; // For car names
	carPorts: string[]; // For car ports
}

const initialState: BookingState = {
	bookings: [],
	loading: false,
	error: null,
	carNames: [], // Initialize carNames
	carPorts: [], // Initialize carPorts
};

// Redux slice for fetching car names and ports
export const getCarNames = createAsyncThunk<
	string[],
	void,
	{ rejectValue: string }
>("fetchCarNames", async (_, { rejectWithValue }) => {
	try {
		const response = await http.get("/get-vehicle-dropdown");
		return response.data.data; // Adjust based on actual API response
	} catch (error: any) {
		return rejectWithValue(
			error?.response?.data?.message || "An error occurred"
		);
	}
});

export const getCarPorts = createAsyncThunk<
	string[],
	void,
	{ rejectValue: string }
>("fetchCarPorts", async (_, { rejectWithValue }) => {
	try {
		const response = await http.get("/get-vehicle-port-dropdown");

		return response.data.data; // Adjust based on actual API response
		
	} catch (error: any) {
		return rejectWithValue(
			error?.response?.data?.message || "An error occurred"
		);
	}
});

// Fetch booking list
export const bookingList = createAsyncThunk<
	Booking[],
	void,
	{ rejectValue: string }
>("fetchBooking", async (_, { rejectWithValue }) => {
	try {
		const token = localStorage?.getItem("authToken");
		if (!token) throw new Error("No token found");

		const response = await http.get("/user-bookings");
		console.log("API Response:", response);

		if (!response.data?.data) throw new Error("Invalid API response");

		return response.data.data; // Updated to access data
	} catch (error: any) {
		toast.error("Error Fetching User Booking List: " + error.message);
		return rejectWithValue(
			error?.response?.data?.message || "An error occurred"
		);
	}
});

// Add a new booking
export const addBooking = createAsyncThunk<
	Booking,
	{
		stationId: string;
		date: string;
		startTime: string;
		endTime: string;
		carName: string;
		carNumber: string;
		carPort: string;
	},
	{ rejectValue: string }
>("/AddBooking", async (data, { rejectWithValue }) => {
	try {
		const response = await http.post("/book-slot", data);
		toast.success("EV Booked Successfully!");
		return response.data.data; // Adjust to match the new API response structure
	} catch (error: any) {
		toast.error(
			"The requested time slot doesn't fall within any available slot "
		);
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});
export const deleteBooking = createAsyncThunk<
	string, // Return type (id of deleted slot)
	string,
	{ rejectValue: string }
>("booking/deleteBooking", async (id, { rejectWithValue }) => {
	try {
		const response = await http.delete(`/delete-booking/${id}`);
		toast.success("Slot deleted successfully");
		return id; // Return the id of the deleted slot
	} catch (error: any) {
		toast.error("Error deleting the slot: " + error?.message);
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});
const bookSlice = createSlice({
	name: "booking",
	initialState,
	reducers: {},
	extraReducers: (builder) => {
		builder
			.addCase(bookingList.pending, (state) => {
				state.loading = true;
				state.error = null;
			})
			.addCase(
				bookingList.fulfilled,
				(state, action: PayloadAction<Booking[]>) => {
					state.loading = false;
					state.bookings = action.payload;
				}
			)
			.addCase(bookingList.rejected, (state, action) => {
				state.loading = false;
				state.error =
					action.error.message || "Failed to fetch bookings";
			})
			.addCase(addBooking.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				addBooking.fulfilled,
				(state, action: PayloadAction<Booking>) => {
					state.loading = false;
					state.bookings.push(action.payload); // Add new booking to state
				}
			)
			.addCase(addBooking.rejected, (state) => {
				state.loading = false;
			})
			// Add case reducers for fetching car names and ports
			.addCase(
				getCarNames.fulfilled,
				(state, action: PayloadAction<string[]>) => {
					state.carNames = action.payload;
				}
			)
			.addCase(
				getCarPorts.fulfilled,
				(state, action: PayloadAction<string[]>) => {
					state.carPorts = action.payload;
				}
			)
			.addCase(deleteBooking.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				deleteBooking.fulfilled,
				(state, action: PayloadAction<string>) => {
					state.loading = false;
					// Ensure we're filtering the correct array (bookings)
					state.bookings = state.bookings.filter(
						(booking) =>
							String(booking.id) !== String(action.payload)
					);
					// Also update slots array if it exists
					if (state.bookings) {
						state.bookings = state.bookings.filter(
							(booking) =>
								String(booking.id) !== String(action.payload)
						);
					}
				}
			)
			.addCase(deleteBooking.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to delete slot";
			});
	},
});

export default bookSlice.reducer;