import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { ChevronDown, ChevronRight } from 'lucide-react'
import {
allExpandableKeys,
buildSkillCatalogTree,
collectSkillLeavesFromTree,
defaultExpandedKeysForSkillTree,
filterSkillTreeByQuery,
} from '../utils/skillCatalogTree'
function normExclude(excludeIds) {
return new Set(
(excludeIds instanceof Set ? [...excludeIds] : excludeIds || [])
.map((x) => Number(x))
.filter((n) => Number.isFinite(n))
)
}
function SkillTreeNodes({ nodes, depth, expanded, exclude, onToggle, onPickSkill, pickMode }) {
if (!nodes?.length) {
return
Keine Fähigkeiten
}
return nodes.map((node) => {
if (node.type === 'skill') {
if (exclude.has(node.skillId)) return null
return (
)
}
const hasKids = node.children?.length > 0
const isOpen = expanded.has(node.key)
return (
{hasKids ? (
) : (
)}
{node.label}
{hasKids && isOpen ? (
) : null}
)
})
}
/**
* Ausklappbare Baumliste: Hauptgruppe → Kategorie → Fähigkeit (nur Hauptgruppe standard offen).
*/
export default function SkillTreePickerPanel({
skills = [],
excludeIds,
searchQuery = '',
onPickSkill,
pickMode = 'single',
className = '',
}) {
const exclude = useMemo(() => normExclude(excludeIds), [excludeIds])
const fullTree = useMemo(() => buildSkillCatalogTree(skills), [skills])
const displayTree = useMemo(
() => filterSkillTreeByQuery(fullTree, searchQuery),
[fullTree, searchQuery]
)
const [expanded, setExpanded] = useState(() => new Set())
useEffect(() => {
if (searchQuery.trim()) {
setExpanded(new Set(allExpandableKeys(displayTree)))
} else {
setExpanded(new Set(defaultExpandedKeysForSkillTree(displayTree)))
}
}, [searchQuery, displayTree])
useEffect(() => {
if (!searchQuery.trim()) {
setExpanded(new Set(defaultExpandedKeysForSkillTree(fullTree)))
}
}, [fullTree, searchQuery])
const onToggle = useCallback((key) => {
setExpanded((prev) => {
const next = new Set(prev)
if (next.has(key)) next.delete(key)
else next.add(key)
return next
})
}, [])
const flatSearchHits = useMemo(() => {
const q = searchQuery.trim()
if (!q) return []
return collectSkillLeavesFromTree(fullTree, exclude).filter((leaf) =>
leaf.pathLabel.toLowerCase().includes(q.toLowerCase())
)
}, [fullTree, exclude, searchQuery])
if (searchQuery.trim() && flatSearchHits.length > 0) {
return (
{flatSearchHits.map((leaf) => (
-
))}
)
}
return (
)
}