import { useState, useMemo } from 'react' import './PairCards.css' function BboxOverlay({ chip, lang }) { if (!chip?.bbox) return null const { x, y, w, h } = chip.bbox const maskId = `bbmask-${chip.id.slice(0, 8)}` const label = chip[lang] || chip.de || '' const labelY = Math.min((y + h + 0.07) * 100, 93) return ( {label && ( {label} )} ) } function resolveSentence(sentence, placeholders, lang, onChipClick, activeId) { if (!sentence) return null const parts = sentence.split(/(\{\{[0-9a-f-]{36}\}\})/) return parts.map((part, i) => { const m = part.match(/^\{\{([0-9a-f-]{36})\}\}$/) if (m) { const id = m[1] const entry = placeholders?.[id] const label = entry?.[lang] || entry?.de || '…' return ( { e.stopPropagation(); onChipClick?.(id, entry) }} > {label} ) } return part }) } function shuffle(arr) { const a = [...arr] for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]] } return a } export default function PairWordCard({ card, onComplete }) { const [picked, setPicked] = useState(null) const [activeChip, setActiveChip] = useState(null) const lang = card.lang || 'de' const native = lang === 'de' ? 'en' : 'de' const isWord = activeChip && (activeChip.type === 'word' || !activeChip.bbox) const isObject = activeChip && activeChip.type === 'object' && activeChip.bbox const q = card.question const stmt = card.positive_statement const neg = card.negative_statement const sentence = q?.[`sentence_${lang}`] || q?.sentence_de const hint = q?.[`sentence_${native}`] || null const pic = card.picture?.url const options = useMemo(() => { const pos = (stmt?.positive_words || []).map(w => ({ ...w, correct: true })) const neg2 = (neg?.negative_words || []).map(w => ({ ...w, correct: false })) return shuffle([...pos, ...neg2]) }, [stmt, neg]) function handleChipClick(id, entry) { setActiveChip(prev => prev?.id === id ? null : { id, ...entry }) } function handlePick(opt) { if (picked) return setActiveChip(null) setPicked(opt) const r = opt.correct ? 'correct' : 'wrong' setTimeout(() => onComplete(r), 900) } return (
setActiveChip(null)}>
{lang.toUpperCase()} +{card.meta?.points ?? 3} Pkt
{pic ? :
🖼️
} {isWord && (
{activeChip[lang] || activeChip.de || '…'} {(activeChip[native] || activeChip.en) && ( {activeChip[native] || activeChip.en} )}
)} {isObject && }
e.stopPropagation()}>

{resolveSentence(sentence, card.placeholders, lang, handleChipClick, activeChip?.id)}

{hint && !picked && (

{resolveSentence(hint, card.placeholders, native)}

)}
{options.map((opt) => { const label = opt[lang] || opt.de || '…' const hint2 = opt[native] || null let cls = 'pair-option-btn' if (picked) { if (opt.id === picked.id) cls += opt.correct ? ' correct' : ' wrong' else if (opt.correct) cls += ' correct' } return ( ) })}
{picked && (

{picked.correct ? '✓ Richtig!' : `✗ Richtig wäre: ${options.find(o => o.correct)?.[lang] || options.find(o => o.correct)?.de || '?'}` }

)}
) }