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: string;
	name: string;
	registeredAddress: string;
	totalSlots: string;
	status: number;
	allowedCarIds: number[];
}

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"
			);
		}
	}
);

// Create Station
export const createStation = createAsyncThunk<
	any,
	{
		name: string;
		registeredAddress: string;
		totalSlots: string;
		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;
	} 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
export const updateStation = createAsyncThunk(
	"updateStation",
	async ({ id, ...stationData }: Station, { rejectWithValue }) => {
		try {
			const response = await http.patch(
				`/update-station/${id}`,
				stationData
			);
			toast.success("Station Deatils updated successfully");
			return response?.data;
		} catch (error: any) {
			toast.error("Error updating the user: " + 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;
					// Properly extract stations from the response data structure
					state.stations =
						action.payload.data?.results ||
						action.payload.data ||
						[];
				}
			)
			.addCase(stationList.rejected, (state, action) => {
				state.loading = false;
				state.error = action.payload || "Failed to fetch stations";
			})
			.addCase(createStation.pending, (state) => {
				state.loading = true;
			})
			.addCase(
				createStation.fulfilled,
				(state, action: PayloadAction<any>) => {
					state.loading = false;
					// Add the newly created station to the state if it exists in the response
					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;
				state.error = action.payload;
			})
			.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;
