import { type Category } from '../types/Category'; // Interfaz para la categoría "Aplanada" y enriquecida para UI export interface FlatCategory { id: number; name: string; level: number; parentId: number | null; path: string; // "Vehículos > Autos" isSelectable: boolean; // True si no tiene hijos (es hoja) hasChildren: boolean; } // Interfaz auxiliar para el árbol interface CategoryNode extends Category { children: CategoryNode[]; } /** * Convierte una lista plana de BD en un árbol recursivo */ export const buildTree = (categories: Category[]): CategoryNode[] => { const map = new Map(); const roots: CategoryNode[] = []; // 1. Inicializar nodos categories.forEach(cat => { map.set(cat.id, { ...cat, children: [] }); }); // 2. Construir relaciones categories.forEach(cat => { const node = map.get(cat.id); if (node) { if (cat.parentId && map.has(cat.parentId)) { map.get(cat.parentId)!.children.push(node); } else { roots.push(node); } } }); return roots; }; /** * Aplana el árbol para usarlo en Selects/Autocompletes * Calcula breadcrumbs y deshabilita padres */ export const flattenCategoriesForSelect = ( nodes: CategoryNode[], level = 0, parentPath = "" ): FlatCategory[] => { let result: FlatCategory[] = []; // Ordenar alfabéticamente para facilitar búsqueda visual const sortedNodes = [...nodes].sort((a, b) => a.name.localeCompare(b.name)); for (const node of sortedNodes) { const currentPath = parentPath ? `${parentPath} > ${node.name}` : node.name; const hasChildren = node.children && node.children.length > 0; // Agregamos el nodo actual result.push({ id: node.id, name: node.name, level: level, parentId: node.parentId || null, path: currentPath, hasChildren: hasChildren, // REGLA DE ORO: Solo seleccionable si NO tiene hijos isSelectable: !hasChildren }); // Recursión para los hijos if (hasChildren) { const childrenFlat = flattenCategoriesForSelect(node.children, level + 1, currentPath); result = [...result, ...childrenFlat]; } } return result; }; /** * Función Helper que hace todo el proceso desde la respuesta de la API */ export const processCategories = (rawCategories: Category[]): FlatCategory[] => { const tree = buildTree(rawCategories); return flattenCategoriesForSelect(tree); };