import {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
} from "react";
import api from "@utils/api";

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true); // Start as true to check auth
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    // Check for existing session on mount
    const checkAuth = async () => {
      const token = localStorage.getItem("authToken");
      if (token) {
        try {
          const response = await api.get("/auth/me");
          setUser(response.data.user);
        } catch (error) {
          console.error("Auth check failed:", error);
          localStorage.removeItem("authToken");
        }
      }
      setLoading(false); // Done checking
    };
    checkAuth();

    // Online status listener
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);

    window.addEventListener("online", handleOnline);
    window.addEventListener("offline", handleOffline);

    return () => {
      window.removeEventListener("online", handleOnline);
      window.removeEventListener("offline", handleOffline);
    };
  }, []);

  const login = useCallback(async (username, password) => {
    const response = await api.post("/auth/login", { username, password });
    const { token, user: userData } = response.data;
    localStorage.setItem("authToken", token);
    setUser(userData);
    return userData;
  }, []);

  const loginWithGoogle = useCallback(async (googleToken) => {
    const response = await api.post("/auth/google", { token: googleToken });
    const { token, user: userData } = response.data;
    localStorage.setItem("authToken", token);
    setUser(userData);
    return userData;
  }, []);

  const loginWithBiometric = useCallback(async () => {
    // WebAuthn authentication flow
    const response = await api.post("/auth/webauthn/authenticate-options");
    const options = response.data;

    // Use SimpleWebAuthn browser
    const { startAuthentication } = await import("@simplewebauthn/browser");
    const authResponse = await startAuthentication(options);

    const verifyResponse = await api.post(
      "/auth/webauthn/authenticate",
      authResponse,
    );
    const { token, user: userData } = verifyResponse.data;
    localStorage.setItem("authToken", token);
    setUser(userData);
    return userData;
  }, []);

  const registerBiometric = useCallback(async () => {
    const optionsResponse = await api.post("/auth/webauthn/register-options");
    const options = optionsResponse.data;

    const { startRegistration } = await import("@simplewebauthn/browser");
    const regResponse = await startRegistration(options);

    await api.post("/auth/webauthn/register", regResponse);
    return true;
  }, []);

  const logout = useCallback(async () => {
    try {
      await api.post("/auth/logout");
    } catch (error) {
      console.error("Logout error:", error);
    } finally {
      localStorage.removeItem("authToken");
      setUser(null);
    }
  }, []);

  const switchProfile = useCallback(async (profileId) => {
    const response = await api.post("/auth/switch-profile", { profileId });
    setUser(response.data.user);
    return response.data.user;
  }, []);

  const value = {
    user,
    loading,
    isOnline,
    login,
    loginWithGoogle,
    loginWithBiometric,
    registerBiometric,
    logout,
    switchProfile,
    isAuthenticated: !!user,
    isAdmin: user?.role === "admin",
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

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

export default AuthContext;
