"use client"; import { useRouter } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; import { GoArrowLeft, GoArrowRight } from "react-icons/go"; import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler"; import { useI18n } from "@/translations/provider"; import Button from "./button"; import { ExplanationUiFont } from "./explanation-ui-font"; import NavigationButton from "./navigation-button"; import { PageBackground } from "./page-background"; import StickyHeader from "./sticky-header"; import TestExitSheet from "./test-exit-sheet"; import TestLoadingScreen from "./test-loading-screen"; export type QuestionOption = { id: string; label: string; value: string | number; }; export type TestQuestion = { id: number; text: string; info?: string; options: QuestionOption[]; }; type TestQuestionsFlowProps = { title: string; questions: TestQuestion[]; closeLabel: string; informationLabel: string; previousLabel?: string; finishLabel?: string; stepsLabel?: string; onFinish?: (answers: Record) => void; onClose?: () => void; draftStorageKey?: string | null; }; function formatOptionLabel(str: string): string { if (!str) return str; let result = str.trim(); // Remove trailing numbers in parentheses, e.g., (1) or (۱) result = result.replace(/\s*\([\d۱۲۳۴۵۶۷۸۹۰]+\)\s*$/, ""); if (result.startsWith(")")) { result = result.slice(1).trim(); } if (result.endsWith("(")) { result = result.slice(0, -1).trim(); } let openCount = 0; let closeCount = 0; for (let i = 0; i < result.length; i++) { if (result[i] === "(") openCount++; else if (result[i] === ")") closeCount++; } if (openCount > closeCount) { result = result + ")".repeat(openCount - closeCount); } else if (closeCount > openCount) { result = "(".repeat(closeCount - openCount) + result; } if (result.length > 0) { result = result.charAt(0).toUpperCase() + result.slice(1); } return result; } export default function TestQuestionsFlow({ title, questions, closeLabel, informationLabel, previousLabel = "Previous", finishLabel = "Finish", stepsLabel = "Steps", onFinish, onClose, draftStorageKey, }: TestQuestionsFlowProps) { const router = useRouter(); const { locale } = useI18n(); const [currentIndex, setCurrentIndex] = useState(0); const [answers, setAnswers] = useState>({}); const [isSubmitting, setIsSubmitting] = useState(false); const [isExitSheetOpen, setIsExitSheetOpen] = useState(false); const isTargetTest = !!draftStorageKey && (draftStorageKey.includes("personality_test") || draftStorageKey.includes("glasser_5_needs_test")); const [maxVisitedIndex, setMaxVisitedIndex] = useState(0); useEffect(() => { if (Object.keys(answers).length === 0) { setMaxVisitedIndex(currentIndex); } else if (currentIndex > maxVisitedIndex) { setMaxVisitedIndex(currentIndex); } }, [currentIndex, answers, maxVisitedIndex]); const handleRequestClose = useCallback(() => { setIsExitSheetOpen(true); }, []); useHardwareBackHandler(() => { if (isExitSheetOpen) { setIsExitSheetOpen(false); return true; } setIsExitSheetOpen(true); return true; }, true); const handleConfirmExit = useCallback(() => { if (draftStorageKey) { try { window.localStorage.removeItem(draftStorageKey); } catch {} } if (typeof window !== "undefined") { try { window.localStorage.removeItem("marriage:tests:personality_test:draft"); window.localStorage.removeItem("marriage:tests:glasser_5_needs_test:draft"); } catch {} } setAnswers({}); setCurrentIndex(0); setIsExitSheetOpen(false); if (onClose) { onClose(); } else { router.back(); } }, [draftStorageKey, onClose, router]); const currentQuestion = questions[currentIndex] ?? questions[0]; const totalQuestions = questions.length; const isLastQuestion = currentIndex === totalQuestions - 1; const selectedValue = currentQuestion ? answers[currentQuestion.id] : undefined; const handleOptionSelect = (value: string | number) => { if (!currentQuestion) return; setAnswers((prev) => ({ ...prev, [currentQuestion.id]: value, })); // Auto advance to next question if not on last question with slide animation if (!isLastQuestion) { setTimeout(() => { setCurrentIndex((prev) => Math.min(prev + 1, totalQuestions - 1)); }, 200); } }; const handlePrev = () => { setCurrentIndex((prev) => Math.max(prev - 1, 0)); }; const handleNext = () => { setCurrentIndex((prev) => Math.min(prev + 1, totalQuestions - 1)); }; const handleFinishSubmit = async () => { if (isSubmitting) return; setIsSubmitting(true); try { if (onFinish) { await onFinish(answers); } if (draftStorageKey) { try { window.localStorage.removeItem(draftStorageKey); } catch {} } if (typeof window !== "undefined") { try { window.localStorage.removeItem("marriage:tests:personality_test:draft"); window.localStorage.removeItem("marriage:tests:glasser_5_needs_test:draft"); } catch {} } if (onClose) { onClose(); } else { router.back(); } } catch { // ignore } finally { setIsSubmitting(false); } }; if (isSubmitting) { return ( ); } if (!currentQuestion) { return null; } const progressPercent = (((isTargetTest ? maxVisitedIndex : currentIndex) + 1) / totalQuestions) * 100; const areAllQuestionsAnswered = questions.every( (question) => answers[question.id] !== undefined, ); return ( <>
{/* Header */}

{title}

{/* Content Area */}
{/* Progress Section */}
{stepsLabel} {currentIndex + 1} /{totalQuestions}
{/* Progress Track & Fill */}
{/* Question Slider Viewport */}
{questions.map((q, index) => { const offset = index - currentIndex; const isNearby = Math.abs(offset) <= 1; if (!isNearby) return null; const qSelectedValue = answers[q.id]; const options = q.options || []; return (
{/* Question Title */}

{q.text}

{/* Answer Options Stack */}
{options.map((option) => { const isSelected = qSelectedValue === option.value; return ( ); })}
); })}
{/* Bottom Actions Bar */}
{/* Previous Button */} {/* Next Button */} {isTargetTest && !isLastQuestion && selectedValue !== undefined && currentIndex < maxVisitedIndex && ( )} {/* Finish Button on Last Question */} {isLastQuestion ? ( ) : null}
setIsExitSheetOpen(false)} onConfirmExit={handleConfirmExit} /> ); }