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;
}
