'use client'; import React, { createContext, useContext, useReducer, useCallback } from 'react'; import { InterviewSession, InterviewConfig, Question, ChatMessage, Evaluation, Answer, SessionSummary, } from '@/types/interview'; type InterviewAction = | { type: 'START_SESSION'; payload: { config: InterviewConfig } } | { type: 'SET_QUESTIONS'; payload: { questions: Question[] } } | { type: 'ADD_MESSAGE'; payload: { message: ChatMessage } } | { type: 'SUBMIT_ANSWER'; payload: { answer: Answer } } | { type: 'ADD_EVALUATION'; payload: { evaluation: Evaluation } } | { type: 'NEXT_QUESTION' } | { type: 'SET_STATUS'; payload: { status: InterviewSession['status'] } } | { type: 'COMPLETE_SESSION'; payload: { summary: SessionSummary } } | { type: 'RESET_SESSION' }; interface InterviewState { session: InterviewSession | null; } const initialState: InterviewState = { session: null, }; function generateId(): string { return Date.now().toString(36) + Math.random().toString(36).substring(2); } function interviewReducer(state: InterviewState, action: InterviewAction): InterviewState { switch (action.type) { case 'START_SESSION': return { session: { id: generateId(), config: action.payload.config, questions: [], answers: [], evaluations: [], messages: [], currentQuestionIndex: 0, status: 'setup', startedAt: Date.now(), }, }; case 'SET_QUESTIONS': if (!state.session) return state; return { session: { ...state.session, questions: action.payload.questions, status: 'in-progress', }, }; case 'ADD_MESSAGE': if (!state.session) return state; return { session: { ...state.session, messages: [...state.session.messages, action.payload.message], }, }; case 'SUBMIT_ANSWER': if (!state.session) return state; return { session: { ...state.session, answers: [...state.session.answers, action.payload.answer], status: 'evaluating', }, }; case 'ADD_EVALUATION': if (!state.session) return state; return { session: { ...state.session, evaluations: [...state.session.evaluations, action.payload.evaluation], status: 'in-progress', }, }; case 'NEXT_QUESTION': if (!state.session) return state; return { session: { ...state.session, currentQuestionIndex: state.session.currentQuestionIndex + 1, }, }; case 'SET_STATUS': if (!state.session) return state; return { session: { ...state.session, status: action.payload.status, }, }; case 'COMPLETE_SESSION': if (!state.session) return state; return { session: { ...state.session, status: 'completed', completedAt: Date.now(), summary: action.payload.summary, }, }; case 'RESET_SESSION': return initialState; default: return state; } } interface InterviewContextType { session: InterviewSession | null; startSession: (config: InterviewConfig) => void; setQuestions: (questions: Question[]) => void; addMessage: (message: ChatMessage) => void; submitAnswer: (answer: Answer) => void; addEvaluation: (evaluation: Evaluation) => void; nextQuestion: () => void; setStatus: (status: InterviewSession['status']) => void; completeSession: (summary: SessionSummary) => void; resetSession: () => void; } const InterviewContext = createContext(null); export function InterviewProvider({ children }: { children: React.ReactNode }) { const [state, dispatch] = useReducer(interviewReducer, initialState); const startSession = useCallback((config: InterviewConfig) => { dispatch({ type: 'START_SESSION', payload: { config } }); }, []); const setQuestions = useCallback((questions: Question[]) => { dispatch({ type: 'SET_QUESTIONS', payload: { questions } }); }, []); const addMessage = useCallback((message: ChatMessage) => { dispatch({ type: 'ADD_MESSAGE', payload: { message } }); }, []); const submitAnswer = useCallback((answer: Answer) => { dispatch({ type: 'SUBMIT_ANSWER', payload: { answer } }); }, []); const addEvaluation = useCallback((evaluation: Evaluation) => { dispatch({ type: 'ADD_EVALUATION', payload: { evaluation } }); }, []); const nextQuestion = useCallback(() => { dispatch({ type: 'NEXT_QUESTION' }); }, []); const setStatus = useCallback((status: InterviewSession['status']) => { dispatch({ type: 'SET_STATUS', payload: { status } }); }, []); const completeSession = useCallback((summary: SessionSummary) => { dispatch({ type: 'COMPLETE_SESSION', payload: { summary } }); }, []); const resetSession = useCallback(() => { dispatch({ type: 'RESET_SESSION' }); }, []); return ( {children} ); } export function useInterview() { const context = useContext(InterviewContext); if (!context) { throw new Error('useInterview must be used within an InterviewProvider'); } return context; }