// static/js/testRunner.jsx

function TestRunner({ testId }) {
    const { token, setView } = useContext(AuthContext);
    const [loading, setLoading] = useState(true);
    const [testData, setTestData] = useState(null);
    const [currentQIndex, setCurrentQIndex] = useState(0);
    const [answers, setAnswers] = useState({});
    const [qStartTime, setQStartTime] = useState(Date.now());

    const [elapsedSeconds, setElapsedSeconds] = useState(0);
    const [autoFinished, setAutoFinished] = useState(false);

    const formatTime = (secs) => {
        const m = Math.floor(secs / 60);
        const s = secs % 60;
        return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
    };

    // запуск теста
    useEffect(() => {
        setLoading(true);

        (async () => {
            try {
                const data = await API.userStartTest(token, testId);
                console.log('TEST DATA FROM SERVER:', data);
                setTestData(data);
                setQStartTime(Date.now());
            } catch (err) {
                console.error(err);
                alert(err.message || 'Не удалось запустить тест');
                setView('dashboard');
            } finally {
                setLoading(false);
            }
        })();
    }, [testId, token, setView]);

    // таймер
    useEffect(() => {
        if (!testData) return;

        setElapsedSeconds(0);

        const timerId = setInterval(() => {
            setElapsedSeconds(prev => prev + 1);
        }, 1000);

        return () => clearInterval(timerId);
    }, [testData]);

    // авто-завершение при окончании времени
    useEffect(() => {
        if (!testData) return;

        const timeLimitSeconds = (testData.time_limit || 0) * 60;
        if (!timeLimitSeconds) return;

        if (elapsedSeconds >= timeLimitSeconds && !autoFinished) {
            setAutoFinished(true);
            handleNext(true);
        }
    }, [elapsedSeconds, testData, autoFinished]);

    const handleNext = async (finish = false) => {
        const q = testData.questions[currentQIndex];
        const ans = answers[q.id] || { selected: [], text: "" };
        const timeSpent = Math.round((Date.now() - qStartTime) / 1000);

        try {
            await API.userSubmitAnswer(token, testData.attempt_id, {
                question_id: q.id,
                selected_options: ans.selected || [],
                text_answer: ans.text || "",
                time_spent: timeSpent,
            });
        } catch (e) {
            console.error(e);
            alert('Ошибка отправки ответа');
        }

        if (finish) {
            finishTest();
        } else {
            setCurrentQIndex(prev => prev + 1);
            setQStartTime(Date.now());
        }
    };

    const finishTest = async () => {
        if (!testData) return;

        try {
            const res = await API.userFinishAttempt(token, testData.attempt_id);

            const percentStr = (typeof res.percent === 'number')
                ? res.percent.toFixed(1)
                : '—';

            let msg = `Тест завершен! Результат: ${res.passed ? 'СДАЛ' : 'НЕ СДАЛ'}.`;

            if (typeof res.score === 'number') {
                if (typeof res.max_score === 'number' && res.max_score > 0) {
                    msg += `\nБаллы: ${res.score} из ${res.max_score} (${percentStr}%).`;
                } else {
                    msg += `\nБаллы: ${res.score} (${percentStr}%).`;
                }
            }

            if (typeof res.correct_questions === 'number' && typeof res.total_questions === 'number') {
                msg += `\nПравильных ответов: ${res.correct_questions} из ${res.total_questions}.`;
            }

            alert(msg);
            setView('dashboard');
        } catch (err) {
            console.error(err);
            alert('Ошибка завершения теста');
            setView('dashboard');
        }
    };

    if (loading || !testData) {
        return (
            <div className="flex justify-center mt-20">
                <div className="spinner"></div>
            </div>
        );
    }

    const currentQ = testData.questions[currentQIndex];
    const isLast = currentQIndex === testData.questions.length - 1;
    const qType = currentQ.type || currentQ.q_type;

    let hintText = "";
    if (qType === 'single') {
        hintText = "нужно выбрать 1 вариант";
    } else if (qType === 'multi') {
        hintText = "нужно выбрать один или несколько вариантов";
    } else if (qType === 'text_short' || qType === 'text_long') {
        hintText = "нужно ввести ответ текстом";
    }

    const timeLimitSeconds = (testData.time_limit || 0) * 60;
    const totalStr = timeLimitSeconds ? formatTime(timeLimitSeconds) : null;
    const remaining = timeLimitSeconds
        ? Math.max(timeLimitSeconds - elapsedSeconds, 0)
        : 0;
    const remainingStr = timeLimitSeconds ? formatTime(remaining) : null;

    const isTimeAlmostOver = timeLimitSeconds && remaining <= 60;

    return (
        <div className="max-w-3xl mx-auto bg-white p-8 rounded shadow-lg">
            <div className="flex justify-between items-center mb-6">
                <div className="text-sm text-gray-600">
                    Вопрос <span className="font-semibold">{currentQIndex + 1}</span> из{" "}
                    <span className="font-semibold">{testData.questions.length}</span>
                </div>

                <div className="text-right">
                    {timeLimitSeconds ? (
                        <>
                            <div className="text-xs uppercase text-gray-400 tracking-wide">
                                Оставшееся время
                            </div>
                            <div
                                className={
                                    "font-mono font-extrabold " +
                                    (isTimeAlmostOver ? "text-red-600 text-3xl" : "text-gray-800 text-3xl")
                                }
                            >
                                {remainingStr} / {totalStr}
                            </div>
                        </>
                    ) : (
                        <div className="text-xs text-gray-500">
                            Без ограничения времени
                        </div>
                    )}
                </div>
            </div>

            <h3 className="text-xl font-bold mb-2">{currentQ.text}</h3>
            {hintText && (
                <p className="text-sm text-gray-500 mb-4">
                    ({hintText})
                </p>
            )}

            <div className="space-y-3 mb-8">
                {qType === 'single' && currentQ.options.map(opt => (
                    <label
                        key={opt.id}
                        className="flex items-center p-3 border rounded cursor-pointer hover:bg-gray-50"
                    >
                        <input
                            type="radio"
                            name="opt"
                            className="mr-3 h-5 w-5"
                            checked={(answers[currentQ.id]?.selected || []).includes(opt.id)}
                            onChange={() =>
                                setAnswers({
                                    ...answers,
                                    [currentQ.id]: { selected: [opt.id], text: "" }
                                })
                            }
                        />
                        {opt.text}
                    </label>
                ))}

                {qType === 'multi' && currentQ.options.map(opt => (
                    <label
                        key={opt.id}
                        className="flex items_center p-3 border rounded cursor-pointer hover:bg-gray-50"
                    >
                        <input
                            type="checkbox"
                            className="mr-3 h-5 w-5"
                            checked={(answers[currentQ.id]?.selected || []).includes(opt.id)}
                            onChange={(e) => {
                                const old = answers[currentQ.id]?.selected || [];
                                const next = e.target.checked
                                    ? [...old, opt.id]
                                    : old.filter(id => id !== opt.id);
                                setAnswers({
                                    ...answers,
                                    [currentQ.id]: { selected: next, text: answers[currentQ.id]?.text || "" }
                                });
                            }}
                        />
                        {opt.text}
                    </label>
                ))}

                {(qType === 'text_short' || qType === 'text_long') && (
                    <textarea
                        className="w-full border p-3 rounded"
                        rows="4"
                        placeholder="Введите ваш ответ..."
                        value={answers[currentQ.id]?.text || ""}
                        onChange={(e) =>
                            setAnswers({
                                ...answers,
                                [currentQ.id]: {
                                    text: e.target.value,
                                    selected: []
                                }
                            })
                        }
                    ></textarea>
                )}
            </div>

            <div className="flex justify-end">
                <button
                    onClick={() => handleNext(isLast)}
                    className="bg-blue-600 text-white px-6 py-2 rounded font-bold hover:bg-blue-700"
                    disabled={timeLimitSeconds && remaining === 0}
                >
                    {isLast ? 'Завершить тест' : 'Следующий вопрос'}
                </button>
            </div>
        </div>
    );
}
