"use client"; import { CheckCircle2 } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { PixelAvatar } from "@/components/avatar/pixel-avatar"; import { WellnessSlider } from "@/components/daily-quiz/wellness-slider"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { defaultDailyQuizAnswers, formatSleepHours, SLEEP_HOURS_MAX, SLEEP_HOURS_MIN, SLEEP_HOURS_STEP, WELLNESS_SCALE_MAX, type DailyQuizAnswers, type DailyQuizSubmission, } from "@/lib/avatar-state"; import { HABIT_PET_DATA_UPDATED_EVENT } from "@/lib/app-events"; import { getAvatarConditionForToday, getDailyEntryForToday, saveDailyEntry, } from "@/lib/daily-quiz-storage"; import { JOURNAL_MAX_LENGTH } from "@/lib/journal-safety"; export function DailyQuizForm() { const [answers, setAnswers] = useState( defaultDailyQuizAnswers, ); const [journal, setJournal] = useState(""); const [submission, setSubmission] = useState( null, ); const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(null); const [isReady, setIsReady] = useState(false); const [liveCondition, setLiveCondition] = useState( submission?.condition ?? null, ); const refreshLiveCondition = useCallback(async () => { setLiveCondition(await getAvatarConditionForToday()); }, []); useEffect(() => { async function loadDailyCheckIn() { try { const existingEntry = await getDailyEntryForToday(); if (existingEntry) { setSubmission(existingEntry); setAnswers(existingEntry.answers); setJournal(existingEntry.journal); setLiveCondition(existingEntry.condition); } else { await refreshLiveCondition(); } } catch (loadError) { setError( loadError instanceof Error ? loadError.message : "Could not load today's check-in.", ); } finally { setIsReady(true); } } void loadDailyCheckIn(); }, [refreshLiveCondition]); useEffect(() => { const handleDataUpdated = () => { void refreshLiveCondition(); }; window.addEventListener(HABIT_PET_DATA_UPDATED_EVENT, handleDataUpdated); return () => { window.removeEventListener(HABIT_PET_DATA_UPDATED_EVENT, handleDataUpdated); }; }, [refreshLiveCondition]); const isCompleted = submission !== null; const canSubmit = !isCompleted && !isSubmitting; const updateAnswer = ( key: K, value: DailyQuizAnswers[K], ) => { setAnswers((current) => ({ ...current, [key]: value, })); }; const handleSubmit = async () => { if (!canSubmit) { return; } setIsSubmitting(true); setError(null); try { const savedEntry = await saveDailyEntry(answers, journal); setSubmission(savedEntry); setLiveCondition(savedEntry.condition); } catch (submitError) { setError( submitError instanceof Error ? submitError.message : "Could not save your daily check-in.", ); } finally { setIsSubmitting(false); } }; if (!isReady) { return (

Loading today's quiz...

); } return (
{isCompleted && submission ? ( <>

Today's quiz is complete

Your wellness check-in and journal are saved for today. You can review your answers below, and come back tomorrow for your next quiz.

Your pet today Based on your wellness check-in and completed habits today.

Mood

{(liveCondition ?? submission.condition).mood}

Energy

{(liveCondition ?? submission.condition).energy}/ {WELLNESS_SCALE_MAX}

Health

{(liveCondition ?? submission.condition).health}/ {WELLNESS_SCALE_MAX}

) : (
Today's check-in Not completed
)} {isCompleted ? "Your answers today" : "Wellness"} {isCompleted ? "These fields are locked until tomorrow's quiz." : "Rate your wellness from 1 to 5. Sleep length uses hours."} updateAnswer("feeling", value)} /> updateAnswer("stress", value)} /> updateAnswer("energy", value)} /> updateAnswer("sleepLength", value)} /> updateAnswer("sleepQuality", value)} /> Daily journal {isCompleted ? "Your journal entry for today." : "Write about your day."}