import React, { useState, useEffect } from "react" import { motion, AnimatePresence } from "framer-motion" import { CardType } from "../../constants/CardTypes" import { DndContext, closestCenter, PointerSensor, useSensor, useSensors } from '@dnd-kit/core' import { arrayMove, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' /** * Draggable item for sentence pairing */ const DraggableItem = ({ id, text, disabled }) => { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id, disabled }) const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, } return (
{text}
) } /** * CardDisplayModal - Kártya megjelenítése a játékos számára * * @param {Object} props * @param {boolean} props.isOpen - Modal megjelenítése * @param {Function} props.onClose - Modal bezárása * @param {Object} props.card - Kártya adatok * @param {string} props.cardType - Kártya típusa (QUESTION, LUCK, JOKER) * @param {Function} props.onSubmitAnswer - Válasz beküldése (csak QUESTION típusnál) * @param {number} props.timeLimit - Időkorlát másodpercben (default: 60) * @param {boolean} props.isMyTurn - Whether this is the active player (can answer) or spectator (read-only) * @param {string} props.submittedAnswer - For spectators, shows what the active player answered */ const CardDisplayModal = ({ isOpen, onClose, card, cardType = "QUESTION", onSubmitAnswer, timeLimit = 60, isMyTurn = true, submittedAnswer = null }) => { const [playerAnswer, setPlayerAnswer] = useState("") const [selectedOption, setSelectedOption] = useState(null) const [timeLeft, setTimeLeft] = useState(timeLimit) const [isProcessing, setIsProcessing] = useState(false) // For sentence pairing drag and drop const [rightItems, setRightItems] = useState([]) const sensors = useSensors(useSensor(PointerSensor)) // Timer countdown (only for active player) useEffect(() => { if (!isOpen || cardType !== "QUESTION" || !isMyTurn) return setTimeLeft(timeLimit) const timer = setInterval(() => { setTimeLeft(prev => { if (prev <= 1) { clearInterval(timer) handleTimeout() return 0 } return prev - 1 }) }, 1000) return () => clearInterval(timer) }, [isOpen, timeLimit, isMyTurn]) // Reset state when modal opens useEffect(() => { if (isOpen) { setPlayerAnswer("") setSelectedOption(null) setIsProcessing(false) // Initialize sentence pairing right items if (card?.sentencePairs && card.sentencePairs.length > 0) { setRightItems(card.sentencePairs.map(p => ({ id: p.id, text: p.right }))) } } }, [isOpen, card]) const handleTimeout = () => { if (onSubmitAnswer) { onSubmitAnswer(null) // null = timeout } } const handleSubmit = async () => { if (isProcessing || !isMyTurn) return let answer = null // Different answer formats based on card type if (card?.type === CardType.SENTENCE_PAIRING && card?.sentencePairs) { // Answer is array of pairs answer = card.sentencePairs.map((leftPair, index) => ({ pairId: leftPair.id, leftText: leftPair.left, rightText: rightItems[index].text })) } else if (selectedOption !== null) { answer = selectedOption } else { answer = playerAnswer.trim() } if (!answer || (Array.isArray(answer) && answer.length === 0)) { console.warn('⚠️ No answer provided') return } console.log('📝 Submitting answer:', answer) setIsProcessing(true) try { await onSubmitAnswer(answer) } catch (error) { console.error("❌ Válasz küldési hiba:", error) setIsProcessing(false) } } const handleDragEnd = (event) => { const { active, over } = event if (active.id !== over.id) { setRightItems((items) => { const oldIndex = items.findIndex(item => item.id === active.id) const newIndex = items.findIndex(item => item.id === over.id) return arrayMove(items, oldIndex, newIndex) }) } } const getCardIcon = () => { switch (cardType) { case "QUESTION": return "❓" case "LUCK": return "🍀" case "JOKER": return "🃏" default: return "📝" } } const getCardTitle = () => { switch (cardType) { case "QUESTION": return "Feladat Kártya" case "LUCK": return "Szerencse Kártya" case "JOKER": return "Joker Kártya Feladat" default: return "Kártya" } } const getCardBgGradient = () => { switch (cardType) { case "QUESTION": return "from-blue-600 via-purple-600 to-blue-600" case "LUCK": return "from-green-600 via-teal-600 to-green-600" case "JOKER": return "from-purple-600 via-pink-600 to-purple-600" default: return "from-gray-600 via-gray-700 to-gray-600" } } const formatTime = (seconds) => { const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins}:${secs.toString().padStart(2, '0')}` } const getTimeColor = () => { if (timeLeft > 30) return "text-green-400" if (timeLeft > 10) return "text-yellow-400" return "text-red-400 animate-pulse" } if (!isOpen || !card) return null return ( {isOpen && (
{/* Backdrop */} {/* Modal Content */} {/* Header */}
{getCardIcon()}

{getCardTitle()}

{cardType === "QUESTION" && (

{isMyTurn ? "Válaszolj a kérdésre!" : "Néző mód - Várakozás a játékosra"}

)} {cardType === "JOKER" && (

{isMyTurn ? "Gamemaster jóváhagyás szükséges" : "Várakozás a Gamemaster döntésére"}

)}
{/* Timer - csak QUESTION típusnál és aktív játékosnál */} {cardType === "QUESTION" && isMyTurn && (
⏱️ {formatTime(timeLeft)}
)}
{/* Content */}
{/* JOKER CARD SPECIFIC LAYOUT */} {cardType === "JOKER" ? ( <> {/* Player Info */}
{card.playerEmoji || "🎭"}

Játékos

{card.playerName}

{/* Joker Card Details */}
🎯

Feladat címe

{card.question || "Joker Kártya Feladat"}

{card.consequence && (
📝

Feladat leírása

{card.consequence}

)} {/* Points Info (if available) */} {card.points && (
{card.points} pont járható érte
)}
{/* Waiting for gamemaster message */} {card.waitingForGamemaster && (
ℹ️

Várakozás: A Gamemaster döntése szükséges a folytatáshoz.

)} ) : ( <> {/* REGULAR CARD LAYOUT */} {/* Spectator Notice */} {!isMyTurn && (

👀 Néző módban vagy

Várakozás a játékos válaszára...

)} {/* Question/Text */}
📝

{card.question || card.text || card.statement}

)} {/* QUIZ TYPE - Four Buttons (A, B, C, D) */} {cardType === "QUESTION" && card.type === CardType.QUIZ && card.answerOptions && card.answerOptions.length > 0 && (

{isMyTurn ? "Válaszd ki a helyes választ:" : "Válasz lehetőségek:"}

{card.answerOptions.map((option, index) => ( ))}
{!isMyTurn && submittedAnswer && (

ℹ️ A játékos választása: {submittedAnswer}

)}
)} {/* TRUE/FALSE TYPE - Two Buttons */} {cardType === "QUESTION" && card.type === CardType.TRUE_FALSE && (

{isMyTurn ? "Igaz vagy Hamis?" : "Válasz lehetőségek:"}

{!isMyTurn && submittedAnswer && (

ℹ️ A játékos választása: {submittedAnswer}

)}
)} {/* SENTENCE_PAIRING TYPE - Drag and Drop */} {cardType === "QUESTION" && card.type === CardType.SENTENCE_PAIRING && card.sentencePairs && card.sentencePairs.length > 0 && (

{isMyTurn ? "Párosítsd a mondatokat! (Húzd a jobb oldali elemeket)" : "Mondatpárosítás:"}

{/* Left column - fixed */}

Bal oldal

{card.sentencePairs.map((pair, index) => (
{pair.left}
))}
{/* Right column - draggable */}

{isMyTurn ? "Jobb oldal (húzható)" : "Jobb oldal"}

item.id)} strategy={verticalListSortingStrategy} disabled={!isMyTurn} > {rightItems.map((item) => ( ))}
{!isMyTurn && (

ℹ️ Várakozás a játékos párosítására...

)}
)} {/* OWN_ANSWER and CLOSER - Text Input */} {cardType === "QUESTION" && (card.type === CardType.OWN_ANSWER || card.type === CardType.CLOSER) && (

{isMyTurn ? "Írd be a választ:" : "A játékos válasza:"}

isMyTurn && setPlayerAnswer(e.target.value)} onKeyPress={(e) => isMyTurn && e.key === 'Enter' && !isProcessing && playerAnswer.trim() && handleSubmit()} disabled={!isMyTurn || isProcessing} placeholder={card.type === CardType.CLOSER ? "Számot adj meg" : "Válaszod..."} className={`w-full bg-gray-800 border-2 border-gray-600 rounded-lg px-4 py-3 text-white focus:border-purple-500 focus:outline-none disabled:opacity-50 ${ !isMyTurn ? "cursor-default" : "" }`} />
)} {/* Hint (if available) */} {card.hint && isMyTurn && (
💡

Segítség

{card.hint}

)} {/* Submit Button - csak QUESTION típusnál és aktív játékosnál */} {cardType === "QUESTION" && isMyTurn && ( )} {/* Close Button - LUCK és JOKER típusnál vagy nézőknél */} {((cardType === "LUCK" || cardType === "JOKER") || !isMyTurn) && ( )}
)} ) } export default CardDisplayModal