import { apiConfig, apiLogin, apiRegister, apiValidationCode, } from "@/service/api-config"; import { apiDeviceTokenDeleted } from "@/service/api-device-token"; import { IUser } from "@/types/User"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { router } from "expo-router"; import { createContext, useEffect, useState } from "react"; import Toast from "react-native-toast-message"; import * as Device from "expo-device"; // --- Types --- type AuthContextType = { user: IUser | null; token: string | null; isLoading: boolean; isAuthenticated: boolean; isAdmin: boolean; isUserActive: boolean; loginWithNomor: (nomor: string) => Promise; validateOtp: (nomor: string) => Promise; logout: () => Promise; registerUser: (userData: { username: string; nomor: string; termsOfServiceAccepted: boolean; }) => Promise; userData: (token: string) => Promise; }; // --- Create Context --- export const AuthContext = createContext( undefined ); export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const isAuthenticated = !!user; const isAdmin = user?.masterUserRoleId !== "1"; const isUserActive = user?.active === true; // --- Load session from AsyncStorage on app start --- useEffect(() => { const loadSession = async () => { try { const storedToken = await AsyncStorage.getItem("authToken"); const storedUser = await AsyncStorage.getItem("userData"); if (storedToken) { setToken(storedToken); } if (storedToken && storedUser) { setToken(storedToken); setUser(JSON.parse(storedUser)); } } catch (error) { console.error("Failed to load session", error); } finally { setIsLoading(false); } }; loadSession(); }, []); // --- 1. Kirim nomor → dapat OTP --- const loginWithNomor = async (nomor: string) => { setIsLoading(true); try { console.log("[Masuk provider]", nomor); const response = await apiLogin({ nomor: nomor }); console.log("[RESPONSE AUTH]", JSON.stringify(response)); if (response.success) { console.log("[Keluar provider]", nomor); Toast.show({ type: "success", text1: "Sukses", text2: "Kode OTP berhasil dikirim", }); await AsyncStorage.setItem("kode_otp", response.kodeId); router.push(`/verification?nomor=${nomor}`); return; } else { router.push(`/register?nomor=${nomor}`); Toast.show({ type: "info", text1: "Info", text2: "Silahkan mendaftar", }); return; } } catch (error: any) { throw new Error(error.response?.data?.message || "Gagal kirim OTP"); } finally { setIsLoading(false); } }; // const loginWithNomor = async (nomor: string) => { // setIsLoading(true); // try { // const response = await apiLogin({ nomor: nomor }); // await AsyncStorage.setItem("kode_otp", response.kodeId); // } catch (error: any) { // throw new Error(error.response?.data?.message || "Gagal kirim OTP"); // } finally { // setIsLoading(false); // } // }; // --- 2. Validasi OTP & cek user --- const validateOtp = async (nomor: string) => { try { setIsLoading(true); const response = await apiValidationCode({ nomor: nomor }); const { token } = response; console.log("[RESPONSE VALIDASI OTP]", JSON.stringify(response, null, 2)); if (response.success) { setToken(token); await AsyncStorage.setItem("authToken", token); const responseUser = await apiConfig.get(`/mobile?token=${token}`, { headers: { Authorization: `Bearer ${token}`, }, }); const dataUser = responseUser.data.data; setUser(dataUser); await AsyncStorage.setItem("userData", JSON.stringify(dataUser)); if (response.active) { // if (response.roleId === "1") { // router.replace("/(application)/(user)/home"); // return; // } else { // router.replace("/(application)/admin/dashboard"); // return; // } router.replace("/(application)/(user)/home"); return; } else { router.replace("/(application)/(user)/waiting-room"); return; } } else { Toast.show({ type: "info", text1: "Terjadi kesalahan", text2: "Silahkan coba lagi", }); return; } } catch (error: any) { console.log("Error validasi otp >>", (error as Error).message || error); throw new Error( error.response?.data?.message || "OTP salah atau user tidak ditemukan" ); } finally { setIsLoading(false); } }; // --- 3. Ambil data user --- const userData = async (token: string) => { try { if (!token) { throw new Error("Token tidak ditemukan"); } setIsLoading(true); const response = await apiConfig.get(`/mobile?token=${token}`, { headers: { Authorization: `Bearer ${token}`, }, }); const dataUser = response.data.data; setUser(dataUser); await AsyncStorage.setItem("userData", JSON.stringify(dataUser)); return dataUser; } catch (error: any) { console.log( "[LOAD USER DATA]", error.response?.data?.message + "user" || "Gagal mengambil data user" ); } finally { setIsLoading(false); } }; // --- 4. Register jika user belum ada --- const registerUser = async (userData: { username: string; nomor: string; termsOfServiceAccepted: boolean; }) => { setIsLoading(true); try { const response = await apiRegister({ data: userData }); console.log("[REGISTER FETCH]", JSON.stringify(response, null, 2)); if (!response.success) { Toast.show({ type: "info", text1: "Info", text2: response.message, }); return; } Toast.show({ type: "success", text1: "Sukses", text2: "Anda berhasil terdaftar", }); router.replace(`/verification?nomor=${userData.nomor}`); return; } catch (error: any) { Toast.show({ type: "error", text1: "Error", text2: error.response?.data?.message || "Gagal mendaftar", }); console.log("Error register", error); } finally { setIsLoading(false); } }; // const registerUser = async (userData: { // username: string; // nomor: string; // termsOfServiceAccepted: boolean; // }) => { // setIsLoading(true); // try { // const response = await apiRegister({ data: userData }); // console.log("response", response); // const { token } = response; // if (!response.success) { // Toast.show({ // type: "info", // text1: "Info", // text2: response.message, // }); // return; // } // setToken(token); // await AsyncStorage.setItem("authToken", token); // Toast.show({ // type: "success", // text1: "Sukses", // text2: "Anda berhasil terdaftar", // }); // router.replace("/(application)/(user)/waiting-room"); // return; // } catch (error: any) { // console.log("Error register", error); // } finally { // setIsLoading(false); // } // }; // --- 5. Logout --- const logout = async () => { try { setIsLoading(true); setToken(null); setUser(null); const deviceId = Device.osInternalBuildId || Device.modelName || "unknown"; await AsyncStorage.removeItem("authToken"); await AsyncStorage.removeItem("userData"); await apiDeviceTokenDeleted({ userId: user?.id as any, deviceId }); Toast.show({ type: "success", text1: "Logout berhasil", text2: "Anda berhasil keluar dari akun.", }); router.replace("/"); } catch (error) { console.log("Logout error (optional):", error); } finally { setIsLoading(false); } }; return ( <> {children} ); };