import {
	createContext,
	type ReactNode,
	useContext,
	useEffect,
	useState,
} from "react";
import { toast } from "sonner";
import { useLogin } from "@/api/generated/authentication/authentication.ts";
import { useRegisterUser } from "@/api/generated/user/user.ts";

export interface UserPreferences {
	theme: "light" | "dark";
	itemsPerPage: number;
	defaultGenres: string[];
}

export interface User {
	id: number;
	email: string;
	name: string;
	token: string;
	refreshToken: string;
	role: string;
}

interface AuthContextType {
	user: User | null;
	isLoading: boolean;
	isAuthenticated: boolean;
	register: (
		email: string,
		password: string,
		username: string,
	) => Promise<void>;
	login: (email: string, password: string) => Promise<void>;
	logout: () => void;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: ReactNode }) {
	const [user, setUser] = useState<User | null>(null);

	const { mutate: mutateRegisterUser, isPending: isPendingRegisterUser } =
		useRegisterUser({
			mutation: {
				onSuccess: () => {
					toast.success("Registration successful! You can now login.");
					window.location.href = "/login";
				},
			},
		});

	const { mutate: mutateAuthenticateUser, isPending: isPendingLoginUser } =
		useLogin({
			mutation: {
				onSuccess: (response) => {
					if (!response.data) {
						return;
					}

					const userData: User = {
						id: response.data.id,
						email: response.data.email,
						name: response.data.name,
						token: response.data.accessToken,
						refreshToken: response.data.refreshToken,
						role: response.data.role,
					};

					setUser(userData);

					localStorage.setItem("userData", JSON.stringify(userData));

					window.location.href = "/";
				},
			},
		});

	const register = async (email: string, password: string, name: string) => {
		console.log(email);
		mutateRegisterUser({ data: { name, email, password } });
	};

	const login = async (email: string, password: string) => {
		mutateAuthenticateUser({ data: { email, password } });
	};

	const logout = () => {
		setUser(null);
		localStorage.removeItem("userData");
	};

	useEffect(() => {
		const jsonString = localStorage.getItem("userData");
		if (jsonString) {
			const userData: User = JSON.parse(jsonString);
			setUser(userData);
		}
	}, []);

	return (
		<AuthContext.Provider
			value={{
				user,
				isLoading: isPendingLoginUser || isPendingRegisterUser,
				isAuthenticated: !!user,
				register,
				login,
				logout,
			}}
		>
			{children}
		</AuthContext.Provider>
	);
}

export function useAuth() {
	const context = useContext(AuthContext);
	if (context === undefined) {
		throw new Error("useAuth must be used within an AuthProvider");
	}
	return context;
}
