'use client' import React, { useState, useCallback, useEffect, useMemo } from 'react' import type { ScopeProfilingAnswer, ScopeProfilingQuestion } from '@/lib/sdk/compliance-scope-types' import { SCOPE_QUESTION_BLOCKS, getBlockProgress, getTotalProgress, getAnswerValue, prefillFromCompanyProfile, getProfileInfoForBlock, getAutoFilledScoringAnswers, getUnansweredRequiredQuestions } from '@/lib/sdk/compliance-scope-profiling' import type { ScopeQuestionBlockId } from '@/lib/sdk/compliance-scope-types' import { useSDK } from '@/lib/sdk' interface ScopeWizardTabProps { answers: ScopeProfilingAnswer[] onAnswersChange: (answers: ScopeProfilingAnswer[]) => void onEvaluate: () => void canEvaluate: boolean isEvaluating: boolean completionStats: { total: number; answered: number; percentage: number; isComplete: boolean } } export function ScopeWizardTab({ answers, onAnswersChange, onEvaluate, canEvaluate, isEvaluating, completionStats, }: ScopeWizardTabProps) { const [currentBlockIndex, setCurrentBlockIndex] = useState(0) const [expandedHelp, setExpandedHelp] = useState>(new Set()) const currentBlock = SCOPE_QUESTION_BLOCKS[currentBlockIndex] const totalProgress = getTotalProgress(answers) // Load companyProfile from SDK context const { state: sdkState } = useSDK() const companyProfile = sdkState.companyProfile // Track which question IDs were prefilled from profile const [prefilledIds, setPrefilledIds] = useState>(new Set()) // Auto-prefill from company profile on mount if answers are empty useEffect(() => { if (companyProfile && answers.length === 0) { const prefilled = prefillFromCompanyProfile(companyProfile) // Also inject auto-filled scoring answers for questions removed from UI const autoFilled = getAutoFilledScoringAnswers(companyProfile) const allPrefilled = [...prefilled, ...autoFilled] if (allPrefilled.length > 0) { onAnswersChange(allPrefilled) setPrefilledIds(new Set(allPrefilled.map(a => a.questionId))) } } // Only run on mount // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const handleAnswerChange = useCallback( (questionId: string, value: string | string[] | boolean | number) => { const existingIndex = answers.findIndex((a) => a.questionId === questionId) if (existingIndex >= 0) { const newAnswers = [...answers] newAnswers[existingIndex] = { questionId, value } onAnswersChange(newAnswers) } else { onAnswersChange([...answers, { questionId, value }]) } // Remove from prefilled set when user manually changes if (prefilledIds.has(questionId)) { setPrefilledIds(prev => { const next = new Set(prev) next.delete(questionId) return next }) } }, [answers, onAnswersChange, prefilledIds] ) const handlePrefillFromProfile = useCallback(() => { if (!companyProfile) return const prefilled = prefillFromCompanyProfile(companyProfile) const autoFilled = getAutoFilledScoringAnswers(companyProfile) const allPrefilled = [...prefilled, ...autoFilled] // Merge with existing answers: prefilled values for questions not yet answered const existingIds = new Set(answers.map(a => a.questionId)) const newAnswers = [...answers] const newPrefilledIds = new Set(prefilledIds) for (const pa of allPrefilled) { if (!existingIds.has(pa.questionId)) { newAnswers.push(pa) newPrefilledIds.add(pa.questionId) } } onAnswersChange(newAnswers) setPrefilledIds(newPrefilledIds) }, [companyProfile, answers, onAnswersChange, prefilledIds]) const handleNext = useCallback(() => { if (currentBlockIndex < SCOPE_QUESTION_BLOCKS.length - 1) { setCurrentBlockIndex(currentBlockIndex + 1) } else if (canEvaluate) { onEvaluate() } }, [currentBlockIndex, canEvaluate, onEvaluate]) const handleBack = useCallback(() => { if (currentBlockIndex > 0) { setCurrentBlockIndex(currentBlockIndex - 1) } }, [currentBlockIndex]) const toggleHelp = useCallback((questionId: string) => { setExpandedHelp(prev => { const next = new Set(prev) if (next.has(questionId)) { next.delete(questionId) } else { next.add(questionId) } return next }) }, []) // Check if a question was prefilled from company profile const isPrefilledFromProfile = useCallback((questionId: string) => { return prefilledIds.has(questionId) }, [prefilledIds]) const renderHelpText = (question: ScopeProfilingQuestion) => { if (!question.helpText) return null return ( <> {expandedHelp.has(question.id) && (
{question.helpText}
)} ) } const renderPrefilledBadge = (questionId: string) => { if (!isPrefilledFromProfile(questionId)) return null return ( Aus Profil ) } const renderQuestion = (question: ScopeProfilingQuestion) => { const currentValue = getAnswerValue(answers, question.id) switch (question.type) { case 'boolean': return (
{question.question} {question.required && *} {renderPrefilledBadge(question.id)} {renderHelpText(question)}
) case 'single': return (
{question.question} {question.required && *} {renderPrefilledBadge(question.id)} {renderHelpText(question)}
{question.options?.map((option) => ( ))}
) case 'multi': return (
{question.question} {question.required && *} {renderPrefilledBadge(question.id)} {renderHelpText(question)}
{question.options?.map((option) => { const selectedValues = Array.isArray(currentValue) ? currentValue as string[] : [] const isChecked = selectedValues.includes(option.value) return ( ) })}
) case 'number': return (
{question.question} {question.required && *} {renderPrefilledBadge(question.id)} {renderHelpText(question)}
handleAnswerChange(question.id, parseInt(e.target.value, 10))} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="Zahl eingeben" />
) case 'text': return (
{question.question} {question.required && *} {renderPrefilledBadge(question.id)} {renderHelpText(question)}
handleAnswerChange(question.id, e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="Text eingeben" />
) default: return null } } return (
{/* Left Sidebar - Block Navigation */}

Fortschritt

{SCOPE_QUESTION_BLOCKS.map((block, idx) => { const progress = getBlockProgress(answers, block.id) const isActive = idx === currentBlockIndex const unanswered = getUnansweredRequiredQuestions(answers, block.id) const hasRequired = block.questions.some(q => q.required) const allRequiredDone = hasRequired && unanswered.length === 0 return ( ) })}
{/* Main Content Area */}
{/* Progress Bar */}
Gesamtfortschritt
{completionStats.answered} / {completionStats.total} Fragen {totalProgress}%
{/* Clickable unanswered required questions summary */} {(() => { const allUnanswered = getUnansweredRequiredQuestions(answers) if (allUnanswered.length === 0) return null // Group by block const byBlock = new Map() for (const item of allUnanswered) { if (!byBlock.has(item.blockId)) { const blockIndex = SCOPE_QUESTION_BLOCKS.findIndex(b => b.id === item.blockId) byBlock.set(item.blockId, { blockTitle: item.blockTitle, blockIndex, count: 0 }) } byBlock.get(item.blockId)!.count++ } return (
⚠ Offene Pflichtfragen: {Array.from(byBlock.entries()).map(([blockId, info], i) => ( {i > 0 && ·} ))}
) })()}
{/* Current Block */}

{currentBlock.title}

{currentBlock.description}

{companyProfile && ( )}
{/* "Aus Profil" Info Box — shown for blocks that have auto-filled data */} {companyProfile && (() => { const profileItems = getProfileInfoForBlock(companyProfile, currentBlock.id as ScopeQuestionBlockId) if (profileItems.length === 0) return null return (

Aus Unternehmensprofil

{profileItems.map(item => ( {item.label}: {item.value} ))}
Profil bearbeiten
) })()} {/* Questions */}
{currentBlock.questions.map((question) => { const isAnswered = answers.some(a => a.questionId === question.id) const borderClass = question.required ? isAnswered ? 'border-l-4 border-l-green-400 pl-4' : 'border-l-4 border-l-orange-400 pl-4' : '' return (
{renderQuestion(question)}
) })}
{/* Navigation Buttons */}
Block {currentBlockIndex + 1} von {SCOPE_QUESTION_BLOCKS.length} {currentBlockIndex === SCOPE_QUESTION_BLOCKS.length - 1 ? ( ) : ( )}
) }