import { createContext, useContext, useState, useCallback, ReactNode } from 'react' import { klausurApi, Klausur, StudentKlausur } from '../services/api' interface KlausurContextType { klausuren: Klausur[] currentKlausur: Klausur | null currentStudent: StudentKlausur | null loading: boolean error: string | null loadKlausuren: () => Promise selectKlausur: (id: string, keepStudent?: boolean) => Promise selectStudent: (id: string) => void setStudentById: (id: string) => void refreshAndSelectStudent: (klausurId: string, studentId: string) => Promise createKlausur: (data: Partial) => Promise deleteKlausur: (id: string) => Promise updateCriteria: (studentId: string, criterion: string, score: number) => Promise } const KlausurContext = createContext(null) export function KlausurProvider({ children }: { children: ReactNode }) { const [klausuren, setKlausuren] = useState([]) const [currentKlausur, setCurrentKlausur] = useState(null) const [currentStudent, setCurrentStudent] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const loadKlausuren = useCallback(async () => { setLoading(true) setError(null) try { const data = await klausurApi.listKlausuren() setKlausuren(data) } catch (e) { setError(e instanceof Error ? e.message : 'Failed to load Klausuren') } finally { setLoading(false) } }, []) const selectKlausur = useCallback(async (id: string, keepStudent = false) => { setLoading(true) setError(null) try { const klausur = await klausurApi.getKlausur(id) setCurrentKlausur(klausur) // Optionally keep the current student selection (for refresh after save) if (keepStudent && currentStudent) { const updatedStudent = klausur.students.find(s => s.id === currentStudent.id) setCurrentStudent(updatedStudent || null) } else if (!keepStudent) { setCurrentStudent(null) } } catch (e) { setError(e instanceof Error ? e.message : 'Failed to load Klausur') } finally { setLoading(false) } }, [currentStudent]) const selectStudent = useCallback((id: string) => { if (!currentKlausur) return const student = currentKlausur.students.find(s => s.id === id) setCurrentStudent(student || null) }, [currentKlausur]) // Set student directly by ID (for cases where we need to set before state updates) const setStudentById = useCallback((id: string) => { if (!currentKlausur) return const student = currentKlausur.students.find(s => s.id === id) if (student) { setCurrentStudent(student) } }, [currentKlausur]) // Combined refresh and select - useful after upload const refreshAndSelectStudent = useCallback(async (klausurId: string, studentId: string) => { setLoading(true) setError(null) try { const klausur = await klausurApi.getKlausur(klausurId) setCurrentKlausur(klausur) const student = klausur.students.find(s => s.id === studentId) if (student) { setCurrentStudent(student) } } catch (e) { setError(e instanceof Error ? e.message : 'Failed to load Klausur') } finally { setLoading(false) } }, []) const createKlausur = useCallback(async (data: Partial) => { setLoading(true) setError(null) try { const klausur = await klausurApi.createKlausur(data) setKlausuren(prev => [...prev, klausur]) return klausur } catch (e) { setError(e instanceof Error ? e.message : 'Failed to create Klausur') throw e } finally { setLoading(false) } }, []) const deleteKlausur = useCallback(async (id: string) => { setLoading(true) setError(null) try { await klausurApi.deleteKlausur(id) setKlausuren(prev => prev.filter(k => k.id !== id)) if (currentKlausur?.id === id) { setCurrentKlausur(null) setCurrentStudent(null) } } catch (e) { setError(e instanceof Error ? e.message : 'Failed to delete Klausur') throw e } finally { setLoading(false) } }, [currentKlausur]) const updateCriteria = useCallback(async (studentId: string, criterion: string, score: number) => { try { const updated = await klausurApi.updateCriteria(studentId, criterion, score) if (currentKlausur) { setCurrentKlausur({ ...currentKlausur, students: currentKlausur.students.map(s => s.id === studentId ? updated : s ) }) } if (currentStudent?.id === studentId) { setCurrentStudent(updated) } } catch (e) { setError(e instanceof Error ? e.message : 'Failed to update criteria') throw e } }, [currentKlausur, currentStudent]) return ( {children} ) } export function useKlausur() { const context = useContext(KlausurContext) if (!context) { throw new Error('useKlausur must be used within a KlausurProvider') } return context }