'use client'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { MathBlock } from '@/components/math/MathFormula'; import { Lightbulb, Eye, Sparkles } from 'lucide-react'; import { cn } from '@/lib/utils'; /** * Hint data interface */ export interface Hint { id: string; content: string; isMath?: boolean; cost?: number; } /** * HintSystem component props */ export interface HintSystemProps { /** * Array of hints */ hints: Hint[]; /** * Current points */ currentPoints?: number; /** * Points penalty per hint */ pointsPerHint?: number; /** * Revealed hint indices */ revealedHints?: Set; /** * On hint reveal callback */ onRevealHint?: (index: number, cost: number) => void; /** * Additional CSS classes */ className?: string; /** * Compact mode */ compact?: boolean; } /** * HintSystem component - displays hints with point costs */ export function HintSystem({ hints, currentPoints, pointsPerHint = 5, revealedHints = new Set(), onRevealHint, className, compact = false, }: HintSystemProps) { const [showAll] = useState(false); if (hints.length === 0) { return null; } const canAffordHint = (hintIndex: number) => { if (!currentPoints) return true; const alreadyRevealed = Array.from(revealedHints).filter((i) => i <= hintIndex).length; const cost = (alreadyRevealed + 1) * pointsPerHint; return currentPoints >= cost; }; const getHintCost = (hintIndex: number) => { const alreadyRevealed = Array.from(revealedHints).filter((i) => i <= hintIndex).length; return (alreadyRevealed + 1) * pointsPerHint; }; const handleRevealHint = (index: number) => { if (onRevealHint) { onRevealHint(index, getHintCost(index)); } }; const allRevealed = revealedHints.size === hints.length; const hasUnrevealed = hints.length > revealedHints.size; return (
Hints
{hasUnrevealed && !compact && (
{revealedHints.size}/{hints.length} revealed
)}
{!compact && ( {currentPoints !== undefined && ( Cost: {pointsPerHint} points per hint (progressive) )} {currentPoints === undefined && Click to reveal hints} )}
{hints.map((hint, index) => { const isRevealed = revealedHints.has(index); const cost = getHintCost(index); const canAfford = canAffordHint(index); if (!showAll && !isRevealed && index > 0 && !revealedHints.has(index - 1)) { // Hide hints that are not yet available (sequential reveal) return null; } return (
{index + 1}
{isRevealed ? (
{hint.isMath ? ( ) : (

{hint.content}

)} {hint.cost && (
Cost: {hint.cost} points
)}
) : (

Hint #{index + 1} -{' '} {currentPoints !== undefined ? ( canAfford ? ( Reveal for {cost} points ) : ( Need {cost - currentPoints} more points ) ) : ( Click to reveal )}

{onRevealHint && ( )}
)}
); })} {allRevealed && (

All hints revealed!

)}
); } /** * Compact hint button for inline display */ export interface HintButtonProps { hintCount: number; revealedCount: number; onClick?: () => void; className?: string; } export function HintButton({ hintCount, revealedCount, onClick, className }: HintButtonProps) { return ( ); }