import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode, } from "react"; import { useAuth, useUser } from "@clerk/clerk-expo"; import { getCurrentMembershipFeaturesFromServer, type MembershipFeatures, type MembershipType, } from "../api/membership"; import log from "../utils/logger"; const BASIC_FEATURES: MembershipFeatures = { recommendationsPerMonth: 1, hydrationTracking: false, nutritionTracking: false, advancedStatistics: false, }; interface MembershipContextValue { membershipType: MembershipType; features: MembershipFeatures; loading: boolean; refreshMembership: () => Promise; } const MembershipContext = createContext( undefined, ); export function MembershipProvider({ children }: { children: ReactNode }) { const { user } = useUser(); const { getToken, isSignedIn } = useAuth(); const [membershipType, setMembershipType] = useState("basic"); const [features, setFeatures] = useState(BASIC_FEATURES); const [loading, setLoading] = useState(true); const loadMembership = useCallback(async () => { if (!isSignedIn || !user?.id) { setMembershipType("basic"); setFeatures(BASIC_FEATURES); setLoading(false); return; } try { setLoading(true); const token = await getToken(); const result = await getCurrentMembershipFeaturesFromServer(token); setMembershipType(result.membershipType); setFeatures(result.features); } catch (error) { log.error("Failed to load membership", error, { userId: user.id }); setMembershipType("basic"); setFeatures(BASIC_FEATURES); } finally { setLoading(false); } }, [isSignedIn, user?.id]); useEffect(() => { loadMembership(); }, [loadMembership]); const value = useMemo( () => ({ membershipType, features, loading, refreshMembership: loadMembership, }), [membershipType, features, loading, loadMembership], ); return ( {children} ); } export function useMembershipContext(): MembershipContextValue { const context = useContext(MembershipContext); if (!context) { throw new Error( "useMembershipContext must be used within MembershipProvider", ); } return context; }