"use client"; import { useState, useEffect, useCallback } from "react"; import Link from "next/link"; import { useAccount } from "@/contexts/AccountContext"; const NUMBERS_COUNT = 6; const TICKET_KEY = "cyberlux-lotto-tickets-v1"; const DRAW_INTERVAL_MS = 24 * 60 * 60 * 1000; const DRAW_EPOCH = new Date("2026-04-14T12:00:00Z").getTime(); function getNextDraw() { const now = Date.now(); const elapsed = now - DRAW_EPOCH; const cycles = Math.floor(elapsed / DRAW_INTERVAL_MS); return DRAW_EPOCH + (cycles + 1) * DRAW_INTERVAL_MS; } function formatRemaining(ms: number) { if (ms <= 0) return "DRAWING SOON"; const h = Math.floor(ms / 3600000); const m = Math.floor((ms % 3600000) / 60000); const s = Math.floor((ms % 60000) / 1000); return `${h.toString().padStart(2, "0")}h ${m.toString().padStart(2, "0")}m ${s.toString().padStart(2, "0")}s`; } type Ticket = { nums: number[]; handle: string; ts: number }; function loadTickets(): Ticket[] { if (typeof window === "undefined") return []; try { return JSON.parse(localStorage.getItem(TICKET_KEY) ?? "[]") as Ticket[]; } catch { return []; } } function saveTickets(t: Ticket[]) { if (typeof window === "undefined") return; localStorage.setItem(TICKET_KEY, JSON.stringify(t.slice(-50))); } export default function LotteryPage() { const { user } = useAccount(); const [numbers, setNumbers] = useState([]); const [isDrawing, setIsDrawing] = useState(false); const [myTickets, setMyTickets] = useState([]); const [remaining, setRemaining] = useState(0); const [picked, setPicked] = useState([]); const [disclaimer, setDisclaimer] = useState(false); useEffect(() => { setMyTickets(loadTickets()); const tick = () => setRemaining(getNextDraw() - Date.now()); tick(); const id = setInterval(tick, 1000); return () => clearInterval(id); }, []); const togglePick = (n: number) => { if (picked.includes(n)) { setPicked((p) => p.filter((x) => x !== n)); } else if (picked.length < NUMBERS_COUNT) { setPicked((p) => [...p, n]); } }; const quickPick = () => { const pool = Array.from({ length: 49 }, (_, i) => i + 1); const result: number[] = []; while (result.length < NUMBERS_COUNT) { const idx = Math.floor(Math.random() * pool.length); result.push(pool.splice(idx, 1)[0]!); } setPicked(result.sort((a, b) => a - b)); }; const submitTicket = useCallback(() => { if (picked.length !== NUMBERS_COUNT) return; const ticket: Ticket = { nums: [...picked].sort((a, b) => a - b), handle: user?.username ?? "anon", ts: Date.now(), }; const updated = [...myTickets, ticket]; setMyTickets(updated); saveTickets(updated); setPicked([]); }, [picked, myTickets, user]); const drawNumbers = useCallback(() => { if (!disclaimer) { setDisclaimer(true); return; } setIsDrawing(true); setNumbers([]); let count = 0; const used = new Set(); const interval = setInterval(() => { let n: number; do { n = Math.floor(Math.random() * 49) + 1; } while (used.has(n)); used.add(n); setNumbers((prev) => [...prev, n]); count++; if (count >= NUMBERS_COUNT) { clearInterval(interval); setIsDrawing(false); } }, 400); }, [disclaimer]); const drawn = numbers.length === NUMBERS_COUNT; const myMatches = drawn ? myTickets.map((t) => ({ ticket: t, matches: t.nums.filter((n) => numbers.includes(n)).length })) : []; return (
Demo lotto — prizes are LUX credits · no real-money payouts

Shadow Lotto

Pick 6 numbers (1–49) or Quick Pick. Daily demo draw — matches earn LUX credits.

Next Draw
{formatRemaining(remaining)}
Your Tickets
{myTickets.length}
{/* Number picker */}
Pick {NUMBERS_COUNT} numbers · selected: {picked.length}/{NUMBERS_COUNT}
{Array.from({ length: 49 }, (_, i) => i + 1).map((n) => { const isSelected = picked.includes(n); const isDrawn = numbers.includes(n); return ( ); })}
{disclaimer && !drawn && (
This is a demo draw — no real prizes are awarded. LUX credit prizes are in-app only.
)} {/* Draw result */} {numbers.length > 0 && (
Draw Result
{numbers.map((n, i) => (
{n}
))}
{drawn && myMatches.length > 0 && (
Your Ticket Results
{myMatches.map((m, i) => (
{m.ticket.nums.join("-")} = 3 ? "text-[#ff00ff] font-bold" : "text-white/40"}> {m.matches} match{m.matches !== 1 ? "es" : ""} {m.matches >= 6 ? " — JACKPOT (LUX prize)" : m.matches >= 4 ? " — LUX reward" : ""}
))}
)}
)}
Shadow Lotto is a demonstration game. No real-money gambling. LUX credits are in-app only.{" "} Inner Circle →
); }