'use client' import React, { useState, useEffect, useCallback, useMemo } from 'react' import { useParams, useRouter } from 'next/navigation' import { useTheme } from '@/lib/ThemeContext' import { useNativeLanguage } from '@/lib/useNativeLanguage' import { StarRating, accuracyToStars } from '@/components/gamification/StarRating' import { AudioButton } from '@/components/learn/AudioButton' interface QAItem { id: string; question: string; answer: string translations?: Record } function getApiBase() { return '' } export default function MatchPage() { const { unitId } = useParams<{ unitId: string }>() const router = useRouter() const { isDark } = useTheme() const { t, wordInNative, nativeLang, isThirdLanguage } = useNativeLanguage() const [allItems, setAllItems] = useState([]) const [isLoading, setIsLoading] = useState(true) const [round, setRound] = useState(0) const [selectedLeft, setSelectedLeft] = useState(null) const [matched, setMatched] = useState>(new Set()) const [wrongPair, setWrongPair] = useState(null) const [firstTryCorrect, setFirstTryCorrect] = useState(0) const [retryCorrect, setRetryCorrect] = useState(0) const [errors, setErrors] = useState(0) const [failedIds, setFailedIds] = useState>(new Set()) const [flashNative, setFlashNative] = useState(null) const [isComplete, setIsComplete] = useState(false) const glassCard = isDark ? 'bg-white/10 backdrop-blur-xl border border-white/10' : 'bg-white/80 backdrop-blur-xl border border-black/5' useEffect(() => { (async () => { try { const resp = await fetch(`${getApiBase()}/api/learning-units/${unitId}/qa`) if (resp.ok) { const d = await resp.json(); setAllItems(d.qa_items || []) } } catch {} finally { setIsLoading(false) } })() }, [unitId]) const roundItems = useMemo(() => { const start = round * 6 return allItems.slice(start, start + 6) }, [allItems, round]) const shuffledRight = useMemo(() => { return [...roundItems].sort(() => Math.random() - 0.5) }, [roundItems]) const handleLeftTap = useCallback((item: QAItem) => { if (matched.has(item.id)) return setSelectedLeft(item.id === selectedLeft ? null : item.id) setWrongPair(null) // Flash native translation briefly if (isThirdLanguage && item.id !== selectedLeft) { const native = wordInNative(item.translations) if (native) { setFlashNative(native) setTimeout(() => setFlashNative(null), 2000) } } }, [selectedLeft, matched, isThirdLanguage, wordInNative]) const handleRightTap = useCallback((id: string) => { if (!selectedLeft || matched.has(id)) return if (selectedLeft === id) { // Correct setMatched(prev => new Set([...prev, id])) if (failedIds.has(id)) { setRetryCorrect(c => c + 1) } else { setFirstTryCorrect(c => c + 1) } setSelectedLeft(null) setFlashNative(null) if (matched.size + 1 >= roundItems.length) { const nextStart = (round + 1) * 6 if (nextStart >= allItems.length) { setTimeout(() => setIsComplete(true), 500) } else { setTimeout(() => { setRound(r => r + 1) setMatched(new Set()) setSelectedLeft(null) }, 800) } } } else { // Wrong setWrongPair(id) setErrors(e => e + 1) setFailedIds(prev => new Set([...prev, selectedLeft])) setTimeout(() => { setWrongPair(null) setSelectedLeft(null) setFlashNative(null) }, 600) } }, [selectedLeft, matched, roundItems, round, allItems, failedIds]) const restart = () => { setRound(0) setMatched(new Set()) setFirstTryCorrect(0) setRetryCorrect(0) setErrors(0) setFailedIds(new Set()) setIsComplete(false) setSelectedLeft(null) } if (isLoading) { return
} const totalPairs = allItems.length const matchedTotal = round * 6 + matched.size const isPerfect = isComplete && errors === 0 return ( <> {/* Header */}

{t('match')}

{matchedTotal}/{totalPairs} · {firstTryCorrect}/{retryCorrect}/{errors}
{/* Native flash overlay */} {flashNative && (
{flashNative}
)}
{isComplete ? (

{isPerfect ? t('well_done') : t('all_matched')}

{firstTryCorrect}
{t('correct')}
{retryCorrect}
2. Versuch
{errors}
{t('errors')}
{!isPerfect && (

{isThirdLanguage ? (nativeLang === 'tr' ? 'Tam puan icin hatasiz tamamlayin' : 'Fuer volle Punkte fehlerfrei abschliessen') : 'Fuer volle Punkte fehlerfrei abschliessen'}

)}
) : (
{/* Column headers */}

{t('english')}

{t('german')}

{isThirdLanguage && (

{nativeLang.toUpperCase()}

)}
{/* Grid */}
{/* Left: English (click to select, no sound) */}
{roundItems.map(item => ( ))}
{/* Middle: German (click to match + sound) */}
{shuffledRight.map(item => (
{!matched.has(item.id) && ( )}
))}
{/* Right: Native language (display only + sound) */} {isThirdLanguage && (
{roundItems.map(item => { const native = wordInNative(item.translations) return (
{native || '—'} {native && !matched.has(item.id) && ( )}
) })}
)}
)}
) }