import { WizardSelections, Product, Category } from '@/lib/types' export function validateWizardSelections( selections: WizardSelections, dbProducts: Product[], dbCategories: Category[] ): void { for (const cat of dbCategories) { const sel = selections[cat.id] // --- is_required: Pflichtauswahl prüfen --- const hasSelection = sel && ( (cat.allow_multiselect && sel.productIds && sel.productIds.length > 0) || (!cat.allow_multiselect && sel.productId) ) if (cat.is_required && !hasSelection) { throw new Error(`Die Kategorie "${cat.name}" ist ein Pflichtfeld, wurde aber nicht ausgewählt.`) } if (sel) { // --- allow_multiselect = false: keine doppelten IDs erlaubt --- if (!cat.allow_multiselect && sel.productIds && sel.productIds.length > 1) { throw new Error( `Die Kategorie "${cat.name}" erlaubt keine Mehrfachauswahl. Bitte nur ein Produkt wählen.` ) } const selectedProds: Product[] = [] if (cat.allow_multiselect && sel.productIds) { sel.productIds.forEach(pId => { const p = dbProducts.find(prod => prod.id === pId) if (p) selectedProds.push(p) }) } else if (sel.productId) { const p = dbProducts.find(prod => prod.id === sel.productId) if (p) selectedProds.push(p) } for (const prod of selectedProds) { // Validate selected modules for (const mId of sel.moduleIds) { const mod = prod.modules?.find(m => m.id === mId) if (!mod) continue // Requirements check if (mod.requirements && mod.requirements.length > 0) { const hasMetRequirement = mod.requirements.some(reqId => sel.moduleIds.includes(reqId)) if (!hasMetRequirement) { throw new Error(`Das Modul "${mod.name}" setzt die Aktivierung mindestens eines der folgenden Module voraus: ${mod.requirements.join(', ')}.`) } } // Exclusions check if (mod.exclusions && mod.exclusions.length > 0) { const conflicting = mod.exclusions.filter(exId => sel.moduleIds.includes(exId)) if (conflicting.length > 0) { throw new Error(`Das Modul "${mod.name}" schließt die Kombination mit anderen gewählten Modulen aus.`) } } } } } } // --- Product-level constraints validation --- const selectedProductIds: string[] = [] Object.values(selections).forEach(s => { if (s.productIds && s.productIds.length > 0) { s.productIds.forEach(id => { if (id) selectedProductIds.push(id) }) } else if (s.productId) { selectedProductIds.push(s.productId) } }) for (const prodId of selectedProductIds) { const prod = dbProducts.find(p => p.id === prodId) if (!prod) continue // Product requirements check if (prod.requirements && prod.requirements.length > 0) { const hasMetRequirement = prod.requirements.some(reqId => selectedProductIds.includes(reqId)) if (!hasMetRequirement) { const reqNames = prod.requirements .map(reqId => dbProducts.find(p => p.id === reqId)?.name || reqId) .join(' oder ') throw new Error(`Das Produkt "${prod.name}" erfordert die Auswahl von mindestens einem dieser Produkte: ${reqNames}.`) } } // Product exclusions check if (prod.exclusions && prod.exclusions.length > 0) { const conflicting = prod.exclusions.filter(exId => selectedProductIds.includes(exId)) if (conflicting.length > 0) { const conflictingNames = conflicting .map(exId => dbProducts.find(p => p.id === exId)?.name || exId) .join(', ') throw new Error(`Das Produkt "${prod.name}" schließt die gleichzeitige Auswahl von folgenden Produkten aus: ${conflictingNames}.`) } } } }