import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
import http from "../../lib/https"; // Assuming you have a custom HTTP library for requests
import { toast } from "sonner";

// Define TypeScript types
interface Slot {
	id: string;
	stationId:string;
	date: string;
	startTime: string;
	endTime: string;
	isAvailable: boolean;

	ChargingStation: { name: string };
}

interface SlotState {
	slots: Slot[];
	availableSlots: Slot[];
	loading: boolean;
	error: string | null;
}

// Initial state
const initialState: SlotState = {
	slots: [],
	availableSlots: [], // <-- Initialize this as an empty array
	loading: false,
	error: null,
};

export const fetchAvailableSlots = createAsyncThunk<
	Slot[],
	void,
	{ rejectValue: string }
>("fetchVehicles", async (_, { rejectWithValue }) => {
	try {
		const token = localStorage?.getItem("authToken");
		if (!token) throw new Error("No token found");

		const response = await http.get("/available");

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

		return response.data.data;
	} catch (error: any) {
		toast.error("Error Fetching Profile" + error);
		return rejectWithValue(
			error?.response?.data?.message || "An error occurred"
		);
	}
});

export const createSlot = createAsyncThunk<
	Slot,
	{
		date: string;
		startTime: string;
		endTime: string;
		isAvailable: boolean;
	},
	{ rejectValue: string }
>("slots/createSlot", async (payload, { rejectWithValue }) => {
	try {
		// const payload = {
		// 	date,
		// 	startHour,
		// 	endHour,
		// 	isAvailable,
		// };

		const token = localStorage?.getItem("authToken");
		if (!token) throw new Error("No token found");
		const response = await http.post("/create-slot", payload);
		toast.success("Slot created successfully");
		return response.data.data;
	} catch (error: any) {
		// Show error message
		toast.error("Error creating slot: " + error?.message);

		// Return a detailed error message if possible
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});

// Update Slot details
export const updateSlot = createAsyncThunk<
	Slot,
	{ id: number; startTime: string; endTime: string }, // Argument type (slot update data)
	{ rejectValue: string }
>("slots/updateSlot", async ({ id, ...slotData }, { rejectWithValue }) => {
	try {
		const response = await http.patch(
			`/update-availability/${id}`,
			slotData
		);
		toast.success("Slot updated successfully");
		return response.data.data; // Return updated slot data
	} catch (error: any) {
		toast.error("Error updating the slot: " + error?.message);
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});

export const deleteSlot = createAsyncThunk<
	string, // Return type (id of deleted slot)
	string,
	{ rejectValue: string }
>("slots/deleteSlot", async (id, { rejectWithValue }) => {
	try {
		const response = await http.delete(`/delete-slot/${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 slotSlice = createSlice({
	name: "slots",
	initialState,
	reducers: {},
	extraReducers: (builder) => {
		builder
			.addCase(fetchAvailableSlots.pending, (state) => {
				state.loading = true;
				state.error = null;
			})
			.addCase(
				fetchAvailableSlots.fulfilled,
				(state, action: PayloadAction<Slot[]>) => {
					state.loading = false;
					state.availableSlots = action.payload;
				}
			)
			.addCase(fetchAvailableSlots.rejected, (state, action) => {
				state.loading = false;
				state.error =
					action.payload || "Failed to fetch available slots";
			})
			.addCase(createSlot.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				createSlot.fulfilled,
				(state, action: PayloadAction<Slot>) => {
					state.loading = false;
					state.slots.push(action.payload);
				}
			)
			.addCase(createSlot.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to create slot";
			})
			.addCase(updateSlot.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				updateSlot.fulfilled,
				(state, action: PayloadAction<Slot>) => {
					state.loading = false;
					// Update the slot in the state with the updated data
					const index = state.slots.findIndex(
						(slot) => slot.id === action.payload.id
					);
					if (index !== -1) {
						state.slots[index] = action.payload;
					}
				}
			)
			.addCase(updateSlot.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to update slot";
			})
			.addCase(deleteSlot.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				deleteSlot.fulfilled,
				(state, action: PayloadAction<string>) => {
					state.loading = false;
					// Ensure we're filtering the correct array (availableSlots)
					state.availableSlots = state.availableSlots.filter(
						(slot) => String(slot.id) !== String(action.payload)
					);
					// Also update slots array if it exists
					if (state.slots) {
						state.slots = state.slots.filter(
							(slot) => String(slot.id) !== String(action.payload)
						);
					}
				}
			)
			.addCase(deleteSlot.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to delete slot";
			});
	},
});

export default slotSlice.reducer;
