import { supabase } from './supabase'; import * as offline from './offlineStorage'; import { generateHabitsFromIdentity } from '../utils/helpers'; import { todayISO, addDays } from '../utils/date'; // Must match authService.js const USE_OFFLINE = true; // ======================== // GET IDENTITY // ======================== export async function getIdentity(userId) { if (USE_OFFLINE) { return offline.getOne('identities', { user_id: userId }); } const { data, error } = await supabase .from('identities') .select('*') .eq('user_id', userId) .order('created_at', { ascending: false }) .limit(1) .single(); if (error && error.code !== 'PGRST116') throw error; return data || null; } // ======================== // CREATE IDENTITY // ======================== export async function createIdentity(userId, title, description, customHabits, storyText) { const startDate = todayISO(); const endDate = addDays(new Date(), 40); if (USE_OFFLINE) { const identity = await offline.insert('identities', { user_id: userId, title, description: description || title, story_text: storyText || '', start_date: startDate, end_date: endDate, status: 'active', }); const habitsList = customHabits && customHabits.length > 0 ? customHabits : generateHabitsFromIdentity(title); const habitsToInsert = habitsList.map((h) => ({ identity_id: identity.id, title: h.title, description: h.description || '', })); const habits = await offline.insertMany('habits', habitsToInsert); await offline.insert('stats', { identity_id: identity.id, discipline_score: 0, focus_score: 0, consistency_score: 0, }); return { identity, habits }; } // --- Supabase path --- const { data, error } = await supabase .from('identities') .insert({ user_id: userId, title, description: description || title, story_text: storyText || '', start_date: startDate, end_date: endDate, status: 'active', }) .select() .single(); if (error) throw error; const habitsList = customHabits && customHabits.length > 0 ? customHabits : generateHabitsFromIdentity(title); const habitsToInsert = habitsList.map((h) => ({ identity_id: data.id, title: h.title, description: h.description || '', })); const { data: habits, error: habitsError } = await supabase .from('habits') .insert(habitsToInsert) .select(); if (habitsError) throw habitsError; await supabase.from('stats').insert({ identity_id: data.id, discipline_score: 0, focus_score: 0, consistency_score: 0, }); return { identity: data, habits: habits || [] }; } // ======================== // DAILY LOGS // ======================== export async function getDailyLogs(identityId) { if (USE_OFFLINE) { const logs = await offline.getAll('daily_logs', { identity_id: identityId }); return logs.sort((a, b) => a.day_number - b.day_number); } const { data, error } = await supabase .from('daily_logs') .select('*') .eq('identity_id', identityId) .order('day_number', { ascending: true }); if (error) throw error; return data || []; } export async function saveDailyLog(identityId, dayNumber, identityCheck, note) { const today = todayISO(); if (USE_OFFLINE) { await offline.upsert( 'daily_logs', { identity_id: identityId, date: today }, { day_number: dayNumber, identity_check: identityCheck, note: note || '' } ); // Update stats const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0; if (scoreAdd > 0) { const stats = await offline.getOne('stats', { identity_id: identityId }); if (stats) { await offline.update('stats', { id: stats.id }, { discipline_score: stats.discipline_score + scoreAdd, consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1), focus_score: stats.focus_score + scoreAdd, }); } } return; } // --- Supabase path --- const { data: existing } = await supabase .from('daily_logs') .select('id') .eq('identity_id', identityId) .eq('date', today) .maybeSingle(); if (existing) { const { error } = await supabase .from('daily_logs') .update({ identity_check: identityCheck, note: note || '' }) .eq('id', existing.id); if (error) throw error; } else { const { error } = await supabase .from('daily_logs') .insert({ identity_id: identityId, date: today, day_number: dayNumber, identity_check: identityCheck, note: note || '', }); if (error) throw error; } const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0; if (scoreAdd > 0) { const { data: stats } = await supabase .from('stats') .select('*') .eq('identity_id', identityId) .maybeSingle(); if (stats) { await supabase .from('stats') .update({ discipline_score: stats.discipline_score + scoreAdd, consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1), focus_score: stats.focus_score + scoreAdd, }) .eq('id', stats.id); } } } // ======================== // STATS // ======================== export async function getStats(identityId) { if (USE_OFFLINE) { return offline.getOne('stats', { identity_id: identityId }); } const { data, error } = await supabase .from('stats') .select('*') .eq('identity_id', identityId) .single(); if (error && error.code !== 'PGRST116') throw error; return data || null; } // ======================== // GAME SESSIONS // ======================== export async function saveGameScore(identityId, gameType, score) { if (USE_OFFLINE) { await offline.insert('game_sessions', { identity_id: identityId, game_type: gameType, score, }); return; } const { error } = await supabase.from('game_sessions').insert({ identity_id: identityId, game_type: gameType, score, }); if (error) throw error; }