const { EmbedBuilder } = require('discord.js'); const { getEmbedColor } = require('./modeHelper'); async function getStandaloneXp(supabase, discordId, guildId) { if (!supabase) return null; try { const { data } = await supabase .from('guild_user_xp') .select('*') .eq('discord_id', discordId) .eq('guild_id', guildId) .maybeSingle(); return data || null; } catch (e) { return null; } } async function updateStandaloneXp(supabase, discordId, guildId, xpGain, username) { if (!supabase) return null; try { const { data: existing } = await supabase .from('guild_user_xp') .select('*') .eq('discord_id', discordId) .eq('guild_id', guildId) .maybeSingle(); if (existing) { const newXp = (existing.xp || 0) + xpGain; const totalEarned = (existing.total_xp_earned || 0) + xpGain; const { data } = await supabase .from('guild_user_xp') .update({ xp: newXp, total_xp_earned: totalEarned, updated_at: new Date().toISOString(), }) .eq('id', existing.id) .select() .single(); return data; } else { const { data } = await supabase .from('guild_user_xp') .insert({ discord_id: discordId, guild_id: guildId, username: username, xp: xpGain, total_xp_earned: xpGain, prestige_level: 0, daily_streak: 0, }) .select() .single(); return data; } } catch (e) { console.error('Standalone XP update error:', e.message); return null; } } async function getStandaloneLeaderboard(supabase, guildId, limit = 10) { if (!supabase) return []; try { const { data } = await supabase .from('guild_user_xp') .select('discord_id, username, xp, prestige_level') .eq('guild_id', guildId) .order('xp', { ascending: false }) .limit(limit); return data || []; } catch (e) { return []; } } async function claimStandaloneDaily(supabase, discordId, guildId, username) { if (!supabase) return { success: false, message: 'Database not available' }; try { const { data: existing } = await supabase .from('guild_user_xp') .select('*') .eq('discord_id', discordId) .eq('guild_id', guildId) .maybeSingle(); const now = new Date(); const today = now.toISOString().split('T')[0]; if (existing) { const lastClaim = existing.last_daily_claim ? existing.last_daily_claim.split('T')[0] : null; if (lastClaim === today) { return { success: false, message: 'You already claimed your daily reward today!' }; } const yesterday = new Date(now); yesterday.setDate(yesterday.getDate() - 1); const yesterdayStr = yesterday.toISOString().split('T')[0]; let newStreak = 1; if (lastClaim === yesterdayStr) { newStreak = (existing.daily_streak || 0) + 1; } const baseXp = 50; const streakBonus = Math.min(newStreak * 5, 100); const totalXp = baseXp + streakBonus; const newXp = (existing.xp || 0) + totalXp; const totalEarned = (existing.total_xp_earned || 0) + totalXp; await supabase .from('guild_user_xp') .update({ xp: newXp, total_xp_earned: totalEarned, daily_streak: newStreak, last_daily_claim: now.toISOString(), updated_at: now.toISOString(), }) .eq('id', existing.id); return { success: true, xpGained: totalXp, streak: newStreak, totalXp: newXp, }; } else { const baseXp = 50; await supabase .from('guild_user_xp') .insert({ discord_id: discordId, guild_id: guildId, username: username, xp: baseXp, total_xp_earned: baseXp, prestige_level: 0, daily_streak: 1, last_daily_claim: now.toISOString(), }); return { success: true, xpGained: baseXp, streak: 1, totalXp: baseXp, }; } } catch (e) { console.error('Standalone daily claim error:', e.message); return { success: false, message: 'An error occurred' }; } } async function prestigeStandalone(supabase, discordId, guildId) { if (!supabase) return { success: false, message: 'Database not available' }; try { const { data: existing } = await supabase .from('guild_user_xp') .select('*') .eq('discord_id', discordId) .eq('guild_id', guildId) .maybeSingle(); if (!existing) { return { success: false, message: 'No XP data found' }; } const level = calculateLevel(existing.xp || 0, 'normal'); if (level < 50) { return { success: false, message: `You need Level 50 to prestige! (Current: Level ${level})` }; } const newPrestige = (existing.prestige_level || 0) + 1; await supabase .from('guild_user_xp') .update({ xp: 0, prestige_level: newPrestige, updated_at: new Date().toISOString(), }) .eq('id', existing.id); return { success: true, newPrestige: newPrestige, bonus: newPrestige * 5, }; } catch (e) { console.error('Standalone prestige error:', e.message); return { success: false, message: 'An error occurred' }; } } function calculateLevel(xp, curve = 'normal') { const bases = { easy: 50, normal: 100, hard: 200, }; const base = bases[curve] || 100; return Math.floor(Math.sqrt(xp / base)); } module.exports = { getStandaloneXp, updateStandaloneXp, getStandaloneLeaderboard, claimStandaloneDaily, prestigeStandalone, calculateLevel, };