import AsyncStorage from "@react-native-async-storage/async-storage"; export type PointsActivityType = | "contact_sync" | "send_money" | "login" | "purchase_ticket" | "add_recipient" | "share_event" | "make_request" | "referral_link"; export interface PointsActivityEntry { id: string; type: PointsActivityType; points: number; timestamp: string; metadata?: Record; } export interface PointsState { total: number; activities: PointsActivityEntry[]; } const STORAGE_KEY = "user_points"; const DEFAULT_STATE: PointsState = { total: 0, activities: [], }; export const POINT_VALUES: Record = { contact_sync: 10, send_money: 10, login: 5, purchase_ticket: 15, add_recipient: 10, share_event: 5, make_request: 8, referral_link: 20, }; async function loadState(): Promise { try { const stored = await AsyncStorage.getItem(STORAGE_KEY); if (!stored) return DEFAULT_STATE; const parsed = JSON.parse(stored); if ( typeof parsed === "object" && parsed !== null && typeof parsed.total === "number" && Array.isArray(parsed.activities) ) { return parsed as PointsState; } return DEFAULT_STATE; } catch (error) { if (__DEV__) { console.warn("[pointsService] Failed to load state", error); } return DEFAULT_STATE; } } async function saveState(state: PointsState): Promise { try { await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch (error) { if (__DEV__) { console.warn("[pointsService] Failed to save state", error); } } } export async function getPointsState(): Promise { return loadState(); } export async function awardPoints( type: PointsActivityType, metadata?: Record ): Promise { const current = await loadState(); const delta = POINT_VALUES[type] ?? 0; const entry: PointsActivityEntry = { id: `${type}-${Date.now()}`, type, points: delta, timestamp: new Date().toISOString(), metadata, }; const next: PointsState = { total: current.total + delta, activities: [entry, ...current.activities], }; await saveState(next); return next; } const LOGIN_LAST_AWARD_KEY = "user_points_login_last_award"; const CONTACT_SYNC_AWARDED_KEY = "user_points_contact_sync_awarded"; export async function awardDailyLoginPoints( metadata?: Record ): Promise { const today = new Date().toISOString().slice(0, 10); try { const lastAwardDate = await AsyncStorage.getItem(LOGIN_LAST_AWARD_KEY); if (lastAwardDate === today) { return loadState(); } } catch (error) { if (__DEV__) { console.warn( "[pointsService] Failed to read last login award date", error ); } } const updatedState = await awardPoints("login", metadata); try { await AsyncStorage.setItem(LOGIN_LAST_AWARD_KEY, today); } catch (error) { if (__DEV__) { console.warn( "[pointsService] Failed to save last login award date", error ); } } return updatedState; } export async function awardFirstContactSyncPoints( metadata?: Record ): Promise { try { const alreadyAwarded = await AsyncStorage.getItem(CONTACT_SYNC_AWARDED_KEY); if (alreadyAwarded === "true") { return loadState(); } } catch (error) { if (__DEV__) { console.warn( "[pointsService] Failed to read contact sync awarded flag", error ); } } const updatedState = await awardPoints("contact_sync", metadata); try { await AsyncStorage.setItem(CONTACT_SYNC_AWARDED_KEY, "true"); } catch (error) { if (__DEV__) { console.warn( "[pointsService] Failed to save contact sync awarded flag", error ); } } return updatedState; }