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

// Define TypeScript types
interface Station {
	id: number;
	name: string;
	registeredAddress: string;
	totalSlots: number;
	status: number;
	allowedCarIds: number[];
	city: string;
}

interface StationState {
	stations: Station[];
	loading: boolean;
	error: string | null;
}

// Initial state
const initialState: StationState = {
	stations: [],
	loading: false,
	error: null,
};

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

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

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

			// Return the full response to handle in the reducer
			return response.data;
		} catch (error: any) {
			toast.error("Error Fetching Stations: " + error.message);
			return rejectWithValue(
				error?.response?.data?.message || "An error occurred"
			);
		}
	}
);
export const externalStationList = createAsyncThunk<
	any,
	void,
	{ rejectValue: string }
>("fetchExternalStations", async (_, { rejectWithValue }) => {
	try {
		const response = await http.get("/external-charging-stations");
		if (!response.data) throw new Error("Invalid API response");
		// Return the response data directly, the structure will be handled in the reducer
		return response.data;
	} catch (error: any) {
		console.error("Error fetching external stations:", error);
		toast.error(
			"Error Fetching Stations: " +
				(error.response?.data?.message || error.message)
		);
		return rejectWithValue(
			error.response?.data?.message ||
				error.message ||
				"An error occurred"
		);
	}
});
export const addStationLocation = createAsyncThunk<
	any,
	{
		city: string;
	},
	{ rejectValue: string }
>("Station/addStationLocation", async ({ city }, { rejectWithValue }) => {
	try {
		const response = await http.post("/charging-stations/fetch", { city });
		toast.success("Station created successfully");
		return response.data; // Assuming the response contains the created station data
	} catch (error: any) {
		toast.error(
			"Failed to create Station: " +
				(error.response?.data?.message || "Unknown error")
		);
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});
export const getAllStations = createAsyncThunk<
	any,
	void,
	{ rejectValue: string }
>("getAllStations", async (_, { rejectWithValue }) => {
	try {
		const token = localStorage?.getItem("authToken");
		if (!token) throw new Error("No token found");

		const response = await http.get("/get-all-stations");

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

		// Return the full response to handle in the reducer
		return response.data;
	} catch (error: any) {
		toast.error("Error Fetching Stations: " + error.message);
		return rejectWithValue(
			error?.response?.data?.message || "An error occurred"
		);
	}
});
// Create Station
export const createStation = createAsyncThunk<
	any,
	{
		name: string;
		registeredAddress: string;
		totalSlots: number;
		allowedCarIds: number[];
	},
	{ rejectValue: string }
>("Station/createStation", async (data, { rejectWithValue }) => {
	try {
		const response = await http.post("/create-station", data);
		toast.success("Station created successfully");
		return response.data; // Assuming the response contains the created station data
	} catch (error: any) {
		toast.error(
			"Failed to create Station: " +
				(error.response?.data?.message || "Unknown error")
		);
		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});

// Update Station details
// Update Station details
export const updateStation = createAsyncThunk(
	"updateStation",
	async ({ id, ...stationData }: Station, { rejectWithValue }) => {
		try {
			// Exclude the `status` from the update payload
			const { status, ...updateData } = stationData;

			// Send the update request without the `status`
			const response = await http.patch(
				`/update-station/${id}`,
				updateData
			);
			toast.success("Station Details updated successfully");
			return response?.data;
		} catch (error: any) {
			toast.error("Error updating the station: " + error);
			return rejectWithValue(
				error.response?.data?.message || "An error occurred"
			);
		}
	}
);

export const deleteStation = createAsyncThunk<
	string,
	string,
	{ rejectValue: string }
>("deleteStation", async (id, { rejectWithValue }) => {
	try {
		await http.delete(`/delete-station/${id}`);
		toast.success("Station deleted successfully!");
		return id;
	} catch (error: any) {
		toast.error("Error deleting the Station" + error);

		return rejectWithValue(
			error.response?.data?.message || "An error occurred"
		);
	}
});

export const toggleStatus = createAsyncThunk<
	any,
	{ id: string; status: number },
	{ rejectValue: string }
>("station/toggleStatus", async ({ id, status }, { rejectWithValue }) => {
	try {
		const response = await http.patch(`/update-station/${id}`, { status });

		if (response.data.statusCode === 200) {
			toast.success(
				response.data.message || "Status updated successfully"
			);
			// Return both the response data and the requested status for reliable state updates
			return {
				responseData: response.data,
				id,
				status,
			};
		} else {
			throw new Error(response.data.message || "Failed to update status");
		}
	} catch (error: any) {
		toast.error(
			"Error updating status: " + (error.message || "Unknown error")
		);
		return rejectWithValue(
			error.response?.data?.message ||
				error.message ||
				"An error occurred"
		);
	}
});

const stationSlice = createSlice({
	name: "stations",
	initialState,
	reducers: {},
	extraReducers: (builder) => {
		builder
			.addCase(stationList.pending, (state) => {
				state.loading = true;
				state.error = null;
			})
			.addCase(
				stationList.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;
					// Correct data extraction
					state.stations = action.payload.data?.stations || [];
				}
			)
			.addCase(stationList.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to fetch stations";
			})
			.addCase(getAllStations.pending, (state) => {
				state.loading = true;
				state.error = null;
			})
			.addCase(
				getAllStations.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;
					state.stations = action.payload.data || [];
				}
			)

			.addCase(getAllStations.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to fetch stations";
			})
			.addCase(externalStationList.pending, (state) => {
				state.loading = true;
				state.error = null;
			})
			.addCase(
				externalStationList.fulfilled,

				(state, action: PayloadAction<any>) => {
					state.loading = false;

					console.log("first", action.payload.data);

					state.stations = action.payload.data || [];
				}
			)

			.addCase(externalStationList.rejected, (state, action) => {
				state.loading = false;
				state.error =
					action.payload || "Failed to fetch external stations";
			})
			.addCase(addStationLocation.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				addStationLocation.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;
					if (action.payload.data) {
						state.stations.push(action.payload.data);
					}
				}
			)

			.addCase(
				addStationLocation.rejected,
				(state, action: PayloadAction<string | undefined>) => {
					state.loading = false;
					state.error = action.payload || "Failed to create station";
				}
			)
			.addCase(createStation.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				createStation.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;
					if (action.payload.data) {
						state.stations.push(action.payload.data);
					}
				}
			)

			.addCase(
				createStation.rejected,
				(state, action: PayloadAction<string | undefined>) => {
					state.loading = false;
					state.error = action.payload || "Failed to create station";
				}
			)
			.addCase(toggleStatus.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				toggleStatus.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;

					// Get the id and updated status from the action payload
					const { id, status } = action.payload;

					// Find and update the station with the new status
					const stationIndex = state.stations.findIndex(
						(station) => station.id === id
					);
					if (stationIndex !== -1) {
						state.stations[stationIndex] = {
							...state.stations[stationIndex],
							status: status,
						};
					}
				}
			)
			.addCase(
				toggleStatus.rejected,
				(state, action: PayloadAction<string | undefined>) => {
					state.loading = false;
					state.error =
						action.payload || "Failed to toggle station status";
				}
			)
			.addCase(updateStation.pending, (state) => {
				state.loading = true;
			})
			.addCase(updateStation.fulfilled, (state, action) => {
				state.loading = false;
				// If the station was updated, find and update it in the state
				const updatedStation = action.payload;
				const stationIndex = state.stations.findIndex(
					(station) => station.id === updatedStation.id
				);
				if (stationIndex !== -1) {
					// Here, merge the updated station with the existing one
					// Ensure `status` is not overwritten if not explicitly updated
					state.stations[stationIndex] = {
						...state.stations[stationIndex],
						...updatedStation,
					};
				}
			})

			.addCase(updateStation.rejected, (state) => {
				state.loading = false;
			})
			.addCase(deleteStation.pending, (state) => {
				state.loading = true;
			})
			.addCase(deleteStation.fulfilled, (state, action) => {
				state.loading = false;
				state.stations = state.stations.filter(
					(station) => String(station.id) !== String(action.payload)
				);
			})
			.addCase(deleteStation.rejected, (state) => {
				state.loading = false;
			});
	},
});

export default stationSlice.reducer;