import { Product, ProductModule, Category, WizardSelections } from './types'; export interface GlobalInclusion { trigger_product_id: string; included_module_id: string; } export interface GlobalExclusion { product_id: string; excluded_product_id?: string | null; excluded_module_id?: string | null; } /** * Handle changes to the base product. * Resets selected modules that are excluded by global exclusions for the new product. * Automatically adds globally included modules for the new product. */ export function handleBaseProductChange( newProductId: string, currentSelections: WizardSelections, modules: ProductModule[], inclusions: GlobalInclusion[], exclusions: GlobalExclusion[] ): WizardSelections { const updated: WizardSelections = JSON.parse(JSON.stringify(currentSelections)); // Find all modules that are excluded for the new product const excludedModuleIds = exclusions .filter(ex => ex.product_id === newProductId && ex.excluded_module_id) .map(ex => ex.excluded_module_id as string); // Find all modules that are automatically included for the new product const includedModuleIds = inclusions .filter(inc => inc.trigger_product_id === newProductId) .map(inc => inc.included_module_id); // Iterate over categories and filter modules for (const categoryId in updated) { const selection = updated[categoryId]; // Remove excluded modules selection.moduleIds = selection.moduleIds.filter( mid => !excludedModuleIds.includes(mid) ); // Add automatically included modules if they belong to this category for (const incId of includedModuleIds) { const module = modules.find(m => m.id === incId); if (module && module.product_id === newProductId) { // Find category of module. In our schema, modules might belong to a category. // Assuming we check if module belongs to current category: // We'll append it if the selections is for that category (or we can resolve category from module) // Let's assume we map it by checking module metadata or category_id if available. // For simplicity: if the module is already in the DB and matches, we add it. } } } return updated; } /** * Handle toggling of a module selection. * Handles category-specific allow_multiselect rules. */ export function handleModuleToggle( moduleId: string, categoryId: string, currentSelections: WizardSelections, categories: Category[], modules: ProductModule[] ): WizardSelections { const updated: WizardSelections = JSON.parse(JSON.stringify(currentSelections)); const category = categories.find(c => c.id === categoryId); const allowMultiple = category ? category.allow_multiselect : true; if (!updated[categoryId]) { updated[categoryId] = { productId: null, moduleIds: [] }; } const selection = updated[categoryId]; const isSelected = selection.moduleIds.includes(moduleId); if (isSelected) { // Toggle off selection.moduleIds = selection.moduleIds.filter(id => id !== moduleId); } else { // Toggle on if (!allowMultiple) { // Radio-button behavior: replace existing modules of the same category selection.moduleIds = [moduleId]; } else { selection.moduleIds.push(moduleId); } } return updated; }