import {
  apiConfig,
  apiLogin,
  apiRegister,
  apiUpdatedTermCondition,
  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 * as Device from "expo-device";
import { router } from "expo-router";
import { createContext, useEffect, useState } from "react";
import Toast from "react-native-toast-message";

// --- Types ---
type AuthContextType = {
  user: IUser | null;
  token: string | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  isAdmin: boolean;
  isUserActive: boolean;
  loginWithNomor: (nomor: string) => Promise<boolean>;
  validateOtp: (nomor: string) => Promise<any>;
  logout: () => Promise<void>;
  registerUser: (userData: {
    username: string;
    nomor: string;
    termsOfServiceAccepted: boolean;
  }) => Promise<void>;
  userData: (token: string) => Promise<any>;
  acceptedTerms: (
    nomor: string,
    onSetModalVisible: (visible: boolean) => void,
  ) => Promise<any>;
};

// --- Create Context ---
export const AuthContext = createContext<AuthContextType | undefined>(
  undefined,
);

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
  const [user, setUser] = useState<IUser | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState<boolean>(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 {
      const response = await apiLogin({ nomor: nomor });
      console.log("[RESPONSE AUTH]", JSON.stringify(response, null, 2));

      if (response.success && response.isAcceptTerms) {
        await AsyncStorage.setItem("kode_otp", response.kodeId);
        router.push(`/verification?nomor=${nomor}`);
        return true;
      } else {
        return false;
      }
    } 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 });

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

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

  // --- 6. Accept Terms ---
  const acceptedTerms = async (
    nomor: string,
    onSetModalVisible: (visible: boolean) => void,
  ) => {
    try {
      setIsLoading(true);
      const response = await apiUpdatedTermCondition({ nomor: nomor });

      if (response.success) {
        return `/verification?nomor=${nomor}`;
      } else {
        return `/register?nomor=${nomor}`;
      }
    } catch (error) {
      console.log("Error accept terms", error);
    } finally {
      setIsLoading(false);
      onSetModalVisible(false);
    }
  };

  return (
    <>
      <AuthContext.Provider
        value={{
          user,
          token,
          isLoading,
          isAuthenticated,
          isAdmin,
          isUserActive,
          loginWithNomor,
          validateOtp,
          logout,
          registerUser,
          userData,
          acceptedTerms,
        }}
      >
        {children}
      </AuthContext.Provider>
    </>
  );
};
